aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorMylène Josserand <mylene.josserand@free-electrons.com>2016-05-03 05:54:38 -0400
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2016-05-21 11:07:00 -0400
commit0ddc5b89cd12938e251c691563f45409b4d15d98 (patch)
tree14498555704c54d71fddbd0be95e74336b60a08f /drivers/rtc
parent38201ca3c58d27ac95ee08995558c7176b4feb13 (diff)
rtc: rv3029: add alarm IRQ
Add the alarm IRQ functionality. Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-rv3029c2.c114
1 files changed, 93 insertions, 21 deletions
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 916bbc2f57de..c2ef64fb4757 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -329,6 +329,47 @@ static int rv3029_eeprom_update_bits(struct device *dev,
329 return 0; 329 return 0;
330} 330}
331 331
332static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
333{
334 struct device *dev = dev_id;
335 struct rv3029_data *rv3029 = dev_get_drvdata(dev);
336 struct mutex *lock = &rv3029->rtc->ops_lock;
337 unsigned long events = 0;
338 u8 flags, controls;
339 int ret;
340
341 mutex_lock(lock);
342
343 ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
344 if (ret) {
345 dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
346 mutex_unlock(lock);
347 return IRQ_NONE;
348 }
349
350 ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
351 if (ret) {
352 dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
353 mutex_unlock(lock);
354 return IRQ_NONE;
355 }
356
357 if (flags & RV3029_IRQ_FLAGS_AF) {
358 flags &= ~RV3029_IRQ_FLAGS_AF;
359 controls &= ~RV3029_IRQ_CTRL_AIE;
360 events |= RTC_AF;
361 }
362
363 if (events) {
364 rtc_update_irq(rv3029->rtc, 1, events);
365 rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
366 rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
367 }
368 mutex_unlock(lock);
369
370 return IRQ_HANDLED;
371}
372
332static int rv3029_read_time(struct device *dev, struct rtc_time *tm) 373static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
333{ 374{
334 u8 buf[1]; 375 u8 buf[1];
@@ -376,7 +417,7 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
376{ 417{
377 struct rtc_time *const tm = &alarm->time; 418 struct rtc_time *const tm = &alarm->time;
378 int ret; 419 int ret;
379 u8 regs[8]; 420 u8 regs[8], controls, flags;
380 421
381 ret = rv3029_get_sr(dev, regs); 422 ret = rv3029_get_sr(dev, regs);
382 if (ret < 0) { 423 if (ret < 0) {
@@ -392,6 +433,17 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
392 return ret; 433 return ret;
393 } 434 }
394 435
436 ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
437 if (ret) {
438 dev_err(dev, "Read IRQ Control Register error %d\n", ret);
439 return ret;
440 }
441 ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
442 if (ret < 0) {
443 dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
444 return ret;
445 }
446
395 tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f); 447 tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
396 tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f); 448 tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
397 tm->tm_hour = bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f); 449 tm->tm_hour = bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f);
@@ -400,16 +452,30 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
400 tm->tm_year = bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100; 452 tm->tm_year = bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100;
401 tm->tm_wday = bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1; 453 tm->tm_wday = bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1;
402 454
455 alarm->enabled = !!(controls & RV3029_IRQ_CTRL_AIE);
456 alarm->pending = (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled;
457
403 return 0; 458 return 0;
404} 459}
405 460
406static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable) 461static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable)
407{ 462{
408 int ret; 463 int ret;
464 u8 controls;
465
466 ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
467 if (ret < 0) {
468 dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
469 return ret;
470 }
409 471
410 /* enable/disable AIE irq */ 472 /* enable/disable AIE irq */
411 ret = rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE, 473 if (enable)
412 (enable ? RV3029_IRQ_CTRL_AIE : 0)); 474 controls |= RV3029_IRQ_CTRL_AIE;
475 else
476 controls &= ~RV3029_IRQ_CTRL_AIE;
477
478 ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
413 if (ret < 0) { 479 if (ret < 0) {
414 dev_err(dev, "can't update INT reg\n"); 480 dev_err(dev, "can't update INT reg\n");
415 return ret; 481 return ret;
@@ -459,26 +525,15 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
459 return ret; 525 return ret;
460 526
461 if (alarm->enabled) { 527 if (alarm->enabled) {
462 /* clear AF flag */
463 ret = rv3029_update_bits(dev, RV3029_IRQ_FLAGS,
464 RV3029_IRQ_FLAGS_AF, 0);
465 if (ret < 0) {
466 dev_err(dev, "can't clear alarm flag\n");
467 return ret;
468 }
469 /* enable AIE irq */ 528 /* enable AIE irq */
470 ret = rv3029_rtc_alarm_set_irq(dev, 1); 529 ret = rv3029_alarm_irq_enable(dev, 1);
471 if (ret) 530 if (ret)
472 return ret; 531 return ret;
473
474 dev_dbg(dev, "alarm IRQ armed\n");
475 } else { 532 } else {
476 /* disable AIE irq */ 533 /* disable AIE irq */
477 ret = rv3029_rtc_alarm_set_irq(dev, 0); 534 ret = rv3029_alarm_irq_enable(dev, 0);
478 if (ret) 535 if (ret)
479 return ret; 536 return ret;
480
481 dev_dbg(dev, "alarm IRQ disabled\n");
482 } 537 }
483 538
484 return 0; 539 return 0;
@@ -731,11 +786,9 @@ static void rv3029_hwmon_register(struct device *dev, const char *name)
731 786
732#endif /* CONFIG_RTC_DRV_RV3029_HWMON */ 787#endif /* CONFIG_RTC_DRV_RV3029_HWMON */
733 788
734static const struct rtc_class_ops rv3029_rtc_ops = { 789static struct rtc_class_ops rv3029_rtc_ops = {
735 .read_time = rv3029_read_time, 790 .read_time = rv3029_read_time,
736 .set_time = rv3029_set_time, 791 .set_time = rv3029_set_time,
737 .read_alarm = rv3029_read_alarm,
738 .set_alarm = rv3029_set_alarm,
739}; 792};
740 793
741static struct i2c_device_id rv3029_id[] = { 794static struct i2c_device_id rv3029_id[] = {
@@ -772,8 +825,27 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
772 825
773 rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops, 826 rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
774 THIS_MODULE); 827 THIS_MODULE);
828 if (IS_ERR(rv3029->rtc)) {
829 dev_err(dev, "unable to register the class device\n");
830 return PTR_ERR(rv3029->rtc);
831 }
775 832
776 return PTR_ERR_OR_ZERO(rv3029->rtc); 833 if (rv3029->irq > 0) {
834 rc = devm_request_threaded_irq(dev, rv3029->irq,
835 NULL, rv3029_handle_irq,
836 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
837 "rv3029", dev);
838 if (rc) {
839 dev_warn(dev, "unable to request IRQ, alarms disabled\n");
840 rv3029->irq = 0;
841 } else {
842 rv3029_rtc_ops.read_alarm = rv3029_read_alarm;
843 rv3029_rtc_ops.set_alarm = rv3029_set_alarm;
844 rv3029_rtc_ops.alarm_irq_enable = rv3029_alarm_irq_enable;
845 }
846 }
847
848 return 0;
777} 849}
778 850
779#if IS_ENABLED(CONFIG_I2C) 851#if IS_ENABLED(CONFIG_I2C)