aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorEd Swierk <eswierk@aristanetworks.com>2009-03-31 18:24:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-01 11:59:25 -0400
commit30e7b039b1f9a6d5a4e50df5469a4f347ea1aa77 (patch)
tree901a186c2e97ff83804992ecaf4f9e52be8aadff /drivers/rtc
parentb250c96ea9d7bc0b9ac3ff6e878b254b0b0b6abc (diff)
rtc-ds1307: true SMBus compatibility
Allow the rtc-ds1307 driver to work with SMBus controllers like nforce2 that do not support i2c block transfers. Signed-off-by: Ed Swierk <eswierk@aristanetworks.com> Acked-by: Jean Delvare <khali@linux-fr.org> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: BARRE Sebastien <sbarre@sdelcc.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-ds1307.c109
1 files changed, 97 insertions, 12 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 7e5155e88ac7..1c975e6439b3 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -94,6 +94,10 @@ struct ds1307 {
94 struct i2c_client *client; 94 struct i2c_client *client;
95 struct rtc_device *rtc; 95 struct rtc_device *rtc;
96 struct work_struct work; 96 struct work_struct work;
97 s32 (*read_block_data)(struct i2c_client *client, u8 command,
98 u8 length, u8 *values);
99 s32 (*write_block_data)(struct i2c_client *client, u8 command,
100 u8 length, const u8 *values);
97}; 101};
98 102
99struct chip_desc { 103struct chip_desc {
@@ -132,6 +136,79 @@ MODULE_DEVICE_TABLE(i2c, ds1307_id);
132 136
133/*----------------------------------------------------------------------*/ 137/*----------------------------------------------------------------------*/
134 138
139#define BLOCK_DATA_MAX_TRIES 10
140
141static s32 ds1307_read_block_data_once(struct i2c_client *client, u8 command,
142 u8 length, u8 *values)
143{
144 s32 i, data;
145
146 for (i = 0; i < length; i++) {
147 data = i2c_smbus_read_byte_data(client, command + i);
148 if (data < 0)
149 return data;
150 values[i] = data;
151 }
152 return i;
153}
154
155static s32 ds1307_read_block_data(struct i2c_client *client, u8 command,
156 u8 length, u8 *values)
157{
158 u8 oldvalues[I2C_SMBUS_BLOCK_MAX];
159 s32 ret;
160 int tries = 0;
161
162 dev_dbg(&client->dev, "ds1307_read_block_data (length=%d)\n", length);
163 ret = ds1307_read_block_data_once(client, command, length, values);
164 if (ret < 0)
165 return ret;
166 do {
167 if (++tries > BLOCK_DATA_MAX_TRIES) {
168 dev_err(&client->dev,
169 "ds1307_read_block_data failed\n");
170 return -EIO;
171 }
172 memcpy(oldvalues, values, length);
173 ret = ds1307_read_block_data_once(client, command, length,
174 values);
175 if (ret < 0)
176 return ret;
177 } while (memcmp(oldvalues, values, length));
178 return length;
179}
180
181static s32 ds1307_write_block_data(struct i2c_client *client, u8 command,
182 u8 length, const u8 *values)
183{
184 u8 currvalues[I2C_SMBUS_BLOCK_MAX];
185 int tries = 0;
186
187 dev_dbg(&client->dev, "ds1307_write_block_data (length=%d)\n", length);
188 do {
189 s32 i, ret;
190
191 if (++tries > BLOCK_DATA_MAX_TRIES) {
192 dev_err(&client->dev,
193 "ds1307_write_block_data failed\n");
194 return -EIO;
195 }
196 for (i = 0; i < length; i++) {
197 ret = i2c_smbus_write_byte_data(client, command + i,
198 values[i]);
199 if (ret < 0)
200 return ret;
201 }
202 ret = ds1307_read_block_data_once(client, command, length,
203 currvalues);
204 if (ret < 0)
205 return ret;
206 } while (memcmp(currvalues, values, length));
207 return length;
208}
209
210/*----------------------------------------------------------------------*/
211
135/* 212/*
136 * The IRQ logic includes a "real" handler running in IRQ context just 213 * The IRQ logic includes a "real" handler running in IRQ context just
137 * long enough to schedule this workqueue entry. We need a task context 214 * long enough to schedule this workqueue entry. We need a task context
@@ -202,7 +279,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
202 int tmp; 279 int tmp;
203 280
204 /* read the RTC date and time registers all at once */ 281 /* read the RTC date and time registers all at once */
205 tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 282 tmp = ds1307->read_block_data(ds1307->client,
206 DS1307_REG_SECS, 7, ds1307->regs); 283 DS1307_REG_SECS, 7, ds1307->regs);
207 if (tmp != 7) { 284 if (tmp != 7) {
208 dev_err(dev, "%s error %d\n", "read", tmp); 285 dev_err(dev, "%s error %d\n", "read", tmp);
@@ -279,7 +356,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
279 "write", buf[0], buf[1], buf[2], buf[3], 356 "write", buf[0], buf[1], buf[2], buf[3],
280 buf[4], buf[5], buf[6]); 357 buf[4], buf[5], buf[6]);
281 358
282 result = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf); 359 result = ds1307->write_block_data(ds1307->client, 0, 7, buf);
283 if (result < 0) { 360 if (result < 0) {
284 dev_err(dev, "%s error %d\n", "write", result); 361 dev_err(dev, "%s error %d\n", "write", result);
285 return result; 362 return result;
@@ -297,7 +374,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
297 return -EINVAL; 374 return -EINVAL;
298 375
299 /* read all ALARM1, ALARM2, and status registers at once */ 376 /* read all ALARM1, ALARM2, and status registers at once */
300 ret = i2c_smbus_read_i2c_block_data(client, 377 ret = ds1307->read_block_data(client,
301 DS1339_REG_ALARM1_SECS, 9, ds1307->regs); 378 DS1339_REG_ALARM1_SECS, 9, ds1307->regs);
302 if (ret != 9) { 379 if (ret != 9) {
303 dev_err(dev, "%s error %d\n", "alarm read", ret); 380 dev_err(dev, "%s error %d\n", "alarm read", ret);
@@ -356,7 +433,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
356 t->enabled, t->pending); 433 t->enabled, t->pending);
357 434
358 /* read current status of both alarms and the chip */ 435 /* read current status of both alarms and the chip */
359 ret = i2c_smbus_read_i2c_block_data(client, 436 ret = ds1307->read_block_data(client,
360 DS1339_REG_ALARM1_SECS, 9, buf); 437 DS1339_REG_ALARM1_SECS, 9, buf);
361 if (ret != 9) { 438 if (ret != 9) {
362 dev_err(dev, "%s error %d\n", "alarm write", ret); 439 dev_err(dev, "%s error %d\n", "alarm write", ret);
@@ -391,7 +468,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
391 } 468 }
392 buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); 469 buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
393 470
394 ret = i2c_smbus_write_i2c_block_data(client, 471 ret = ds1307->write_block_data(client,
395 DS1339_REG_ALARM1_SECS, 9, buf); 472 DS1339_REG_ALARM1_SECS, 9, buf);
396 if (ret < 0) { 473 if (ret < 0) {
397 dev_err(dev, "can't set alarm time\n"); 474 dev_err(dev, "can't set alarm time\n");
@@ -479,7 +556,7 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr,
479 if (unlikely(!count)) 556 if (unlikely(!count))
480 return count; 557 return count;
481 558
482 result = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf); 559 result = ds1307->read_block_data(client, 8 + off, count, buf);
483 if (result < 0) 560 if (result < 0)
484 dev_err(&client->dev, "%s error %d\n", "nvram read", result); 561 dev_err(&client->dev, "%s error %d\n", "nvram read", result);
485 return result; 562 return result;
@@ -490,9 +567,11 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
490 char *buf, loff_t off, size_t count) 567 char *buf, loff_t off, size_t count)
491{ 568{
492 struct i2c_client *client; 569 struct i2c_client *client;
570 struct ds1307 *ds1307;
493 int result; 571 int result;
494 572
495 client = kobj_to_i2c_client(kobj); 573 client = kobj_to_i2c_client(kobj);
574 ds1307 = i2c_get_clientdata(client);
496 575
497 if (unlikely(off >= NVRAM_SIZE)) 576 if (unlikely(off >= NVRAM_SIZE))
498 return -EFBIG; 577 return -EFBIG;
@@ -501,7 +580,7 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
501 if (unlikely(!count)) 580 if (unlikely(!count))
502 return count; 581 return count;
503 582
504 result = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buf); 583 result = ds1307->write_block_data(client, 8 + off, count, buf);
505 if (result < 0) { 584 if (result < 0) {
506 dev_err(&client->dev, "%s error %d\n", "nvram write", result); 585 dev_err(&client->dev, "%s error %d\n", "nvram write", result);
507 return result; 586 return result;
@@ -535,9 +614,8 @@ static int __devinit ds1307_probe(struct i2c_client *client,
535 int want_irq = false; 614 int want_irq = false;
536 unsigned char *buf; 615 unsigned char *buf;
537 616
538 if (!i2c_check_functionality(adapter, 617 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)
539 I2C_FUNC_SMBUS_WRITE_BYTE_DATA | 618 && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
540 I2C_FUNC_SMBUS_I2C_BLOCK))
541 return -EIO; 619 return -EIO;
542 620
543 if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) 621 if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL)))
@@ -547,6 +625,13 @@ static int __devinit ds1307_probe(struct i2c_client *client,
547 i2c_set_clientdata(client, ds1307); 625 i2c_set_clientdata(client, ds1307);
548 ds1307->type = id->driver_data; 626 ds1307->type = id->driver_data;
549 buf = ds1307->regs; 627 buf = ds1307->regs;
628 if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
629 ds1307->read_block_data = i2c_smbus_read_i2c_block_data;
630 ds1307->write_block_data = i2c_smbus_write_i2c_block_data;
631 } else {
632 ds1307->read_block_data = ds1307_read_block_data;
633 ds1307->write_block_data = ds1307_write_block_data;
634 }
550 635
551 switch (ds1307->type) { 636 switch (ds1307->type) {
552 case ds_1337: 637 case ds_1337:
@@ -557,7 +642,7 @@ static int __devinit ds1307_probe(struct i2c_client *client,
557 want_irq = true; 642 want_irq = true;
558 } 643 }
559 /* get registers that the "rtc" read below won't read... */ 644 /* get registers that the "rtc" read below won't read... */
560 tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 645 tmp = ds1307->read_block_data(ds1307->client,
561 DS1337_REG_CONTROL, 2, buf); 646 DS1337_REG_CONTROL, 2, buf);
562 if (tmp != 2) { 647 if (tmp != 2) {
563 pr_debug("read error %d\n", tmp); 648 pr_debug("read error %d\n", tmp);
@@ -595,7 +680,7 @@ static int __devinit ds1307_probe(struct i2c_client *client,
595 680
596read_rtc: 681read_rtc:
597 /* read RTC registers */ 682 /* read RTC registers */
598 tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf); 683 tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf);
599 if (tmp != 8) { 684 if (tmp != 8) {
600 pr_debug("read error %d\n", tmp); 685 pr_debug("read error %d\n", tmp);
601 err = -EIO; 686 err = -EIO;