* [PATCH 2.6.26.5] rtc-ds1307 : SMBus compatibility
@ 2008-10-07 12:55 BARRE Sebastien
2008-10-16 19:18 ` Andrew Morton
0 siblings, 1 reply; 5+ messages in thread
From: BARRE Sebastien @ 2008-10-07 12:55 UTC (permalink / raw)
To: linux-kernel
This patch change all i2c access functions to SMBus access functions in order to use the ds1307 on SMBus.
I expect that using SMBus access functions is correct for all boards with i2C or SMBus adapter. Is it correct ?
I have tested it on my Geode LX board with a ds1307 device.
Please CC me your comments.
Thanks.
--- a/drivers/rtc/rtc-ds1307.c 2008-09-08 17:40:20.000000000 +0000
+++ b/drivers/rtc/rtc-ds1307.c 2008-10-07 13:21:57.000000000 +0000
@@ -92,7 +92,6 @@ struct ds1307 {
bool has_nvram;
u8 regs[8];
enum ds_type type;
- struct i2c_msg msg[2];
struct i2c_client *client;
struct i2c_client dev;
struct rtc_device *rtc;
@@ -138,12 +137,10 @@ static int ds1307_get_time(struct device
int tmp;
/* read the RTC date and time registers all at once */
- ds1307->msg[1].flags = I2C_M_RD;
- ds1307->msg[1].len = 7;
-
- tmp = i2c_transfer(to_i2c_adapter(ds1307->client->dev.parent),
- ds1307->msg, 2);
- if (tmp != 2) {
+ u8 *buf = ds1307->regs;
+ tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+ DS1307_REG_SECS, 7, buf);
+ if (tmp != 7) {
dev_err(dev, "%s error %d\n", "read", tmp);
return -EIO;
}
@@ -180,7 +177,6 @@ static int ds1307_get_time(struct device
static int ds1307_set_time(struct device *dev, struct rtc_time *t)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
- int result;
int tmp;
u8 *buf = ds1307->regs;
@@ -190,7 +186,6 @@ static int ds1307_set_time(struct device
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
- *buf++ = 0; /* first register addr */
buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec);
buf[DS1307_REG_MIN] = BIN2BCD(t->tm_min);
buf[DS1307_REG_HOUR] = BIN2BCD(t->tm_hour);
@@ -215,16 +210,12 @@ static int ds1307_set_time(struct device
break;
}
- ds1307->msg[1].flags = 0;
- ds1307->msg[1].len = 8;
-
dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n",
"write", buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6]);
- result = i2c_transfer(to_i2c_adapter(ds1307->client->dev.parent),
- &ds1307->msg[1], 1);
- if (result != 1) {
+ tmp = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf);
+ if (tmp < 0) {
dev_err(dev, "%s error %d\n", "write", tmp);
return -EIO;
}
@@ -246,8 +237,7 @@ ds1307_nvram_read(struct kobject *kobj,
{
struct i2c_client *client;
struct ds1307 *ds1307;
- struct i2c_msg msg[2];
- int result;
+ int tmp;
client = kobj_to_i2c_client(kobj);
ds1307 = i2c_get_clientdata(client);
@@ -259,24 +249,13 @@ ds1307_nvram_read(struct kobject *kobj,
if (unlikely(!count))
return count;
- msg[0].addr = client->addr;
- msg[0].flags = 0;
- msg[0].len = 1;
- msg[0].buf = buf;
-
- buf[0] = 8 + off;
-
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].len = count;
- msg[1].buf = buf;
-
- result = i2c_transfer(to_i2c_adapter(client->dev.parent), msg, 2);
- if (result != 2) {
- dev_err(&client->dev, "%s error %d\n", "nvram read", result);
+ tmp = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf);
+ if (tmp < 0) {
+ dev_err(&client->dev, "%s error %d\n", "read", tmp);
return -EIO;
}
- return count;
+
+ return tmp;
}
static ssize_t
@@ -284,8 +263,8 @@ ds1307_nvram_write(struct kobject *kobj,
char *buf, loff_t off, size_t count)
{
struct i2c_client *client;
- u8 buffer[NVRAM_SIZE + 1];
- int ret;
+ u8 buffer[NVRAM_SIZE];
+ int tmp;
client = kobj_to_i2c_client(kobj);
@@ -296,11 +275,14 @@ ds1307_nvram_write(struct kobject *kobj,
if (unlikely(!count))
return count;
- buffer[0] = 8 + off;
- memcpy(buffer + 1, buf, count);
+ memcpy(buffer, buf, count);
- ret = i2c_master_send(client, buffer, count + 1);
- return (ret < 0) ? ret : (ret - 1);
+ tmp = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buffer);
+ if (tmp < 0) {
+ dev_err(&client->dev, "%s error %d\n", "write", tmp);
+ return -EIO;
+ }
+ return count;
}
static struct bin_attribute nvram = {
@@ -325,11 +307,15 @@ static int __devinit ds1307_probe(struct
struct ds1307 *ds1307;
int err = -ENODEV;
int tmp;
+ u8 *buf;
+
const struct chip_desc *chip = &chips[id->driver_data];
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
if (!i2c_check_functionality(adapter,
- I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA
+ | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
+ | I2C_FUNC_SMBUS_READ_I2C_BLOCK))
return -EIO;
if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL)))
@@ -338,35 +324,21 @@ static int __devinit ds1307_probe(struct
ds1307->client = client;
i2c_set_clientdata(client, ds1307);
- ds1307->msg[0].addr = client->addr;
- ds1307->msg[0].flags = 0;
- ds1307->msg[0].len = 1;
- ds1307->msg[0].buf = &ds1307->reg_addr;
-
- ds1307->msg[1].addr = client->addr;
- ds1307->msg[1].flags = I2C_M_RD;
- ds1307->msg[1].len = sizeof(ds1307->regs);
- ds1307->msg[1].buf = ds1307->regs;
-
ds1307->type = id->driver_data;
switch (ds1307->type) {
case ds_1337:
case ds_1339:
- ds1307->reg_addr = DS1337_REG_CONTROL;
- ds1307->msg[1].len = 2;
-
+ buf = &ds1307->regs[DS1337_REG_CONTROL];
/* get registers that the "rtc" read below won't read... */
- tmp = i2c_transfer(adapter, ds1307->msg, 2);
+ tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+ DS1337_REG_CONTROL, 2, buf);
if (tmp != 2) {
pr_debug("read error %d\n", tmp);
err = -EIO;
goto exit_free;
}
- ds1307->reg_addr = 0;
- ds1307->msg[1].len = sizeof(ds1307->regs);
-
/* oscillator off? turn it on, so clock can tick. */
if (ds1307->regs[0] & DS1337_BIT_nEOSC)
i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
@@ -385,9 +357,9 @@ static int __devinit ds1307_probe(struct
read_rtc:
/* read RTC registers */
-
- tmp = i2c_transfer(adapter, ds1307->msg, 2);
- if (tmp != 2) {
+ buf = ds1307->regs;
+ tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf);
+ if (tmp != 8) {
pr_debug("read error %d\n", tmp);
err = -EIO;
goto exit_free;
--
Sébastien Barré
Bureau d'étude - Développement
SDEL Contrôle Commande
D2A - Rue Nungesser et Coli
44860 Saint Aignan de Grand Lieu
FRANCE
Tél : +33(0)2 40 84 50 88
Fax : +33(0)2 40 84 51 10
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 2.6.26.5] rtc-ds1307 : SMBus compatibility 2008-10-07 12:55 [PATCH 2.6.26.5] rtc-ds1307 : SMBus compatibility BARRE Sebastien @ 2008-10-16 19:18 ` Andrew Morton 2008-10-17 15:11 ` [i2c] [PATCH] " BARRE Sebastien 0 siblings, 1 reply; 5+ messages in thread From: Andrew Morton @ 2008-10-16 19:18 UTC (permalink / raw) To: BARRE Sebastien; +Cc: linux-kernel On Tue, 7 Oct 2008 14:55:52 +0200 BARRE Sebastien <sbarre@sdelcc.com> wrote: > This patch change all i2c access functions to SMBus access functions in order to use the ds1307 on SMBus. > I expect that using SMBus access functions is correct for all boards with i2C or SMBus adapter. Is it correct ? > > I have tested it on my Geode LX board with a ds1307 device. > Alas, some patches against that driver have just been sent to Linus and this patch isn't mergeable any more. Can you please redo it against 2.6.28-rc1 (when that is released) or Linus's current git tree and resend, copying the following: i2c@lm-sensors.org David Brownell <david-b@pacbell.net> Alessandro Zummo <a.zummo@towertech.it> linux-kernel@vger.kernel.org Andrew Morton <akpm@linux-foundation.org> Also, your email client replaced all the tabs with spaces. Please fix that up beforehand. Thanks. ^ permalink raw reply [flat|nested] 5+ messages in thread
* [i2c] [PATCH] rtc-ds1307 : SMBus compatibility 2008-10-16 19:18 ` Andrew Morton @ 2008-10-17 15:11 ` BARRE Sebastien 2008-10-21 18:29 ` [rtc-linux] " Alessandro Zummo 0 siblings, 1 reply; 5+ messages in thread From: BARRE Sebastien @ 2008-10-17 15:11 UTC (permalink / raw) To: linux-kernel Cc: i2c, rtc-linux, David Brownell, Alessandro Zummo, Jean Delvare, Rodolfo Giometti, Andrew Morton [-- Attachment #1: Type: text/plain, Size: 647 bytes --] This patch change i2c access functions to SMBus access functions in order to use the ds1307 with SMBus adapter. Signed-off-by: Sebastien Barre <sbarre@sdelcc.com> -- The initial patch was based on 2.6.26.5, I've redone it against Linus's current git tree. Sorry, the patch is attached because my email client replace all the tabs with spaces. I've tested it with ds1307 chip. Is somebody can test it on ds1337/ds1338 ? -- Sébastien Barré Bureau d'étude - Développement SDEL Contrôle Commande D2A - Rue Nungesser et Coli 44860 Saint Aignan de Grand Lieu FRANCE Tél : +33(0)2 40 84 50 88 Fax : +33(0)2 40 84 51 10 [-- Attachment #2: patch-rtc-ds1307 --] [-- Type: application/octet-stream, Size: 7387 bytes --] --- a/drivers/rtc/rtc-ds1307.c 2008-10-17 14:43:43.000000000 +0200 +++ b/drivers/rtc/rtc-ds1307.c 2008-10-17 15:38:12.000000000 +0200 @@ -86,13 +86,11 @@ enum ds_type { struct ds1307 { - u8 reg_addr; u8 regs[11]; enum ds_type type; unsigned long flags; #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ #define HAS_ALARM 1 /* bit 1 == irq claimed */ - struct i2c_msg msg[2]; struct i2c_client *client; struct rtc_device *rtc; struct work_struct work; @@ -204,13 +202,9 @@ static int ds1307_get_time(struct device int tmp; /* read the RTC date and time registers all at once */ - ds1307->reg_addr = 0; - ds1307->msg[1].flags = I2C_M_RD; - ds1307->msg[1].len = 7; - - tmp = i2c_transfer(to_i2c_adapter(ds1307->client->dev.parent), - ds1307->msg, 2); - if (tmp != 2) { + tmp = i2c_smbus_read_i2c_block_data(ds1307->client, + DS1307_REG_SECS, 7, ds1307->regs); + if (tmp != 7) { dev_err(dev, "%s error %d\n", "read", tmp); return -EIO; } @@ -257,7 +251,6 @@ static int ds1307_set_time(struct device t->tm_hour, t->tm_mday, t->tm_mon, t->tm_year, t->tm_wday); - *buf++ = 0; /* first register addr */ buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec); buf[DS1307_REG_MIN] = BIN2BCD(t->tm_min); buf[DS1307_REG_HOUR] = BIN2BCD(t->tm_hour); @@ -282,18 +275,14 @@ static int ds1307_set_time(struct device break; } - ds1307->msg[1].flags = 0; - ds1307->msg[1].len = 8; - dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", "write", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); - result = i2c_transfer(to_i2c_adapter(ds1307->client->dev.parent), - &ds1307->msg[1], 1); - if (result != 1) { - dev_err(dev, "%s error %d\n", "write", tmp); - return -EIO; + result = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf); + if (result < 0) { + dev_err(dev, "%s error %d\n", "write", result); + return result; } return 0; } @@ -308,13 +297,9 @@ static int ds1307_read_alarm(struct devi return -EINVAL; /* read all ALARM1, ALARM2, and status registers at once */ - ds1307->reg_addr = DS1339_REG_ALARM1_SECS; - ds1307->msg[1].flags = I2C_M_RD; - ds1307->msg[1].len = 9; - - ret = i2c_transfer(to_i2c_adapter(client->dev.parent), - ds1307->msg, 2); - if (ret != 2) { + ret = i2c_smbus_read_i2c_block_data(client, + DS1339_REG_ALARM1_SECS, 9, ds1307->regs); + if (ret != 9) { dev_err(dev, "%s error %d\n", "alarm read", ret); return -EIO; } @@ -371,13 +356,9 @@ static int ds1307_set_alarm(struct devic t->enabled, t->pending); /* read current status of both alarms and the chip */ - ds1307->reg_addr = DS1339_REG_ALARM1_SECS; - ds1307->msg[1].flags = I2C_M_RD; - ds1307->msg[1].len = 9; - - ret = i2c_transfer(to_i2c_adapter(client->dev.parent), - ds1307->msg, 2); - if (ret != 2) { + ret = i2c_smbus_read_i2c_block_data(client, + DS1339_REG_ALARM1_SECS, 9, buf); + if (ret != 9) { dev_err(dev, "%s error %d\n", "alarm write", ret); return -EIO; } @@ -392,7 +373,6 @@ static int ds1307_set_alarm(struct devic ds1307->regs[6], control, status); /* set ALARM1, using 24 hour and day-of-month modes */ - *buf++ = DS1339_REG_ALARM1_SECS; /* first register addr */ buf[0] = bin2bcd(t->time.tm_sec); buf[1] = bin2bcd(t->time.tm_min); buf[2] = bin2bcd(t->time.tm_hour); @@ -411,14 +391,11 @@ static int ds1307_set_alarm(struct devic } buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); - ds1307->msg[1].flags = 0; - ds1307->msg[1].len = 10; - - ret = i2c_transfer(to_i2c_adapter(client->dev.parent), - &ds1307->msg[1], 1); - if (ret != 1) { + ret = i2c_smbus_write_i2c_block_data(client, + DS1339_REG_ALARM1_SECS, 9, buf); + if (ret < 0) { dev_err(dev, "can't set alarm time\n"); - return -EIO; + return ret; } return 0; @@ -490,7 +467,6 @@ ds1307_nvram_read(struct kobject *kobj, { struct i2c_client *client; struct ds1307 *ds1307; - struct i2c_msg msg[2]; int result; client = kobj_to_i2c_client(kobj); @@ -503,24 +479,10 @@ ds1307_nvram_read(struct kobject *kobj, if (unlikely(!count)) return count; - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = buf; - - buf[0] = 8 + off; - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = count; - msg[1].buf = buf; - - result = i2c_transfer(to_i2c_adapter(client->dev.parent), msg, 2); - if (result != 2) { + result = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf); + if (result < 0) dev_err(&client->dev, "%s error %d\n", "nvram read", result); - return -EIO; - } - return count; + return result; } static ssize_t @@ -528,8 +490,7 @@ ds1307_nvram_write(struct kobject *kobj, char *buf, loff_t off, size_t count) { struct i2c_client *client; - u8 buffer[NVRAM_SIZE + 1]; - int ret; + int result; client = kobj_to_i2c_client(kobj); @@ -540,11 +501,12 @@ ds1307_nvram_write(struct kobject *kobj, if (unlikely(!count)) return count; - buffer[0] = 8 + off; - memcpy(buffer + 1, buf, count); - - ret = i2c_master_send(client, buffer, count + 1); - return (ret < 0) ? ret : (ret - 1); + result = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buf); + if (result < 0) { + dev_err(&client->dev, "%s error %d\n", "nvram write", result); + return result; + } + return count; } static struct bin_attribute nvram = { @@ -572,9 +534,11 @@ static int __devinit ds1307_probe(struct const struct chip_desc *chip = &chips[id->driver_data]; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int want_irq = false; + unsigned char *buf; if (!i2c_check_functionality(adapter, - I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) + I2C_FUNC_SMBUS_WRITE_BYTE_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) return -EIO; if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) @@ -582,18 +546,8 @@ static int __devinit ds1307_probe(struct ds1307->client = client; i2c_set_clientdata(client, ds1307); - - ds1307->msg[0].addr = client->addr; - ds1307->msg[0].flags = 0; - ds1307->msg[0].len = 1; - ds1307->msg[0].buf = &ds1307->reg_addr; - - ds1307->msg[1].addr = client->addr; - ds1307->msg[1].flags = I2C_M_RD; - ds1307->msg[1].len = sizeof(ds1307->regs); - ds1307->msg[1].buf = ds1307->regs; - ds1307->type = id->driver_data; + buf = ds1307->regs; switch (ds1307->type) { case ds_1337: @@ -603,21 +557,15 @@ static int __devinit ds1307_probe(struct INIT_WORK(&ds1307->work, ds1307_work); want_irq = true; } - - ds1307->reg_addr = DS1337_REG_CONTROL; - ds1307->msg[1].len = 2; - /* get registers that the "rtc" read below won't read... */ - tmp = i2c_transfer(adapter, ds1307->msg, 2); + tmp = i2c_smbus_read_i2c_block_data(ds1307->client, + DS1337_REG_CONTROL, 2, buf); if (tmp != 2) { pr_debug("read error %d\n", tmp); err = -EIO; goto exit_free; } - ds1307->reg_addr = 0; - ds1307->msg[1].len = sizeof(ds1307->regs); - /* oscillator off? turn it on, so clock can tick. */ if (ds1307->regs[0] & DS1337_BIT_nEOSC) ds1307->regs[0] &= ~DS1337_BIT_nEOSC; @@ -648,9 +596,8 @@ static int __devinit ds1307_probe(struct read_rtc: /* read RTC registers */ - - tmp = i2c_transfer(adapter, ds1307->msg, 2); - if (tmp != 2) { + tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf); + if (tmp != 8) { pr_debug("read error %d\n", tmp); err = -EIO; goto exit_free; ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [rtc-linux] [i2c] [PATCH] rtc-ds1307 : SMBus compatibility 2008-10-17 15:11 ` [i2c] [PATCH] " BARRE Sebastien @ 2008-10-21 18:29 ` Alessandro Zummo 2008-10-27 21:29 ` David Brownell 0 siblings, 1 reply; 5+ messages in thread From: Alessandro Zummo @ 2008-10-21 18:29 UTC (permalink / raw) To: rtc-linux Cc: sbarre, linux-kernel, i2c, David Brownell, Jean Delvare, Rodolfo Giometti, Andrew Morton On Fri, 17 Oct 2008 17:11:27 +0200 BARRE Sebastien <sbarre@sdelcc.com> wrote: > I've tested it with ds1307 chip. > Is somebody can test it on ds1337/ds1338 ? Given the amount of changes I need some Tested-bys for the patch to go thru. -- Best regards, Alessandro Zummo, Tower Technologies - Torino, Italy http://www.towertech.it ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [rtc-linux] [i2c] [PATCH] rtc-ds1307 : SMBus compatibility 2008-10-21 18:29 ` [rtc-linux] " Alessandro Zummo @ 2008-10-27 21:29 ` David Brownell 0 siblings, 0 replies; 5+ messages in thread From: David Brownell @ 2008-10-27 21:29 UTC (permalink / raw) To: Alessandro Zummo Cc: rtc-linux, sbarre, linux-kernel, i2c, Jean Delvare, Rodolfo Giometti, Andrew Morton On Tuesday 21 October 2008, Alessandro Zummo wrote: > > I've tested it with ds1307 chip. > > Is somebody can test it on ds1337/ds1338 ? > > Given the amount of changes I need some Tested-bys > for the patch to go thru. I tested these changes on my trusty ds1307 system using i2c-gpio (vs a "real SMBus controller") and it works just fine. Of the nine changed I/O calls, testing with the ds1307 covers all but the three supporting the new alarm calls. Given that those alarm changes are "obvious", I actually don't have any qualms signing off on these changes ... though it would of course be good to have Rodolfo re-test his alarm code. (It's freshly merged in any case, so it merits testing just in case a problem snuck in!) - Dave ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-10-27 21:40 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-10-07 12:55 [PATCH 2.6.26.5] rtc-ds1307 : SMBus compatibility BARRE Sebastien 2008-10-16 19:18 ` Andrew Morton 2008-10-17 15:11 ` [i2c] [PATCH] " BARRE Sebastien 2008-10-21 18:29 ` [rtc-linux] " Alessandro Zummo 2008-10-27 21:29 ` David Brownell
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
Powered by JetHome