diff options
Diffstat (limited to 'drivers/rtc/rtc-twl.c')
| -rw-r--r-- | drivers/rtc/rtc-twl.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 4c2c6df2a9ef..258abeabf624 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c | |||
| @@ -112,6 +112,7 @@ static const u8 twl6030_rtc_reg_map[] = { | |||
| 112 | #define BIT_RTC_CTRL_REG_TEST_MODE_M 0x10 | 112 | #define BIT_RTC_CTRL_REG_TEST_MODE_M 0x10 |
| 113 | #define BIT_RTC_CTRL_REG_SET_32_COUNTER_M 0x20 | 113 | #define BIT_RTC_CTRL_REG_SET_32_COUNTER_M 0x20 |
| 114 | #define BIT_RTC_CTRL_REG_GET_TIME_M 0x40 | 114 | #define BIT_RTC_CTRL_REG_GET_TIME_M 0x40 |
| 115 | #define BIT_RTC_CTRL_REG_RTC_V_OPT 0x80 | ||
| 115 | 116 | ||
| 116 | /* RTC_STATUS_REG bitfields */ | 117 | /* RTC_STATUS_REG bitfields */ |
| 117 | #define BIT_RTC_STATUS_REG_RUN_M 0x02 | 118 | #define BIT_RTC_STATUS_REG_RUN_M 0x02 |
| @@ -235,25 +236,57 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
| 235 | unsigned char rtc_data[ALL_TIME_REGS + 1]; | 236 | unsigned char rtc_data[ALL_TIME_REGS + 1]; |
| 236 | int ret; | 237 | int ret; |
| 237 | u8 save_control; | 238 | u8 save_control; |
| 239 | u8 rtc_control; | ||
| 238 | 240 | ||
| 239 | ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); | 241 | ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); |
| 240 | if (ret < 0) | 242 | if (ret < 0) { |
| 243 | dev_err(dev, "%s: reading CTRL_REG, error %d\n", __func__, ret); | ||
| 241 | return ret; | 244 | return ret; |
| 245 | } | ||
| 246 | /* for twl6030/32 make sure BIT_RTC_CTRL_REG_GET_TIME_M is clear */ | ||
| 247 | if (twl_class_is_6030()) { | ||
| 248 | if (save_control & BIT_RTC_CTRL_REG_GET_TIME_M) { | ||
| 249 | save_control &= ~BIT_RTC_CTRL_REG_GET_TIME_M; | ||
| 250 | ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); | ||
| 251 | if (ret < 0) { | ||
| 252 | dev_err(dev, "%s clr GET_TIME, error %d\n", | ||
| 253 | __func__, ret); | ||
| 254 | return ret; | ||
| 255 | } | ||
| 256 | } | ||
| 257 | } | ||
| 242 | 258 | ||
| 243 | save_control |= BIT_RTC_CTRL_REG_GET_TIME_M; | 259 | /* Copy RTC counting registers to static registers or latches */ |
| 260 | rtc_control = save_control | BIT_RTC_CTRL_REG_GET_TIME_M; | ||
| 244 | 261 | ||
| 245 | ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); | 262 | /* for twl6030/32 enable read access to static shadowed registers */ |
| 246 | if (ret < 0) | 263 | if (twl_class_is_6030()) |
| 264 | rtc_control |= BIT_RTC_CTRL_REG_RTC_V_OPT; | ||
| 265 | |||
| 266 | ret = twl_rtc_write_u8(rtc_control, REG_RTC_CTRL_REG); | ||
| 267 | if (ret < 0) { | ||
| 268 | dev_err(dev, "%s: writing CTRL_REG, error %d\n", __func__, ret); | ||
| 247 | return ret; | 269 | return ret; |
| 270 | } | ||
| 248 | 271 | ||
| 249 | ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, | 272 | ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, |
| 250 | (rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS); | 273 | (rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS); |
| 251 | 274 | ||
| 252 | if (ret < 0) { | 275 | if (ret < 0) { |
| 253 | dev_err(dev, "rtc_read_time error %d\n", ret); | 276 | dev_err(dev, "%s: reading data, error %d\n", __func__, ret); |
| 254 | return ret; | 277 | return ret; |
| 255 | } | 278 | } |
| 256 | 279 | ||
| 280 | /* for twl6030 restore original state of rtc control register */ | ||
| 281 | if (twl_class_is_6030()) { | ||
| 282 | ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); | ||
| 283 | if (ret < 0) { | ||
| 284 | dev_err(dev, "%s: restore CTRL_REG, error %d\n", | ||
| 285 | __func__, ret); | ||
| 286 | return ret; | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 257 | tm->tm_sec = bcd2bin(rtc_data[0]); | 290 | tm->tm_sec = bcd2bin(rtc_data[0]); |
| 258 | tm->tm_min = bcd2bin(rtc_data[1]); | 291 | tm->tm_min = bcd2bin(rtc_data[1]); |
| 259 | tm->tm_hour = bcd2bin(rtc_data[2]); | 292 | tm->tm_hour = bcd2bin(rtc_data[2]); |
