From patchwork Mon Jan 10 09:55:44 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: rtc-isl12022: set write enable and start the RTC already in probe function Date: Sun, 09 Jan 2011 23:55:44 -0000 From: Roman Fietze X-Patchwork-Id: 78109 Message-Id: <201101101055.44794.roman.fietze@telemotive.de> To: Alessandro Zummo Cc: rtc-linux@googlegroups.com Hello Alessandro, hello list members, When using rtc-isl12022 with brand new boards and RTC chips we detected the problem described in the patch. Any comments are welcome. >From 93bb2ee41aa65550163c61218e7ffee802fcda79 Mon Sep 17 00:00:00 2001 From: Roman Fietze Date: Mon, 10 Jan 2011 10:17:31 +0100 Subject: [PATCH] rtc-isl12022: set write enable and start the RTC already in probe function This RTC chip is delivered by the manufacturer in the not running state. Delaying the RTC initialization to the first set_datetime function call, as it was done up to know, caused problems when the kernels tries to read a stopped RTC multiple times to detect a seconds boundary, when booting up a new board the very first time. The solution is to move the initialization of the RTC to the driver's probe function. Signed-off-by: Roman Fietze --- drivers/rtc/rtc-isl12022.c | 77 +++++++++++++++++++++---------------------- 1 files changed, 38 insertions(+), 39 deletions(-) diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index ddbc797..834450f 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -16,7 +16,7 @@ #include #include -#define DRV_VERSION "0.1" +#define DRV_VERSION "0.2" /* ISL register offsets */ #define ISL12022_REG_SC 0x00 @@ -157,7 +157,6 @@ static int isl12022_get_datetime(struct i2c_client *client, struct rtc_time *tm) static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm) { - struct isl12022 *isl12022 = i2c_get_clientdata(client); size_t i; int ret; uint8_t buf[ISL12022_REG_DW + 1]; @@ -168,43 +167,6 @@ static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - if (!isl12022->write_enabled) { - - ret = isl12022_read_regs(client, ISL12022_REG_INT, buf, 1); - if (ret) - return ret; - - /* Check if WRTC (write rtc enable) is set factory default is - * 0 (not set) */ - if (!(buf[0] & ISL12022_INT_WRTC)) { - dev_info(&client->dev, - "init write enable and 24 hour format\n"); - - /* Set the write enable bit. */ - ret = isl12022_write_reg(client, - ISL12022_REG_INT, - buf[0] | ISL12022_INT_WRTC); - if (ret) - return ret; - - /* Write to any RTC register to start RTC, we use the - * HR register, setting the MIL bit to use the 24 hour - * format. */ - ret = isl12022_read_regs(client, ISL12022_REG_HR, - buf, 1); - if (ret) - return ret; - - ret = isl12022_write_reg(client, - ISL12022_REG_HR, - buf[0] | ISL12022_HR_MIL); - if (ret) - return ret; - } - - isl12022->write_enabled = 1; - } - /* hours, minutes and seconds */ buf[ISL12022_REG_SC] = bin2bcd(tm->tm_sec); buf[ISL12022_REG_MN] = bin2bcd(tm->tm_min); @@ -250,6 +212,7 @@ static int isl12022_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct isl12022 *isl12022; + uint8_t buf[ISL12022_REG_DW + 1]; int ret = 0; @@ -274,6 +237,42 @@ static int isl12022_probe(struct i2c_client *client, goto exit_kfree; } + if (!isl12022->write_enabled) { + + ret = isl12022_read_regs(client, ISL12022_REG_INT, buf, 1); + if (ret) + return ret; + + /* Check if WRTC (write rtc enable) is set, factory default is + * 0 (not set) */ + if (!(buf[0] & ISL12022_INT_WRTC)) { + dev_info(&client->dev, + "init write enable and 24 hour format\n"); + + /* Set the write enable bit. */ + ret = isl12022_write_reg(client, + ISL12022_REG_INT, + buf[0] | ISL12022_INT_WRTC); + if (ret) + return ret; + + /* Write to any RTC register to start RTC, we use the + * HR register, setting the MIL bit to use the 24 hour + * format. */ + ret = isl12022_read_regs(client, ISL12022_REG_HR, + buf, 1); + if (ret) + return ret; + ret = isl12022_write_reg(client, + ISL12022_REG_HR, + buf[0] | ISL12022_HR_MIL); + if (ret) + return ret; + } + + isl12022->write_enabled = 1; + } + return 0; exit_kfree: