diff options
Diffstat (limited to 'drivers/rtc/rtc-twl.c')
-rw-r--r-- | drivers/rtc/rtc-twl.c | 71 |
1 files changed, 52 insertions, 19 deletions
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index d43b4f6eb4e4..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 |
@@ -176,6 +177,10 @@ static int set_rtc_irq_bit(unsigned char bit) | |||
176 | unsigned char val; | 177 | unsigned char val; |
177 | int ret; | 178 | int ret; |
178 | 179 | ||
180 | /* if the bit is set, return from here */ | ||
181 | if (rtc_irq_bits & bit) | ||
182 | return 0; | ||
183 | |||
179 | val = rtc_irq_bits | bit; | 184 | val = rtc_irq_bits | bit; |
180 | val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M; | 185 | val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M; |
181 | ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); | 186 | ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); |
@@ -193,6 +198,10 @@ static int mask_rtc_irq_bit(unsigned char bit) | |||
193 | unsigned char val; | 198 | unsigned char val; |
194 | int ret; | 199 | int ret; |
195 | 200 | ||
201 | /* if the bit is clear, return from here */ | ||
202 | if (!(rtc_irq_bits & bit)) | ||
203 | return 0; | ||
204 | |||
196 | val = rtc_irq_bits & ~bit; | 205 | val = rtc_irq_bits & ~bit; |
197 | ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); | 206 | ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); |
198 | if (ret == 0) | 207 | if (ret == 0) |
@@ -227,25 +236,57 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
227 | unsigned char rtc_data[ALL_TIME_REGS + 1]; | 236 | unsigned char rtc_data[ALL_TIME_REGS + 1]; |
228 | int ret; | 237 | int ret; |
229 | u8 save_control; | 238 | u8 save_control; |
239 | u8 rtc_control; | ||
230 | 240 | ||
231 | ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); | 241 | ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); |
232 | if (ret < 0) | 242 | if (ret < 0) { |
243 | dev_err(dev, "%s: reading CTRL_REG, error %d\n", __func__, ret); | ||
233 | 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 | } | ||
234 | 258 | ||
235 | 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; | ||
236 | 261 | ||
237 | ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); | 262 | /* for twl6030/32 enable read access to static shadowed registers */ |
238 | 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); | ||
239 | return ret; | 269 | return ret; |
270 | } | ||
240 | 271 | ||
241 | ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, | 272 | ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, |
242 | (rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS); | 273 | (rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS); |
243 | 274 | ||
244 | if (ret < 0) { | 275 | if (ret < 0) { |
245 | dev_err(dev, "rtc_read_time error %d\n", ret); | 276 | dev_err(dev, "%s: reading data, error %d\n", __func__, ret); |
246 | return ret; | 277 | return ret; |
247 | } | 278 | } |
248 | 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 | |||
249 | tm->tm_sec = bcd2bin(rtc_data[0]); | 290 | tm->tm_sec = bcd2bin(rtc_data[0]); |
250 | tm->tm_min = bcd2bin(rtc_data[1]); | 291 | tm->tm_min = bcd2bin(rtc_data[1]); |
251 | tm->tm_hour = bcd2bin(rtc_data[2]); | 292 | tm->tm_hour = bcd2bin(rtc_data[2]); |
@@ -357,7 +398,7 @@ out: | |||
357 | 398 | ||
358 | static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) | 399 | static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) |
359 | { | 400 | { |
360 | unsigned long events = 0; | 401 | unsigned long events; |
361 | int ret = IRQ_NONE; | 402 | int ret = IRQ_NONE; |
362 | int res; | 403 | int res; |
363 | u8 rd_reg; | 404 | u8 rd_reg; |
@@ -372,11 +413,11 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) | |||
372 | * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM] | 413 | * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM] |
373 | */ | 414 | */ |
374 | if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) | 415 | if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) |
375 | events |= RTC_IRQF | RTC_AF; | 416 | events = RTC_IRQF | RTC_AF; |
376 | else | 417 | else |
377 | events |= RTC_IRQF | RTC_UF; | 418 | events = RTC_IRQF | RTC_PF; |
378 | 419 | ||
379 | res = twl_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M, | 420 | res = twl_rtc_write_u8(BIT_RTC_STATUS_REG_ALARM_M, |
380 | REG_RTC_STATUS_REG); | 421 | REG_RTC_STATUS_REG); |
381 | if (res) | 422 | if (res) |
382 | goto out; | 423 | goto out; |
@@ -449,19 +490,11 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) | |||
449 | REG_INT_MSK_STS_A); | 490 | REG_INT_MSK_STS_A); |
450 | } | 491 | } |
451 | 492 | ||
452 | /* Check RTC module status, Enable if it is off */ | 493 | dev_info(&pdev->dev, "Enabling TWL-RTC\n"); |
453 | ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG); | 494 | ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG); |
454 | if (ret < 0) | 495 | if (ret < 0) |
455 | goto out1; | 496 | goto out1; |
456 | 497 | ||
457 | if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) { | ||
458 | dev_info(&pdev->dev, "Enabling TWL-RTC.\n"); | ||
459 | rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M; | ||
460 | ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG); | ||
461 | if (ret < 0) | ||
462 | goto out1; | ||
463 | } | ||
464 | |||
465 | /* init cached IRQ enable bits */ | 498 | /* init cached IRQ enable bits */ |
466 | ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); | 499 | ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); |
467 | if (ret < 0) | 500 | if (ret < 0) |