Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1422629 > unrolled thread
| Started by | Andrey Smirnov <andrew.smirnov@gmail.com> |
|---|---|
| First post | 2016-06-15 08:10 +0200 |
| Last post | 2016-06-15 08:10 +0200 |
| Articles | 6 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH 00/13] DS1341 support and code cleanup Andrey Smirnov <andrew.smirnov@gmail.com> - 2016-06-15 08:10 +0200
[PATCH 08/13] RTC: ds1307: Remove register "cache" Andrey Smirnov <andrew.smirnov@gmail.com> - 2016-06-15 08:10 +0200
[PATCH 10/13] RTC: ds1307: Convert goto to a loop Andrey Smirnov <andrew.smirnov@gmail.com> - 2016-06-15 08:10 +0200
[PATCH 05/13] RTC: ds1307: Convert want_irq into a predicate Andrey Smirnov <andrew.smirnov@gmail.com> - 2016-06-15 08:10 +0200
[PATCH 06/13] RTC: ds1307: Move chip configuration into a separate routine Andrey Smirnov <andrew.smirnov@gmail.com> - 2016-06-15 08:10 +0200
[PATCH 11/13] RTC: ds1307: Redefine RX8025_REG_* to minimize extra code Andrey Smirnov <andrew.smirnov@gmail.com> - 2016-06-15 08:10 +0200
| From | Andrey Smirnov <andrew.smirnov@gmail.com> |
|---|---|
| Date | 2016-06-15 08:10 +0200 |
| Subject | [PATCH 00/13] DS1341 support and code cleanup |
| Message-ID | <rKcbv-7f2-3@gated-at.bofh.it> |
Hi everyone, This patch set contains code to add support for DS1341 variant of the chip, as well as code to support enabling/disabling some of its power savings features. Lastly the set contains a number of code cleanups intended to improve the readability of driver's code. Any feedback is appreciated! Thank you, Andrey Smirnov Andrey Smirnov (13): RTC: ds1307: Add DS1341 variant RTC: ds1307: Disable square wave and timers as default RTC: ds1307: Add DS1341 specific power-saving options RTC: ds1307: Convert ds1307_can_wakeup_device into a predicate RTC: ds1307: Convert want_irq into a predicate RTC: ds1307: Move chip configuration into a separate routine RTC: ds1307: Move chip sanity checking into a separate routine RTC: ds1307: Remove register "cache" RTC: ds1307: Constify struct ds1307 where possible RTC: ds1307: Convert goto to a loop RTC: ds1307: Redefine RX8025_REG_* to minimize extra code RTC: ds1307: Report oscillator problems more intelligently RTC: ds1307: Move last bits of sanity checking out of chip_configure .../devicetree/bindings/rtc/dallas,ds1341.txt | 23 + drivers/rtc/rtc-ds1307.c | 742 ++++++++++++--------- 2 files changed, 457 insertions(+), 308 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/dallas,ds1341.txt -- 2.5.5
[toc] | [next] | [standalone]
| From | Andrey Smirnov <andrew.smirnov@gmail.com> |
|---|---|
| Date | 2016-06-15 08:10 +0200 |
| Subject | [PATCH 08/13] RTC: ds1307: Remove register "cache" |
| Message-ID | <rKcbw-7f2-13@gated-at.bofh.it> |
| In reply to | #1422629 |
Remove shared area used by many subroutines to store values of RTC's
registers. There wasn't very much caching or sharing going on in the
code and that register cache, being a semi-global variable, only created
additional implicit dependencies between function and made code more
confusing (there were a number of functions that defined a convenience
variable pointing to ds1307->regs, but failed to use it in the code
consistently).
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/rtc/rtc-ds1307.c | 229 ++++++++++++++++++++++++-----------------------
1 file changed, 116 insertions(+), 113 deletions(-)
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 5e7eb13..3c137ab 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -110,10 +110,10 @@ enum ds_type {
# define RX8025_BIT_VDET 0x40
# define RX8025_BIT_XST 0x20
+#define DS1307_REG_COUNT 11
struct ds1307 {
u8 offset; /* register's offset */
- u8 regs[11];
u16 nvram_offset;
struct bin_attribute *nvram;
enum ds_type type;
@@ -366,30 +366,31 @@ out:
static int ds1307_get_time(struct device *dev, struct rtc_time *t)
{
+ u8 regs[DS1307_REG_COUNT];
struct ds1307 *ds1307 = dev_get_drvdata(dev);
int tmp;
/* read the RTC date and time registers all at once */
tmp = ds1307->read_block_data(ds1307->client,
- ds1307->offset, 7, ds1307->regs);
+ ds1307->offset, 7, regs);
if (tmp != 7) {
dev_err(dev, "%s error %d\n", "read", tmp);
return -EIO;
}
- dev_dbg(dev, "%s: %7ph\n", "read", ds1307->regs);
+ dev_dbg(dev, "%s: %7ph\n", "read", regs);
- t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f);
- t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f);
- tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f;
+ t->tm_sec = bcd2bin(regs[DS1307_REG_SECS] & 0x7f);
+ t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f);
+ tmp = regs[DS1307_REG_HOUR] & 0x3f;
t->tm_hour = bcd2bin(tmp);
- t->tm_wday = bcd2bin(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1;
- t->tm_mday = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
- tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f;
+ t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
+ t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f);
+ tmp = regs[DS1307_REG_MONTH] & 0x1f;
t->tm_mon = bcd2bin(tmp) - 1;
/* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */
- t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100;
+ t->tm_year = bcd2bin(regs[DS1307_REG_YEAR]) + 100;
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -406,7 +407,7 @@ 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;
+ u8 regs[DS1307_REG_COUNT];
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -414,26 +415,26 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
- buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
- buf[DS1307_REG_MIN] = bin2bcd(t->tm_min);
- buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
- buf[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
- buf[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
- buf[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
+ regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
+ regs[DS1307_REG_MIN] = bin2bcd(t->tm_min);
+ regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
+ regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
+ regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
+ regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
/* assume 20YY not 19YY */
tmp = t->tm_year - 100;
- buf[DS1307_REG_YEAR] = bin2bcd(tmp);
+ regs[DS1307_REG_YEAR] = bin2bcd(tmp);
switch (ds1307->type) {
case ds_1337:
case ds_1339:
case ds_3231:
case ds_1341:
- buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
+ regs[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
break;
case ds_1340:
- buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN
+ regs[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN
| DS1340_BIT_CENTURY;
break;
case mcp794xx:
@@ -442,17 +443,17 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
* values and need to be set again before writing the
* buffer out to the device.
*/
- buf[DS1307_REG_SECS] |= MCP794XX_BIT_ST;
- buf[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN;
+ regs[DS1307_REG_SECS] |= MCP794XX_BIT_ST;
+ regs[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN;
break;
default:
break;
}
- dev_dbg(dev, "%s: %7ph\n", "write", buf);
+ dev_dbg(dev, "%s: %7ph\n", "write", regs);
result = ds1307->write_block_data(ds1307->client,
- ds1307->offset, 7, buf);
+ ds1307->offset, 7, regs);
if (result < 0) {
dev_err(dev, "%s error %d\n", "write", result);
return result;
@@ -465,29 +466,30 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
struct i2c_client *client = to_i2c_client(dev);
struct ds1307 *ds1307 = i2c_get_clientdata(client);
int ret;
+ u8 regs[DS1307_REG_COUNT];
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
/* read all ALARM1, ALARM2, and status registers at once */
ret = ds1307->read_block_data(client,
- DS1339_REG_ALARM1_SECS, 9, ds1307->regs);
+ DS1339_REG_ALARM1_SECS, 9, regs);
if (ret != 9) {
dev_err(dev, "%s error %d\n", "alarm read", ret);
return -EIO;
}
dev_dbg(dev, "%s: %4ph, %3ph, %2ph\n", "alarm read",
- &ds1307->regs[0], &ds1307->regs[4], &ds1307->regs[7]);
+ ®s[0], ®s[4], ®s[7]);
/*
* report alarm time (ALARM1); assume 24 hour and day-of-month modes,
* and that all four fields are checked matches
*/
- t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f);
- t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f);
- t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f);
- t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f);
+ t->time.tm_sec = bcd2bin(regs[0] & 0x7f);
+ t->time.tm_min = bcd2bin(regs[1] & 0x7f);
+ t->time.tm_hour = bcd2bin(regs[2] & 0x3f);
+ t->time.tm_mday = bcd2bin(regs[3] & 0x3f);
t->time.tm_mon = -1;
t->time.tm_year = -1;
t->time.tm_wday = -1;
@@ -495,8 +497,8 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
t->time.tm_isdst = -1;
/* ... and status */
- t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE);
- t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I);
+ t->enabled = !!(regs[7] & DS1337_BIT_A1IE);
+ t->pending = !!(regs[8] & DS1337_BIT_A1I);
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, enabled=%d, pending=%d\n",
@@ -511,7 +513,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct i2c_client *client = to_i2c_client(dev);
struct ds1307 *ds1307 = i2c_get_clientdata(client);
- unsigned char *buf = ds1307->regs;
+ u8 regs[DS1307_REG_COUNT];
u8 control, status;
int ret;
@@ -526,34 +528,34 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
/* read current status of both alarms and the chip */
ret = ds1307->read_block_data(client,
- DS1339_REG_ALARM1_SECS, 9, buf);
+ DS1339_REG_ALARM1_SECS, 9, regs);
if (ret != 9) {
dev_err(dev, "%s error %d\n", "alarm write", ret);
return -EIO;
}
- control = ds1307->regs[7];
- status = ds1307->regs[8];
+ control = regs[7];
+ status = regs[8];
dev_dbg(dev, "%s: %4ph, %3ph, %02x %02x\n", "alarm set (old status)",
- &ds1307->regs[0], &ds1307->regs[4], control, status);
+ ®s[0], ®s[4], control, status);
/* set ALARM1, using 24 hour and day-of-month modes */
- buf[0] = bin2bcd(t->time.tm_sec);
- buf[1] = bin2bcd(t->time.tm_min);
- buf[2] = bin2bcd(t->time.tm_hour);
- buf[3] = bin2bcd(t->time.tm_mday);
+ regs[0] = bin2bcd(t->time.tm_sec);
+ regs[1] = bin2bcd(t->time.tm_min);
+ regs[2] = bin2bcd(t->time.tm_hour);
+ regs[3] = bin2bcd(t->time.tm_mday);
/* set ALARM2 to non-garbage */
- buf[4] = 0;
- buf[5] = 0;
- buf[6] = 0;
+ regs[4] = 0;
+ regs[5] = 0;
+ regs[6] = 0;
/* disable alarms */
- buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
- buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
+ regs[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
+ regs[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
ret = ds1307->write_block_data(client,
- DS1339_REG_ALARM1_SECS, 9, buf);
+ DS1339_REG_ALARM1_SECS, 9, regs);
if (ret < 0) {
dev_err(dev, "can't set alarm time\n");
return ret;
@@ -562,8 +564,8 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
/* optionally enable ALARM1 */
if (t->enabled) {
dev_dbg(dev, "alarm IRQ armed\n");
- buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */
- i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, buf[7]);
+ regs[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */
+ i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, regs[7]);
}
return 0;
@@ -665,7 +667,7 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct i2c_client *client = to_i2c_client(dev);
struct ds1307 *ds1307 = i2c_get_clientdata(client);
- u8 *regs = ds1307->regs;
+ u8 regs[DS1307_REG_COUNT];
int ret;
if (!test_bit(HAS_ALARM, &ds1307->flags))
@@ -679,12 +681,12 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
t->enabled = !!(regs[0] & MCP794XX_BIT_ALM0_EN);
/* Report alarm 0 time assuming 24-hour and day-of-month modes. */
- t->time.tm_sec = bcd2bin(ds1307->regs[3] & 0x7f);
- t->time.tm_min = bcd2bin(ds1307->regs[4] & 0x7f);
- t->time.tm_hour = bcd2bin(ds1307->regs[5] & 0x3f);
- t->time.tm_wday = bcd2bin(ds1307->regs[6] & 0x7) - 1;
- t->time.tm_mday = bcd2bin(ds1307->regs[7] & 0x3f);
- t->time.tm_mon = bcd2bin(ds1307->regs[8] & 0x1f) - 1;
+ t->time.tm_sec = bcd2bin(regs[3] & 0x7f);
+ t->time.tm_min = bcd2bin(regs[4] & 0x7f);
+ t->time.tm_hour = bcd2bin(regs[5] & 0x3f);
+ t->time.tm_wday = bcd2bin(regs[6] & 0x7) - 1;
+ t->time.tm_mday = bcd2bin(regs[7] & 0x3f);
+ t->time.tm_mon = bcd2bin(regs[8] & 0x1f) - 1;
t->time.tm_year = -1;
t->time.tm_yday = -1;
t->time.tm_isdst = -1;
@@ -693,9 +695,9 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
"enabled=%d polarity=%d irq=%d match=%d\n", __func__,
t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
t->time.tm_wday, t->time.tm_mday, t->time.tm_mon, t->enabled,
- !!(ds1307->regs[6] & MCP794XX_BIT_ALMX_POL),
- !!(ds1307->regs[6] & MCP794XX_BIT_ALMX_IF),
- (ds1307->regs[6] & MCP794XX_MSK_ALMX_MATCH) >> 4);
+ !!(regs[6] & MCP794XX_BIT_ALMX_POL),
+ !!(regs[6] & MCP794XX_BIT_ALMX_IF),
+ (regs[6] & MCP794XX_MSK_ALMX_MATCH) >> 4);
return 0;
}
@@ -704,7 +706,7 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct i2c_client *client = to_i2c_client(dev);
struct ds1307 *ds1307 = i2c_get_clientdata(client);
- unsigned char *regs = ds1307->regs;
+ u8 regs[DS1307_REG_COUNT];
int ret;
if (!test_bit(HAS_ALARM, &ds1307->flags))
@@ -1274,11 +1276,9 @@ static bool ds1307_want_irq(const struct ds1307 *ds1307,
static int ds1307_chip_configure(struct ds1307 *ds1307)
{
int tmp;
- unsigned char *buf;
+ u8 regs[DS1307_REG_COUNT];
struct i2c_client *client = ds1307->client;
- buf = ds1307->regs;
-
switch (ds1307->type) {
case ds_1337:
case ds_1339:
@@ -1293,32 +1293,32 @@ static int ds1307_chip_configure(struct ds1307 *ds1307)
/* get registers that the "rtc" read below won't read... */
tmp = ds1307->read_block_data(client,
- DS1337_REG_CONTROL, 2, buf);
+ DS1337_REG_CONTROL, 2, regs);
if (tmp != 2) {
dev_dbg(&ds1307->client->dev, "read error %d\n", tmp);
return -EIO;
}
/* oscillator off? turn it on, so clock can tick. */
- if (ds1307->regs[0] & DS1337_BIT_nEOSC)
- ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
+ if (regs[0] & DS1337_BIT_nEOSC)
+ regs[0] &= ~DS1337_BIT_nEOSC;
if (ds1307->type == ds_1341) {
/* Make sure we are not generating square wave
* output */
- ds1307->regs[1] &= ~DS1341_BIT_ECLK;
+ regs[1] &= ~DS1341_BIT_ECLK;
if (of_property_read_bool(client->dev.of_node,
"disable-oscillator-stop-flag"))
- ds1307->regs[1] |= DS1341_BIT_DOSF;
+ regs[1] |= DS1341_BIT_DOSF;
else
- ds1307->regs[1] &= ~DS1341_BIT_DOSF;
+ regs[1] &= ~DS1341_BIT_DOSF;
if (of_property_read_bool(client->dev.of_node,
"enable-glitch-filter"))
- ds1307->regs[0] |= DS1341_BIT_EGFIL;
+ regs[0] |= DS1341_BIT_EGFIL;
else
- ds1307->regs[0] &= ~DS1341_BIT_EGFIL;
+ regs[0] &= ~DS1341_BIT_EGFIL;
/*
* Write status register. Control register
@@ -1326,7 +1326,7 @@ static int ds1307_chip_configure(struct ds1307 *ds1307)
*/
i2c_smbus_write_byte_data(client,
DS1337_REG_STATUS,
- ds1307->regs[1]);
+ regs[1]);
}
/*
@@ -1334,19 +1334,19 @@ static int ds1307_chip_configure(struct ds1307 *ds1307)
* For some variants, be sure alarms can trigger when we're
* running on Vbackup (BBSQI/BBSQW)
*/
- ds1307->regs[0] |= DS1337_BIT_INTCN
+ regs[0] |= DS1337_BIT_INTCN
| bbsqi_bitpos[ds1307->type];
- ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
+ regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
i2c_smbus_write_byte_data(client,
DS1337_REG_CONTROL,
- ds1307->regs[0]);
+ regs[0]);
/* oscillator fault? clear flag, and warn */
- if (ds1307->regs[1] & DS1337_BIT_OSF) {
+ if (regs[1] & DS1337_BIT_OSF) {
i2c_smbus_write_byte_data(client,
DS1337_REG_STATUS,
- ds1307->regs[1] & ~DS1337_BIT_OSF);
+ regs[1] & ~DS1337_BIT_OSF);
dev_warn(&ds1307->client->dev, "SET TIME!\n");
}
break;
@@ -1354,60 +1354,60 @@ static int ds1307_chip_configure(struct ds1307 *ds1307)
case rx_8025:
tmp = i2c_smbus_read_i2c_block_data(client,
RX8025_REG_CTRL1 << 4 | 0x08,
- 2, buf);
+ 2, regs);
if (tmp != 2) {
dev_dbg(&client->dev, "read error %d\n", tmp);
return -EIO;
}
/* oscillator off? turn it on, so clock can tick. */
- if (!(ds1307->regs[1] & RX8025_BIT_XST)) {
- ds1307->regs[1] |= RX8025_BIT_XST;
+ if (!(regs[1] & RX8025_BIT_XST)) {
+ regs[1] |= RX8025_BIT_XST;
i2c_smbus_write_byte_data(client,
RX8025_REG_CTRL2 << 4 | 0x08,
- ds1307->regs[1]);
+ regs[1]);
dev_warn(&client->dev,
"oscillator stop detected - SET TIME!\n");
}
- if (ds1307->regs[1] & RX8025_BIT_PON) {
- ds1307->regs[1] &= ~RX8025_BIT_PON;
+ if (regs[1] & RX8025_BIT_PON) {
+ regs[1] &= ~RX8025_BIT_PON;
i2c_smbus_write_byte_data(client,
RX8025_REG_CTRL2 << 4 | 0x08,
- ds1307->regs[1]);
+ regs[1]);
dev_warn(&client->dev, "power-on detected\n");
}
- if (ds1307->regs[1] & RX8025_BIT_VDET) {
- ds1307->regs[1] &= ~RX8025_BIT_VDET;
+ if (regs[1] & RX8025_BIT_VDET) {
+ regs[1] &= ~RX8025_BIT_VDET;
i2c_smbus_write_byte_data(client,
RX8025_REG_CTRL2 << 4 | 0x08,
- ds1307->regs[1]);
+ regs[1]);
dev_warn(&client->dev, "voltage drop detected\n");
}
/* make sure we are running in 24hour mode */
- if (!(ds1307->regs[0] & RX8025_BIT_2412)) {
+ if (!(regs[0] & RX8025_BIT_2412)) {
u8 hour;
/* switch to 24 hour mode */
i2c_smbus_write_byte_data(client,
RX8025_REG_CTRL1 << 4 | 0x08,
- ds1307->regs[0] | RX8025_BIT_2412);
+ regs[0] | RX8025_BIT_2412);
tmp = i2c_smbus_read_i2c_block_data(client,
RX8025_REG_CTRL1 << 4 | 0x08,
- 2, buf);
+ 2, regs);
if (tmp != 2) {
dev_dbg(&client->dev, "read error %d\n", tmp);
return -EIO;
}
/* correct hour */
- hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]);
+ hour = bcd2bin(regs[DS1307_REG_HOUR]);
if (hour == 12)
hour = 0;
- if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
+ if (regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
hour += 12;
i2c_smbus_write_byte_data(client,
@@ -1425,14 +1425,12 @@ static int ds1307_chip_configure(struct ds1307 *ds1307)
static int ds1307_chip_sanity_check(struct ds1307 *ds1307)
{
int tmp;
- unsigned char *buf;
+ u8 regs[DS1307_REG_COUNT];
struct i2c_client *client = ds1307->client;
- buf = ds1307->regs;
-
read_rtc:
/* read RTC registers */
- tmp = ds1307->read_block_data(ds1307->client, ds1307->offset, 8, buf);
+ tmp = ds1307->read_block_data(ds1307->client, ds1307->offset, 8, regs);
if (tmp != 8) {
dev_dbg(&client->dev, "read error %d\n", tmp);
return -EIO;
@@ -1443,7 +1441,7 @@ read_rtc:
* specify the extra bits as must-be-zero, but there are
* still a few values that are clearly out-of-range.
*/
- tmp = ds1307->regs[DS1307_REG_SECS];
+ tmp = regs[DS1307_REG_SECS];
switch (ds1307->type) {
case ds_1307:
case m41t00:
@@ -1460,9 +1458,9 @@ read_rtc:
i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0);
/* oscillator fault? clear flag, and warn */
- if (ds1307->regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
+ if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
i2c_smbus_write_byte_data(client, DS1307_REG_CONTROL,
- ds1307->regs[DS1307_REG_CONTROL]
+ regs[DS1307_REG_CONTROL]
& ~DS1338_BIT_OSF);
dev_warn(&client->dev, "SET TIME!\n");
goto read_rtc;
@@ -1487,9 +1485,9 @@ read_rtc:
break;
case mcp794xx:
/* make sure that the backup battery is enabled */
- if (!(ds1307->regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
+ if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
i2c_smbus_write_byte_data(client, DS1307_REG_WDAY,
- ds1307->regs[DS1307_REG_WDAY]
+ regs[DS1307_REG_WDAY]
| MCP794XX_BIT_VBATEN);
}
@@ -1514,10 +1512,10 @@ static int ds1307_probe(struct i2c_client *client,
{
struct ds1307 *ds1307;
int err = -ENODEV;
- int tmp;
+ int reg;
+ u8 hour;
struct chip_desc *chip = &chips[id->driver_data];
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- unsigned char *buf;
struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
irq_handler_t irq_handler = ds1307_irq;
@@ -1550,7 +1548,6 @@ static int ds1307_probe(struct i2c_client *client,
chip->trickle_charger_setup);
}
- buf = ds1307->regs;
if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
ds1307->read_block_data = ds1307_native_smbus_read_block_data;
ds1307->write_block_data = ds1307_native_smbus_write_block_data;
@@ -1579,7 +1576,14 @@ static int ds1307_probe(struct i2c_client *client,
if (err < 0)
return err;
- tmp = ds1307->regs[DS1307_REG_HOUR];
+ reg = i2c_smbus_read_byte_data(client,
+ ds1307->offset + DS1307_REG_HOUR);
+ if (reg < 0) {
+ dev_err(&client->dev,
+ "failed to read HOUR register\n");
+ return reg;
+ }
+
switch (ds1307->type) {
case ds_1340:
case m41t00:
@@ -1591,21 +1595,21 @@ static int ds1307_probe(struct i2c_client *client,
case rx_8025:
break;
default:
- if (!(tmp & DS1307_BIT_12HR))
+ if (!(reg & DS1307_BIT_12HR))
break;
/*
* Be sure we're in 24 hour mode. Multi-master systems
* take note...
*/
- tmp = bcd2bin(tmp & 0x1f);
- if (tmp == 12)
- tmp = 0;
- if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
- tmp += 12;
+ hour = bcd2bin(reg & 0x1f);
+ if (hour == 12)
+ hour = 0;
+ if (reg & DS1307_BIT_PM)
+ hour += 12;
i2c_smbus_write_byte_data(client,
ds1307->offset + DS1307_REG_HOUR,
- bin2bcd(tmp));
+ bin2bcd(hour));
}
if (ds1307_want_irq(ds1307, chip)) {
@@ -1620,7 +1624,6 @@ static int ds1307_probe(struct i2c_client *client,
if (ds1307_can_wakeup_device(ds1307) &&
ds1307->client->irq <= 0) {
- /* Disable request for an IRQ */
dev_info(&client->dev,
"'wakeup-source' is set, request for an IRQ is disabled!\n");
/* We cannot support UIE mode if we do not have an IRQ line */
--
2.5.5
[toc] | [prev] | [next] | [standalone]
| From | Andrey Smirnov <andrew.smirnov@gmail.com> |
|---|---|
| Date | 2016-06-15 08:10 +0200 |
| Subject | [PATCH 10/13] RTC: ds1307: Convert goto to a loop |
| Message-ID | <rKcbw-7f2-27@gated-at.bofh.it> |
| In reply to | #1422629 |
Convert goto to a loop and set a hard upper limit on the number of times
driver would try to make RTC work (as opposed to having an infinite
retry loop).
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/rtc/rtc-ds1307.c | 151 +++++++++++++++++++++++++----------------------
1 file changed, 82 insertions(+), 69 deletions(-)
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index dbf8361..8ccfe5b 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -1424,87 +1424,100 @@ static int ds1307_chip_configure(const struct ds1307 *ds1307)
static int ds1307_chip_sanity_check(const struct ds1307 *ds1307)
{
- int tmp;
+ int tmp, retries;
u8 regs[DS1307_REG_COUNT];
struct i2c_client *client = ds1307->client;
-read_rtc:
- /* read RTC registers */
- tmp = ds1307->read_block_data(ds1307->client, ds1307->offset, 8, regs);
- if (tmp != 8) {
- dev_dbg(&client->dev, "read error %d\n", tmp);
- return -EIO;
- }
-
- /*
- * minimal sanity checking; some chips (like DS1340) don't
- * specify the extra bits as must-be-zero, but there are
- * still a few values that are clearly out-of-range.
- */
- tmp = regs[DS1307_REG_SECS];
- switch (ds1307->type) {
- case ds_1307:
- case m41t00:
- /* clock halted? turn it on, so clock can tick. */
- if (tmp & DS1307_BIT_CH) {
- i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0);
- dev_warn(&client->dev, "SET TIME!\n");
- goto read_rtc;
- }
- break;
- case ds_1338:
- /* clock halted? turn it on, so clock can tick. */
- if (tmp & DS1307_BIT_CH)
- i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0);
-
- /* oscillator fault? clear flag, and warn */
- if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
- i2c_smbus_write_byte_data(client, DS1307_REG_CONTROL,
- regs[DS1307_REG_CONTROL]
- & ~DS1338_BIT_OSF);
- dev_warn(&client->dev, "SET TIME!\n");
- goto read_rtc;
- }
- break;
- case ds_1340:
- /* clock halted? turn it on, so clock can tick. */
- if (tmp & DS1340_BIT_nEOSC)
- i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0);
-
- tmp = i2c_smbus_read_byte_data(client, DS1340_REG_FLAG);
- if (tmp < 0) {
+ for (retries = 0; retries < 5; retries++) {
+ /* read RTC registers */
+ tmp = ds1307->read_block_data(ds1307->client,
+ ds1307->offset, 8, regs);
+ if (tmp != 8) {
dev_dbg(&client->dev, "read error %d\n", tmp);
return -EIO;
}
- /* oscillator fault? clear flag, and warn */
- if (tmp & DS1340_BIT_OSF) {
- i2c_smbus_write_byte_data(client, DS1340_REG_FLAG, 0);
- dev_warn(&client->dev, "SET TIME!\n");
- }
- break;
- case mcp794xx:
- /* make sure that the backup battery is enabled */
- if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
- i2c_smbus_write_byte_data(client, DS1307_REG_WDAY,
- regs[DS1307_REG_WDAY]
- | MCP794XX_BIT_VBATEN);
- }
+ /*
+ * minimal sanity checking; some chips (like DS1340)
+ * don't specify the extra bits as must-be-zero, but
+ * there are still a few values that are clearly
+ * out-of-range.
+ */
+ tmp = regs[DS1307_REG_SECS];
+ switch (ds1307->type) {
+ case ds_1307:
+ case m41t00:
+ /* clock halted? turn it on, so clock can tick. */
+ if (tmp & DS1307_BIT_CH) {
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_SECS, 0);
+ dev_warn(&client->dev, "SET TIME!\n");
+ continue;
+ }
+ break;
+ case ds_1338:
+ /* clock halted? turn it on, so clock can tick. */
+ if (tmp & DS1307_BIT_CH)
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_SECS, 0);
+
+ /* oscillator fault? clear flag, and warn */
+ if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_CONTROL,
+ regs[DS1307_REG_CONTROL]
+ & ~DS1338_BIT_OSF);
+ dev_warn(&client->dev, "SET TIME!\n");
+ continue;
+ }
+ break;
+ case ds_1340:
+ /* clock halted? turn it on, so clock can tick. */
+ if (tmp & DS1340_BIT_nEOSC)
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_SECS, 0);
+
+ tmp = i2c_smbus_read_byte_data(client, DS1340_REG_FLAG);
+ if (tmp < 0) {
+ dev_dbg(&client->dev, "read error %d\n", tmp);
+ return -EIO;
+ }
+
+ /* oscillator fault? clear flag, and warn */
+ if (tmp & DS1340_BIT_OSF) {
+ i2c_smbus_write_byte_data(client,
+ DS1340_REG_FLAG, 0);
+ dev_warn(&client->dev, "SET TIME!\n");
+ }
+ return 0;
- /* clock halted? turn it on, so clock can tick. */
- if (!(tmp & MCP794XX_BIT_ST)) {
- i2c_smbus_write_byte_data(client, DS1307_REG_SECS,
- MCP794XX_BIT_ST);
- dev_warn(&client->dev, "SET TIME!\n");
- goto read_rtc;
+ case mcp794xx:
+ /* make sure that the backup battery is enabled */
+ if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_WDAY,
+ regs[DS1307_REG_WDAY]
+ | MCP794XX_BIT_VBATEN);
+ }
+
+ /* clock halted? turn it on, so clock can tick. */
+ if (!(tmp & MCP794XX_BIT_ST)) {
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_SECS,
+ MCP794XX_BIT_ST);
+ dev_warn(&client->dev, "SET TIME!\n");
+ continue;
+ }
+
+ break;
+ default:
+ break;
}
- break;
- default:
- break;
+ return 0;
}
- return 0;
+ return -EIO;
}
static int ds1307_probe(struct i2c_client *client,
--
2.5.5
[toc] | [prev] | [next] | [standalone]
| From | Andrey Smirnov <andrew.smirnov@gmail.com> |
|---|---|
| Date | 2016-06-15 08:10 +0200 |
| Subject | [PATCH 05/13] RTC: ds1307: Convert want_irq into a predicate |
| Message-ID | <rKcbw-7f2-33@gated-at.bofh.it> |
| In reply to | #1422629 |
Convert want_irq variable into a predicate in order to detangle various
independent chunks of ds1307_probe().
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/rtc/rtc-ds1307.c | 44 +++++++++++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 15 deletions(-)
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index c482d8b..81967c1 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -1247,6 +1247,30 @@ static bool ds1307_can_wakeup_device(const struct ds1307 *ds1307)
"wakeup-source");
}
+static bool ds1307_want_irq(const struct ds1307 *ds1307,
+ const struct chip_desc *chip)
+{
+
+
+ if (chip->alarm) {
+ switch (ds1307->type) {
+ case ds_1337:
+ case ds_1339:
+ case ds_3231:
+ case ds_1341:
+ return (ds1307->client->irq > 0 ||
+ ds1307_can_wakeup_device(ds1307));
+
+ case mcp794xx:
+ return (ds1307->client->irq > 0);
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
static int ds1307_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -1255,7 +1279,6 @@ static int ds1307_probe(struct i2c_client *client,
int tmp;
struct chip_desc *chip = &chips[id->driver_data];
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- bool want_irq = false;
unsigned char *buf;
struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
irq_handler_t irq_handler = ds1307_irq;
@@ -1356,10 +1379,6 @@ static int ds1307_probe(struct i2c_client *client,
| bbsqi_bitpos[ds1307->type];
ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
- if (chip->alarm && (ds1307->client->irq > 0 ||
- ds1307_can_wakeup_device(ds1307)))
- want_irq = true;
-
i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
ds1307->regs[0]);
@@ -1441,10 +1460,7 @@ static int ds1307_probe(struct i2c_client *client,
break;
case mcp794xx:
rtc_ops = &mcp794xx_rtc_ops;
- if (ds1307->client->irq > 0 && chip->alarm) {
- irq_handler = mcp794xx_irq;
- want_irq = true;
- }
+ irq_handler = mcp794xx_irq;
break;
default:
break;
@@ -1557,7 +1573,7 @@ read_rtc:
bin2bcd(tmp));
}
- if (want_irq) {
+ if (ds1307_want_irq(ds1307, chip)) {
device_set_wakeup_capable(&client->dev, true);
set_bit(HAS_ALARM, &ds1307->flags);
}
@@ -1570,13 +1586,11 @@ read_rtc:
if (ds1307_can_wakeup_device(ds1307) &&
ds1307->client->irq <= 0) {
/* Disable request for an IRQ */
- want_irq = false;
- dev_info(&client->dev, "'wakeup-source' is set, request for an IRQ is disabled!\n");
+ dev_info(&client->dev,
+ "'wakeup-source' is set, request for an IRQ is disabled!\n");
/* We cannot support UIE mode if we do not have an IRQ line */
ds1307->rtc->uie_unsupported = 1;
- }
-
- if (want_irq) {
+ } else if (ds1307_want_irq(ds1307, chip)) {
err = devm_request_threaded_irq(&client->dev,
client->irq, NULL, irq_handler,
IRQF_SHARED | IRQF_ONESHOT,
--
2.5.5
[toc] | [prev] | [next] | [standalone]
| From | Andrey Smirnov <andrew.smirnov@gmail.com> |
|---|---|
| Date | 2016-06-15 08:10 +0200 |
| Subject | [PATCH 06/13] RTC: ds1307: Move chip configuration into a separate routine |
| Message-ID | <rKcbw-7f2-39@gated-at.bofh.it> |
| In reply to | #1422629 |
Move chip configuration into a separate routine to improve readablity of
the code.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/rtc/rtc-ds1307.c | 172 ++++++++++++++++++++++++++---------------------
1 file changed, 97 insertions(+), 75 deletions(-)
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 81967c1..df8c78a 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -1271,74 +1271,32 @@ static bool ds1307_want_irq(const struct ds1307 *ds1307,
return false;
}
-static int ds1307_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ds1307_chip_configure(struct ds1307 *ds1307)
{
- struct ds1307 *ds1307;
- int err = -ENODEV;
- int tmp;
- struct chip_desc *chip = &chips[id->driver_data];
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- unsigned char *buf;
- struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
- irq_handler_t irq_handler = ds1307_irq;
-
- static const int bbsqi_bitpos[] = {
- [ds_1337] = 0,
- [ds_1341] = 0,
- [ds_1339] = DS1339_BIT_BBSQI,
- [ds_3231] = DS3231_BIT_BBSQW,
- };
- const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)
- && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
- return -EIO;
-
- ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL);
- if (!ds1307)
- return -ENOMEM;
-
- i2c_set_clientdata(client, ds1307);
-
- ds1307->client = client;
- ds1307->type = id->driver_data;
-
- if (!pdata && client->dev.of_node)
- ds1307_trickle_of_init(client, chip);
- else if (pdata && pdata->trickle_charger_setup)
- chip->trickle_charger_setup = pdata->trickle_charger_setup;
-
- if (chip->trickle_charger_setup && chip->trickle_charger_reg) {
- dev_dbg(&client->dev, "writing trickle charger info 0x%x to 0x%x\n",
- DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup,
- chip->trickle_charger_reg);
- i2c_smbus_write_byte_data(client, chip->trickle_charger_reg,
- DS13XX_TRICKLE_CHARGER_MAGIC |
- chip->trickle_charger_setup);
- }
+ int tmp;
+ unsigned char *buf;
+ struct i2c_client *client = ds1307->client;
buf = ds1307->regs;
- if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
- ds1307->read_block_data = ds1307_native_smbus_read_block_data;
- ds1307->write_block_data = ds1307_native_smbus_write_block_data;
- } else {
- ds1307->read_block_data = ds1307_read_block_data;
- ds1307->write_block_data = ds1307_write_block_data;
- }
switch (ds1307->type) {
case ds_1337:
case ds_1339:
case ds_3231:
- case ds_1341:
+ case ds_1341: {
+ static const int bbsqi_bitpos[] = {
+ [ds_1337] = 0,
+ [ds_1341] = 0,
+ [ds_1339] = DS1339_BIT_BBSQI,
+ [ds_3231] = DS3231_BIT_BBSQW,
+ };
+
/* get registers that the "rtc" read below won't read... */
- tmp = ds1307->read_block_data(ds1307->client,
- DS1337_REG_CONTROL, 2, buf);
+ tmp = ds1307->read_block_data(client,
+ DS1337_REG_CONTROL, 2, buf);
if (tmp != 2) {
- dev_dbg(&client->dev, "read error %d\n", tmp);
- err = -EIO;
- goto exit;
+ dev_dbg(&ds1307->client->dev, "read error %d\n", tmp);
+ return -EIO;
}
/* oscillator off? turn it on, so clock can tick. */
@@ -1366,7 +1324,8 @@ static int ds1307_probe(struct i2c_client *client,
* Write status register. Control register
* would be set by the code below
*/
- i2c_smbus_write_byte_data(client, DS1337_REG_STATUS,
+ i2c_smbus_write_byte_data(client,
+ DS1337_REG_STATUS,
ds1307->regs[1]);
}
@@ -1379,24 +1338,26 @@ static int ds1307_probe(struct i2c_client *client,
| bbsqi_bitpos[ds1307->type];
ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
- i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
- ds1307->regs[0]);
+ i2c_smbus_write_byte_data(client,
+ DS1337_REG_CONTROL,
+ ds1307->regs[0]);
/* oscillator fault? clear flag, and warn */
if (ds1307->regs[1] & DS1337_BIT_OSF) {
- i2c_smbus_write_byte_data(client, DS1337_REG_STATUS,
- ds1307->regs[1] & ~DS1337_BIT_OSF);
- dev_warn(&client->dev, "SET TIME!\n");
+ i2c_smbus_write_byte_data(client,
+ DS1337_REG_STATUS,
+ ds1307->regs[1] & ~DS1337_BIT_OSF);
+ dev_warn(&ds1307->client->dev, "SET TIME!\n");
}
break;
-
+ }
case rx_8025:
- tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
- RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
+ tmp = i2c_smbus_read_i2c_block_data(client,
+ RX8025_REG_CTRL1 << 4 | 0x08,
+ 2, buf);
if (tmp != 2) {
dev_dbg(&client->dev, "read error %d\n", tmp);
- err = -EIO;
- goto exit;
+ return -EIO;
}
/* oscillator off? turn it on, so clock can tick. */
@@ -1432,15 +1393,14 @@ static int ds1307_probe(struct i2c_client *client,
/* switch to 24 hour mode */
i2c_smbus_write_byte_data(client,
RX8025_REG_CTRL1 << 4 | 0x08,
- ds1307->regs[0] |
- RX8025_BIT_2412);
+ ds1307->regs[0] | RX8025_BIT_2412);
- tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
- RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
+ tmp = i2c_smbus_read_i2c_block_data(client,
+ RX8025_REG_CTRL1 << 4 | 0x08,
+ 2, buf);
if (tmp != 2) {
dev_dbg(&client->dev, "read error %d\n", tmp);
- err = -EIO;
- goto exit;
+ return -EIO;
}
/* correct hour */
@@ -1455,6 +1415,68 @@ static int ds1307_probe(struct i2c_client *client,
hour);
}
break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int ds1307_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ds1307 *ds1307;
+ int err = -ENODEV;
+ int tmp;
+ struct chip_desc *chip = &chips[id->driver_data];
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ unsigned char *buf;
+ struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
+ irq_handler_t irq_handler = ds1307_irq;
+
+ const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)
+ && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -EIO;
+
+ ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL);
+ if (!ds1307)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, ds1307);
+
+ ds1307->client = client;
+ ds1307->type = id->driver_data;
+
+ if (!pdata && client->dev.of_node)
+ ds1307_trickle_of_init(client, chip);
+ else if (pdata && pdata->trickle_charger_setup)
+ chip->trickle_charger_setup = pdata->trickle_charger_setup;
+
+ if (chip->trickle_charger_setup && chip->trickle_charger_reg) {
+ dev_dbg(&client->dev, "writing trickle charger info 0x%x to 0x%x\n",
+ DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup,
+ chip->trickle_charger_reg);
+ i2c_smbus_write_byte_data(client, chip->trickle_charger_reg,
+ DS13XX_TRICKLE_CHARGER_MAGIC |
+ chip->trickle_charger_setup);
+ }
+
+ buf = ds1307->regs;
+ if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ ds1307->read_block_data = ds1307_native_smbus_read_block_data;
+ ds1307->write_block_data = ds1307_native_smbus_write_block_data;
+ } else {
+ ds1307->read_block_data = ds1307_read_block_data;
+ ds1307->write_block_data = ds1307_write_block_data;
+ }
+
+ err = ds1307_chip_configure(ds1307);
+ if (err < 0)
+ return err;
+
+ switch (ds1307->type) {
case ds_1388:
ds1307->offset = 1; /* Seconds starts at 1 */
break;
--
2.5.5
[toc] | [prev] | [next] | [standalone]
| From | Andrey Smirnov <andrew.smirnov@gmail.com> |
|---|---|
| Date | 2016-06-15 08:10 +0200 |
| Subject | [PATCH 11/13] RTC: ds1307: Redefine RX8025_REG_* to minimize extra code |
| Message-ID | <rKcbw-7f2-25@gated-at.bofh.it> |
| In reply to | #1422629 |
The only place in the driver where RX8025_REG_* are used they are always
shifted and ORed the same way, so instead of repeating that idiom make
it a part of symbolic constant.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/rtc/rtc-ds1307.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 8ccfe5b..76e66a3 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -103,9 +103,11 @@ enum ds_type {
#define DS13XX_TRICKLE_CHARGER_MAGIC 0xa0
-#define RX8025_REG_CTRL1 0x0e
+#define RX8025_REG_CTRL1_ 0x0e
+#define RX8025_REG_CTRL1 ((RX8025_REG_CTRL1_ << 4) | 0x08)
# define RX8025_BIT_2412 0x20
-#define RX8025_REG_CTRL2 0x0f
+#define RX8025_REG_CTRL2_ 0x0f
+#define RX8025_REG_CTRL2 ((RX8025_REG_CTRL2_ << 4) | 0x08)
# define RX8025_BIT_PON 0x10
# define RX8025_BIT_VDET 0x40
# define RX8025_BIT_XST 0x20
@@ -1353,7 +1355,7 @@ static int ds1307_chip_configure(const struct ds1307 *ds1307)
}
case rx_8025:
tmp = i2c_smbus_read_i2c_block_data(client,
- RX8025_REG_CTRL1 << 4 | 0x08,
+ RX8025_REG_CTRL1,
2, regs);
if (tmp != 2) {
dev_dbg(&client->dev, "read error %d\n", tmp);
@@ -1364,7 +1366,7 @@ static int ds1307_chip_configure(const struct ds1307 *ds1307)
if (!(regs[1] & RX8025_BIT_XST)) {
regs[1] |= RX8025_BIT_XST;
i2c_smbus_write_byte_data(client,
- RX8025_REG_CTRL2 << 4 | 0x08,
+ RX8025_REG_CTRL2,
regs[1]);
dev_warn(&client->dev,
"oscillator stop detected - SET TIME!\n");
@@ -1373,7 +1375,7 @@ static int ds1307_chip_configure(const struct ds1307 *ds1307)
if (regs[1] & RX8025_BIT_PON) {
regs[1] &= ~RX8025_BIT_PON;
i2c_smbus_write_byte_data(client,
- RX8025_REG_CTRL2 << 4 | 0x08,
+ RX8025_REG_CTRL2,
regs[1]);
dev_warn(&client->dev, "power-on detected\n");
}
@@ -1381,7 +1383,7 @@ static int ds1307_chip_configure(const struct ds1307 *ds1307)
if (regs[1] & RX8025_BIT_VDET) {
regs[1] &= ~RX8025_BIT_VDET;
i2c_smbus_write_byte_data(client,
- RX8025_REG_CTRL2 << 4 | 0x08,
+ RX8025_REG_CTRL2,
regs[1]);
dev_warn(&client->dev, "voltage drop detected\n");
}
@@ -1392,11 +1394,11 @@ static int ds1307_chip_configure(const struct ds1307 *ds1307)
/* switch to 24 hour mode */
i2c_smbus_write_byte_data(client,
- RX8025_REG_CTRL1 << 4 | 0x08,
+ RX8025_REG_CTRL1,
regs[0] | RX8025_BIT_2412);
tmp = i2c_smbus_read_i2c_block_data(client,
- RX8025_REG_CTRL1 << 4 | 0x08,
+ RX8025_REG_CTRL1,
2, regs);
if (tmp != 2) {
dev_dbg(&client->dev, "read error %d\n", tmp);
--
2.5.5
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web