From: Mark Zhan <rongkai.zhan@windriver.com>
To: i2c@lm-sensors.org, linux-mips@linux-mips.org,
rtc-linux@googlegroups.com
Cc: ralf@linux-mips.org, a.zummo@towertech.it, rongkai.zhan@windriver.com
Subject: [PATCH 2/4] RTC: make m41t80 driver can work with the SMBus adapters
Date: Sun, 30 Sep 2007 17:54:54 +0800 [thread overview]
Message-ID: <46FF726E.4020200@windriver.com> (raw)
This patch makes m41t80 RTC driver also can work with the SMBus adapters,
which doesn't i2c_transfer() method.
Signed-off-by: Mark Zhan <rongkai.zhan@windriver.com>
---
drivers/rtc/rtc-m41t80.c | 118 ++++++++++++++++++++++++-----------------------
1 file changed, 62 insertions(+), 56 deletions(-)
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -105,6 +105,51 @@ struct m41t80_data {
struct rtc_device *rtc;
};
+static int m41t80_i2c_read(struct i2c_client *client, struct i2c_msg *msgs, int num)
+{
+ int i, rc;
+ u8 dt_addr = msgs[0].buf[0];
+
+ if (num < 2)
+ return -1;
+
+ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) &&
+ i2c_transfer(client->adapter, msgs, 2) < 0) {
+ dev_err(&client->dev, "read error\n");
+ return -EIO;
+ } else {
+ for (i = 0; i < msgs[1].len; i++) {
+ rc = i2c_smbus_read_byte_data(client, dt_addr + i);
+ if (rc < 0)
+ return -EIO;
+ msgs[1].buf[i] = (u8)rc;
+ }
+ }
+
+ return 0;
+}
+
+static int m41t80_i2c_write(struct i2c_client *client, struct i2c_msg *msg)
+{
+ int i, rc;
+ u8 *wbuf = msg->buf;
+ u8 *buf = wbuf + 1;
+
+ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) &&
+ i2c_transfer(client->adapter, msg, 1) < 0) {
+ dev_err(&client->dev, "write error\n");
+ return -EIO;
+ } else {
+ for (i = 0; i < msg[0].len - 1; i++) {
+ rc = i2c_smbus_write_byte_data(client, wbuf[0]+i, buf[i]);
+ if (rc < 0)
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
static int m41t80_get_datetime(struct i2c_client *client,
struct rtc_time *tm)
{
@@ -124,10 +169,8 @@ static int m41t80_get_datetime(struct i2
},
};
- if (i2c_transfer(client->adapter, msgs, 2) < 0) {
- dev_err(&client->dev, "read error\n");
+ if (m41t80_i2c_read(client, msgs, 2))
return -EIO;
- }
tm->tm_sec = BCD2BIN(buf[M41T80_REG_SEC] & 0x7f);
tm->tm_min = BCD2BIN(buf[M41T80_REG_MIN] & 0x7f);
@@ -171,10 +214,8 @@ static int m41t80_set_datetime(struct i2
};
/* Read current reg values into buf[1..7] */
- if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
- dev_err(&client->dev, "read error\n");
+ if (m41t80_i2c_read(client, msgs_in, 2))
return -EIO;
- }
wbuf[0] = 0; /* offset into rtc's regs */
/* Merge time-data and register flags into buf[0..7] */
@@ -194,10 +235,9 @@ static int m41t80_set_datetime(struct i2
/* assume 20YY not 19YY */
buf[M41T80_REG_YEAR] = BIN2BCD(tm->tm_year % 100);
- if (i2c_transfer(client->adapter, msgs, 1) != 1) {
- dev_err(&client->dev, "write error\n");
+ if (m41t80_i2c_write(client, msgs))
return -EIO;
- }
+
return 0;
}
@@ -295,10 +335,9 @@ static int m41t80_rtc_set_alarm(struct d
},
};
- if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
- dev_err(&client->dev, "read error\n");
+ if (m41t80_i2c_read(client, msgs_in, 2))
return -EIO;
- }
+
reg[M41T80_REG_ALARM_MON] &= ~(0x1f | M41T80_ALMON_AFE);
reg[M41T80_REG_ALARM_DAY] = 0;
reg[M41T80_REG_ALARM_HOUR] &= ~(0x3f | 0x80);
@@ -319,10 +358,8 @@ static int m41t80_rtc_set_alarm(struct d
else
reg[M41T80_REG_ALARM_DAY] |= 0x40;
- if (i2c_transfer(client->adapter, msgs, 1) != 1) {
- dev_err(&client->dev, "write error\n");
+ if (m41t80_i2c_write(client, msgs))
return -EIO;
- }
if (t->enabled) {
reg[M41T80_REG_ALARM_MON] |= M41T80_ALMON_AFE;
@@ -356,10 +393,9 @@ static int m41t80_rtc_read_alarm(struct
},
};
- if (i2c_transfer(client->adapter, msgs, 2) < 0) {
- dev_err(&client->dev, "read error\n");
+ if (m41t80_i2c_read(client, msgs, 2))
return -EIO;
- }
+
t->time.tm_sec = -1;
t->time.tm_min = -1;
t->time.tm_hour = -1;
@@ -516,14 +552,7 @@ static int boot_flag;
static void wdt_ping(void)
{
unsigned char i2c_data[2];
- struct i2c_msg msgs1[1] = {
- {
- .addr = save_client->addr,
- .flags = 0,
- .len = 2,
- .buf = i2c_data,
- },
- };
+
i2c_data[0] = 0x09; /* watchdog register */
if (wdt_margin > 31)
@@ -534,7 +563,7 @@ static void wdt_ping(void)
*/
i2c_data[1] = wdt_margin<<2 | 0x82;
- i2c_transfer(save_client->adapter, msgs1, 1);
+ i2c_smbus_write_byte_data(save_client, i2c_data[0], i2c_data[1]);
}
/**
@@ -544,36 +573,14 @@ static void wdt_ping(void)
*/
static void wdt_disable(void)
{
- unsigned char i2c_data[2], i2c_buf[0x10];
- struct i2c_msg msgs0[2] = {
- {
- .addr = save_client->addr,
- .flags = 0,
- .len = 1,
- .buf = i2c_data,
- },
- {
- .addr = save_client->addr,
- .flags = I2C_M_RD,
- .len = 1,
- .buf = i2c_buf,
- },
- };
- struct i2c_msg msgs1[1] = {
- {
- .addr = save_client->addr,
- .flags = 0,
- .len = 2,
- .buf = i2c_data,
- },
- };
+ unsigned char i2c_data[2];
- i2c_data[0] = 0x09;
- i2c_transfer(save_client->adapter, msgs0, 2);
+ i2c_data[0] = 0x09; /* watchdog register */
+ i2c_data[1] = i2c_smbus_read_byte_data(save_client, i2c_data[0]);
- i2c_data[0] = 0x09;
+ /* write 0x00 to disable WDT until it is programmed again. */
i2c_data[1] = 0x00;
- i2c_transfer(save_client->adapter, msgs1, 1);
+ i2c_smbus_read_byte_datasave_client, i2c_data[0], i2c_data[1]);
}
/**
@@ -764,8 +771,7 @@ static int m41t80_probe(struct i2c_clien
const struct m41t80_chip_info *chip;
struct m41t80_data *clientdata = NULL;
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
- | I2C_FUNC_SMBUS_BYTE_DATA)) {
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
rc = -ENODEV;
goto exit;
}
next reply other threads:[~2007-09-30 9:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-30 9:54 Mark Zhan [this message]
2007-10-01 15:06 ` [PATCH 2/4] RTC: make m41t80 driver can work with the SMBus adapters Atsushi Nemoto
2007-10-02 13:16 ` [rtc-linux] " Alessandro Zummo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=46FF726E.4020200@windriver.com \
--to=rongkai.zhan@windriver.com \
--cc=a.zummo@towertech.it \
--cc=i2c@lm-sensors.org \
--cc=linux-mips@linux-mips.org \
--cc=ralf@linux-mips.org \
--cc=rtc-linux@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.