Commit f2b84ee8 authored by Mylène Josserand's avatar Mylène Josserand Committed by Alexandre Belloni

rtc: m41t80: replace i2c functions for smbus ones

The driver used i2c_transfer methods to read and set date/time.
The smbus methods should be used.

This commit replaces i2c_transfer functions by i2c_smbus_XX_i2c_block_data
for reading and setting the datetime.
Signed-off-by: default avatarMylène Josserand <mylene.josserand@free-electrons.com>
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@free-electrons.com>
parent ca91607f
...@@ -32,21 +32,21 @@ ...@@ -32,21 +32,21 @@
#include <linux/watchdog.h> #include <linux/watchdog.h>
#endif #endif
#define M41T80_REG_SSEC 0 #define M41T80_REG_SSEC 0x00
#define M41T80_REG_SEC 1 #define M41T80_REG_SEC 0x01
#define M41T80_REG_MIN 2 #define M41T80_REG_MIN 0x02
#define M41T80_REG_HOUR 3 #define M41T80_REG_HOUR 0x03
#define M41T80_REG_WDAY 4 #define M41T80_REG_WDAY 0x04
#define M41T80_REG_DAY 5 #define M41T80_REG_DAY 0x05
#define M41T80_REG_MON 6 #define M41T80_REG_MON 0x06
#define M41T80_REG_YEAR 7 #define M41T80_REG_YEAR 0x07
#define M41T80_REG_ALARM_MON 0xa #define M41T80_REG_ALARM_MON 0x0a
#define M41T80_REG_ALARM_DAY 0xb #define M41T80_REG_ALARM_DAY 0x0b
#define M41T80_REG_ALARM_HOUR 0xc #define M41T80_REG_ALARM_HOUR 0x0c
#define M41T80_REG_ALARM_MIN 0xd #define M41T80_REG_ALARM_MIN 0x0d
#define M41T80_REG_ALARM_SEC 0xe #define M41T80_REG_ALARM_SEC 0x0e
#define M41T80_REG_FLAGS 0xf #define M41T80_REG_FLAGS 0x0f
#define M41T80_REG_SQW 0x13 #define M41T80_REG_SQW 0x13
#define M41T80_DATETIME_REG_SIZE (M41T80_REG_YEAR + 1) #define M41T80_DATETIME_REG_SIZE (M41T80_REG_YEAR + 1)
#define M41T80_ALARM_REG_SIZE \ #define M41T80_ALARM_REG_SIZE \
...@@ -93,24 +93,13 @@ struct m41t80_data { ...@@ -93,24 +93,13 @@ struct m41t80_data {
static int m41t80_get_datetime(struct i2c_client *client, static int m41t80_get_datetime(struct i2c_client *client,
struct rtc_time *tm) struct rtc_time *tm)
{ {
u8 buf[M41T80_DATETIME_REG_SIZE], dt_addr[1] = { M41T80_REG_SEC }; unsigned char buf[8];
struct i2c_msg msgs[] = { int err;
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = dt_addr,
},
{
.addr = client->addr,
.flags = I2C_M_RD,
.len = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
.buf = buf + M41T80_REG_SEC,
},
};
if (i2c_transfer(client->adapter, msgs, 2) < 0) { err = i2c_smbus_read_i2c_block_data(client, M41T80_REG_SSEC,
dev_err(&client->dev, "read error\n"); sizeof(buf), buf);
if (err < 0) {
dev_err(&client->dev, "Unable to read date\n");
return -EIO; return -EIO;
} }
...@@ -129,67 +118,29 @@ static int m41t80_get_datetime(struct i2c_client *client, ...@@ -129,67 +118,29 @@ static int m41t80_get_datetime(struct i2c_client *client,
/* Sets the given date and time to the real time clock. */ /* Sets the given date and time to the real time clock. */
static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm) static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{ {
u8 wbuf[1 + M41T80_DATETIME_REG_SIZE]; unsigned char buf[8];
u8 *buf = &wbuf[1]; int err;
u8 dt_addr[1] = { M41T80_REG_SEC };
struct i2c_msg msgs_in[] = {
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = dt_addr,
},
{
.addr = client->addr,
.flags = I2C_M_RD,
.len = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
.buf = buf + M41T80_REG_SEC,
},
};
struct i2c_msg msgs[] = {
{
.addr = client->addr,
.flags = 0,
.len = 1 + M41T80_DATETIME_REG_SIZE,
.buf = wbuf,
},
};
/* Read current reg values into buf[1..7] */ if (tm->tm_year < 100 || tm->tm_year > 199)
if (i2c_transfer(client->adapter, msgs_in, 2) < 0) { return -EINVAL;
dev_err(&client->dev, "read error\n");
return -EIO;
}
wbuf[0] = 0; /* offset into rtc's regs */
/* Merge time-data and register flags into buf[0..7] */
buf[M41T80_REG_SSEC] = 0; buf[M41T80_REG_SSEC] = 0;
buf[M41T80_REG_SEC] = buf[M41T80_REG_SEC] = bin2bcd(tm->tm_sec);
bin2bcd(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f); buf[M41T80_REG_MIN] = bin2bcd(tm->tm_min);
buf[M41T80_REG_MIN] = buf[M41T80_REG_HOUR] = bin2bcd(tm->tm_hour);
bin2bcd(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f); buf[M41T80_REG_DAY] = bin2bcd(tm->tm_mday);
buf[M41T80_REG_HOUR] = buf[M41T80_REG_MON] = bin2bcd(tm->tm_mon + 1);
bin2bcd(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f); buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year - 100);
buf[M41T80_REG_WDAY] = buf[M41T80_REG_WDAY] = tm->tm_wday;
(tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07);
buf[M41T80_REG_DAY] = err = i2c_smbus_write_i2c_block_data(client, M41T80_REG_SSEC,
bin2bcd(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f); sizeof(buf), buf);
buf[M41T80_REG_MON] = if (err < 0) {
bin2bcd(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f); dev_err(&client->dev, "Unable to write to date registers\n");
return err;
/* assume 20YY not 19YY */
if (tm->tm_year < 100 || tm->tm_year > 199) {
dev_err(&client->dev, "Year must be between 2000 and 2099. It's %d.\n",
tm->tm_year + 1900);
return -EINVAL;
} }
buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year % 100);
if (i2c_transfer(client->adapter, msgs, 1) != 1) { return err;
dev_err(&client->dev, "write error\n");
return -EIO;
}
return 0;
} }
static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq) static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
...@@ -631,14 +582,17 @@ static void m41t80_remove_sysfs_group(void *_dev) ...@@ -631,14 +582,17 @@ static void m41t80_remove_sysfs_group(void *_dev)
static int m41t80_probe(struct i2c_client *client, static int m41t80_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
int rc = 0; int rc = 0;
struct rtc_device *rtc = NULL; struct rtc_device *rtc = NULL;
struct rtc_time tm; struct rtc_time tm;
struct m41t80_data *clientdata = NULL; struct m41t80_data *clientdata = NULL;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
| I2C_FUNC_SMBUS_BYTE_DATA)) I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&adapter->dev, "doesn't support I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK\n");
return -ENODEV; return -ENODEV;
}
clientdata = devm_kzalloc(&client->dev, sizeof(*clientdata), clientdata = devm_kzalloc(&client->dev, sizeof(*clientdata),
GFP_KERNEL); GFP_KERNEL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment