Lines Matching +full:bit +full:- +full:set +full:- +full:to +full:- +full:disable

1 // SPDX-License-Identifier: GPL-2.0+
3 * rtc-ab-b5ze-s3 - Driver for Abracon AB-RTCMC-32.768Khz-B5ZE-S3
10 * https://www.abracon.com/realtimeclock/AB-RTCMC-32.768kHz-B5ZE-S3-Application-Manual.pdf
12 * This work is based on ISL12057 driver (drivers/rtc/rtc-isl12057.c).
24 #define DRV_NAME "rtc-ab-b5ze-s3"
28 #define ABB5ZES3_REG_CTRL1_CIE BIT(0) /* Pulse interrupt enable */
29 #define ABB5ZES3_REG_CTRL1_AIE BIT(1) /* Alarm interrupt enable */
30 #define ABB5ZES3_REG_CTRL1_SIE BIT(2) /* Second interrupt enable */
31 #define ABB5ZES3_REG_CTRL1_PM BIT(3) /* 24h/12h mode */
32 #define ABB5ZES3_REG_CTRL1_SR BIT(4) /* Software reset */
33 #define ABB5ZES3_REG_CTRL1_STOP BIT(5) /* RTC circuit enable */
34 #define ABB5ZES3_REG_CTRL1_CAP BIT(7)
37 #define ABB5ZES3_REG_CTRL2_CTBIE BIT(0) /* Countdown timer B int. enable */
38 #define ABB5ZES3_REG_CTRL2_CTAIE BIT(1) /* Countdown timer A int. enable */
39 #define ABB5ZES3_REG_CTRL2_WTAIE BIT(2) /* Watchdog timer A int. enable */
40 #define ABB5ZES3_REG_CTRL2_AF BIT(3) /* Alarm interrupt status */
41 #define ABB5ZES3_REG_CTRL2_SF BIT(4) /* Second interrupt status */
42 #define ABB5ZES3_REG_CTRL2_CTBF BIT(5) /* Countdown timer B int. status */
43 #define ABB5ZES3_REG_CTRL2_CTAF BIT(6) /* Countdown timer A int. status */
44 #define ABB5ZES3_REG_CTRL2_WTAF BIT(7) /* Watchdog timer A int. status */
47 #define ABB5ZES3_REG_CTRL3_PM2 BIT(7) /* Power Management bit 2 */
48 #define ABB5ZES3_REG_CTRL3_PM1 BIT(6) /* Power Management bit 1 */
49 #define ABB5ZES3_REG_CTRL3_PM0 BIT(5) /* Power Management bit 0 */
50 #define ABB5ZES3_REG_CTRL3_BSF BIT(3) /* Battery switchover int. status */
51 #define ABB5ZES3_REG_CTRL3_BLF BIT(2) /* Battery low int. status */
52 #define ABB5ZES3_REG_CTRL3_BSIE BIT(1) /* Battery switchover int. enable */
53 #define ABB5ZES3_REG_CTRL3_BLIE BIT(0) /* Battery low int. enable */
59 #define ABB5ZES3_REG_RTC_SC_OSC BIT(7) /* Clock integrity status */
62 #define ABB5ZES3_REG_RTC_HR_PM BIT(5) /* RTC Hours PM bit */
71 #define ABB5ZES3_REG_ALRM_MN 0x0A /* Alarm - minute register */
72 #define ABB5ZES3_REG_ALRM_MN_AE BIT(7) /* Minute enable */
73 #define ABB5ZES3_REG_ALRM_HR 0x0B /* Alarm - hours register */
74 #define ABB5ZES3_REG_ALRM_HR_AE BIT(7) /* Hour enable */
75 #define ABB5ZES3_REG_ALRM_DT 0x0C /* Alarm - date register */
76 #define ABB5ZES3_REG_ALRM_DT_AE BIT(7) /* Date (day of the month) enable */
77 #define ABB5ZES3_REG_ALRM_DW 0x0D /* Alarm - day of the week reg. */
78 #define ABB5ZES3_REG_ALRM_DW_AE BIT(7) /* Day of the week enable */
88 #define ABB5ZES3_REG_TIM_CLK_TAM BIT(7) /* Permanent/pulsed timer A/int. 2 */
89 #define ABB5ZES3_REG_TIM_CLK_TBM BIT(6) /* Permanent/pulsed timer B */
90 #define ABB5ZES3_REG_TIM_CLK_COF2 BIT(5) /* Clkout Freq bit 2 */
91 #define ABB5ZES3_REG_TIM_CLK_COF1 BIT(4) /* Clkout Freq bit 1 */
92 #define ABB5ZES3_REG_TIM_CLK_COF0 BIT(3) /* Clkout Freq bit 0 */
93 #define ABB5ZES3_REG_TIM_CLK_TAC1 BIT(2) /* Timer A: - 01 : countdown */
94 #define ABB5ZES3_REG_TIM_CLK_TAC0 BIT(1) /* - 10 : timer */
95 #define ABB5ZES3_REG_TIM_CLK_TBC BIT(0) /* Timer B enable */
99 #define ABB5ZES3_REG_TIMA_CLK_TAQ2 BIT(2) /* Freq bit 2 */
100 #define ABB5ZES3_REG_TIMA_CLK_TAQ1 BIT(1) /* Freq bit 1 */
101 #define ABB5ZES3_REG_TIMA_CLK_TAQ0 BIT(0) /* Freq bit 0 */
108 #define ABB5ZES3_REG_TIMB_CLK_TBW2 BIT(6)
109 #define ABB5ZES3_REG_TIMB_CLK_TBW1 BIT(5)
110 #define ABB5ZES3_REG_TIMB_CLK_TBW0 BIT(4)
111 #define ABB5ZES3_REG_TIMB_CLK_TAQ2 BIT(2)
112 #define ABB5ZES3_REG_TIMB_CLK_TAQ1 BIT(1)
113 #define ABB5ZES3_REG_TIMB_CLK_TAQ0 BIT(0)
130 * Try and match register bits w/ fixed null values to see whether we
149 return -ENODEV; in abb5zes3_i2c_validate_chip()
155 /* Clear alarm status bit. */
161 ret = regmap_update_bits(data->regmap, ABB5ZES3_REG_CTRL2, in _abb5zes3_rtc_clear_alarm()
169 /* Enable or disable alarm (i.e. alarm interrupt generation) */
175 ret = regmap_update_bits(data->regmap, ABB5ZES3_REG_CTRL1, in _abb5zes3_rtc_update_alarm()
185 /* Enable or disable timer (watchdog timer A interrupt generation) */
191 ret = regmap_update_bits(data->regmap, ABB5ZES3_REG_CTRL2, in _abb5zes3_rtc_update_timer()
212 * As we need to read CTRL1 register anyway to access 24/12h in _abb5zes3_rtc_read_time()
213 * mode bit, we do a single bulk read of both control and RTC in _abb5zes3_rtc_read_time()
217 ret = regmap_bulk_read(data->regmap, ABB5ZES3_REG_CTRL1, regs, in _abb5zes3_rtc_read_time()
227 return -ENODATA; in _abb5zes3_rtc_read_time()
229 tm->tm_sec = bcd2bin(regs[ABB5ZES3_REG_RTC_SC] & 0x7F); in _abb5zes3_rtc_read_time()
230 tm->tm_min = bcd2bin(regs[ABB5ZES3_REG_RTC_MN]); in _abb5zes3_rtc_read_time()
233 tm->tm_hour = bcd2bin(regs[ABB5ZES3_REG_RTC_HR] & 0x1f); in _abb5zes3_rtc_read_time()
235 tm->tm_hour += 12; in _abb5zes3_rtc_read_time()
237 tm->tm_hour = bcd2bin(regs[ABB5ZES3_REG_RTC_HR]); in _abb5zes3_rtc_read_time()
240 tm->tm_mday = bcd2bin(regs[ABB5ZES3_REG_RTC_DT]); in _abb5zes3_rtc_read_time()
241 tm->tm_wday = bcd2bin(regs[ABB5ZES3_REG_RTC_DW]); in _abb5zes3_rtc_read_time()
242 tm->tm_mon = bcd2bin(regs[ABB5ZES3_REG_RTC_MO]) - 1; /* starts at 1 */ in _abb5zes3_rtc_read_time()
243 tm->tm_year = bcd2bin(regs[ABB5ZES3_REG_RTC_YR]) + 100; in _abb5zes3_rtc_read_time()
254 regs[ABB5ZES3_REG_RTC_SC] = bin2bcd(tm->tm_sec); /* MSB=0 clears OSC */ in abb5zes3_rtc_set_time()
255 regs[ABB5ZES3_REG_RTC_MN] = bin2bcd(tm->tm_min); in abb5zes3_rtc_set_time()
256 regs[ABB5ZES3_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */ in abb5zes3_rtc_set_time()
257 regs[ABB5ZES3_REG_RTC_DT] = bin2bcd(tm->tm_mday); in abb5zes3_rtc_set_time()
258 regs[ABB5ZES3_REG_RTC_DW] = bin2bcd(tm->tm_wday); in abb5zes3_rtc_set_time()
259 regs[ABB5ZES3_REG_RTC_MO] = bin2bcd(tm->tm_mon + 1); in abb5zes3_rtc_set_time()
260 regs[ABB5ZES3_REG_RTC_YR] = bin2bcd(tm->tm_year - 100); in abb5zes3_rtc_set_time()
262 ret = regmap_bulk_write(data->regmap, ABB5ZES3_REG_RTC_SC, in abb5zes3_rtc_set_time()
270 * Set provided TAQ and Timer A registers (TIMA_CLK and TIMA) based on
281 * timer A with a 1Hz freq, this is what we expect to have.
286 return -EINVAL; in sec_from_timer_a()
301 struct rtc_time rtc_tm, *alarm_tm = &alarm->time; in _abb5zes3_rtc_read_timer()
311 * used to decide if timer A is enabled (as a watchdog timer). in _abb5zes3_rtc_read_timer()
313 ret = regmap_bulk_read(data->regmap, ABB5ZES3_REG_TIM_CLK, regs, in _abb5zes3_rtc_read_timer()
326 /* ... convert to seconds ... */ in _abb5zes3_rtc_read_timer()
337 ret = regmap_read(data->regmap, ABB5ZES3_REG_CTRL2, &reg); in _abb5zes3_rtc_read_timer()
344 alarm->enabled = !!(reg & ABB5ZES3_REG_CTRL2_WTAIE); in _abb5zes3_rtc_read_timer()
354 struct rtc_time rtc_tm, *alarm_tm = &alarm->time; in _abb5zes3_rtc_read_alarm()
360 ret = regmap_bulk_read(data->regmap, ABB5ZES3_REG_ALRM_MN, regs, in _abb5zes3_rtc_read_alarm()
368 alarm_tm->tm_sec = 0; in _abb5zes3_rtc_read_alarm()
369 alarm_tm->tm_min = bcd2bin(regs[0] & 0x7f); in _abb5zes3_rtc_read_alarm()
370 alarm_tm->tm_hour = bcd2bin(regs[1] & 0x3f); in _abb5zes3_rtc_read_alarm()
371 alarm_tm->tm_mday = bcd2bin(regs[2] & 0x3f); in _abb5zes3_rtc_read_alarm()
372 alarm_tm->tm_wday = -1; in _abb5zes3_rtc_read_alarm()
376 * section as a basis and increment month and then year if needed to get in _abb5zes3_rtc_read_alarm()
383 alarm_tm->tm_year = rtc_tm.tm_year; in _abb5zes3_rtc_read_alarm()
384 alarm_tm->tm_mon = rtc_tm.tm_mon; in _abb5zes3_rtc_read_alarm()
390 if (alarm_tm->tm_mon == 11) { in _abb5zes3_rtc_read_alarm()
391 alarm_tm->tm_mon = 0; in _abb5zes3_rtc_read_alarm()
392 alarm_tm->tm_year += 1; in _abb5zes3_rtc_read_alarm()
394 alarm_tm->tm_mon += 1; in _abb5zes3_rtc_read_alarm()
398 ret = regmap_read(data->regmap, ABB5ZES3_REG_CTRL1, &reg); in _abb5zes3_rtc_read_alarm()
405 alarm->enabled = !!(reg & ABB5ZES3_REG_CTRL1_AIE); in _abb5zes3_rtc_read_alarm()
411 * As the Alarm mechanism supported by the chip is only accurate to the
413 * (up to 256 seconds w/ a second accuracy) for low alarm values (below
415 * by the chip. In order for that to work, we keep track of currently
424 if (data->timer_alarm) in abb5zes3_rtc_read_alarm()
433 * Set alarm using chip alarm mechanism. It is only accurate to the
434 * minute (not the second). The function expects alarm interrupt to
440 struct rtc_time *alarm_tm = &alarm->time; in _abb5zes3_rtc_set_alarm()
445 if (!alarm->enabled) { in _abb5zes3_rtc_set_alarm()
451 * Chip only support alarms up to one month in the future. Let's in _abb5zes3_rtc_set_alarm()
473 return -EINVAL; in _abb5zes3_rtc_set_alarm()
479 * MSB to 0 enables associated alarm. in _abb5zes3_rtc_set_alarm()
481 regs[0] = bin2bcd(alarm_tm->tm_min) & 0x7f; in _abb5zes3_rtc_set_alarm()
482 regs[1] = bin2bcd(alarm_tm->tm_hour) & 0x3f; in _abb5zes3_rtc_set_alarm()
483 regs[2] = bin2bcd(alarm_tm->tm_mday) & 0x3f; in _abb5zes3_rtc_set_alarm()
486 ret = regmap_bulk_write(data->regmap, ABB5ZES3_REG_ALRM_MN, regs, in _abb5zes3_rtc_set_alarm()
495 data->timer_alarm = 0; in _abb5zes3_rtc_set_alarm()
497 /* Enable or disable alarm interrupt generation */ in _abb5zes3_rtc_set_alarm()
502 * Set alarm using timer watchdog (via timer A) mechanism. The function expects
503 * timer A interrupt to be disabled.
513 /* Program given number of seconds to Timer A registers */ in _abb5zes3_rtc_set_timer()
515 ret = regmap_bulk_write(data->regmap, ABB5ZES3_REG_TIMA_CLK, regs, in _abb5zes3_rtc_set_timer()
523 ret = regmap_update_bits(data->regmap, ABB5ZES3_REG_TIM_CLK, in _abb5zes3_rtc_set_timer()
526 dev_err(dev, "%s: failed to update timer\n", __func__); in _abb5zes3_rtc_set_timer()
529 data->timer_alarm = 1; in _abb5zes3_rtc_set_timer()
531 /* Enable or disable timer interrupt generation */ in _abb5zes3_rtc_set_timer()
532 return _abb5zes3_rtc_update_timer(dev, alarm->enabled); in _abb5zes3_rtc_set_timer()
536 * The chip has an alarm which is only accurate to the minute. In order to
544 struct rtc_time *alarm_tm = &alarm->time; in abb5zes3_rtc_set_alarm()
556 /* Let's first disable both the alarm and the timer interrupts */ in abb5zes3_rtc_set_alarm()
559 dev_err(dev, "%s: unable to disable alarm (%d)\n", __func__, in abb5zes3_rtc_set_alarm()
565 dev_err(dev, "%s: unable to disable timer (%d)\n", __func__, in abb5zes3_rtc_set_alarm()
570 data->timer_alarm = 0; in abb5zes3_rtc_set_alarm()
573 * Let's now configure the alarm; if we are expected to ring in in abb5zes3_rtc_set_alarm()
576 if ((alarm_secs > rtc_secs) && ((alarm_secs - rtc_secs) <= 240)) in abb5zes3_rtc_set_alarm()
578 alarm_secs - rtc_secs); in abb5zes3_rtc_set_alarm()
583 dev_err(dev, "%s: unable to configure alarm (%d)\n", __func__, in abb5zes3_rtc_set_alarm()
589 /* Enable or disable battery low irq generation */
599 * Check current RTC status and enable/disable what needs to be. Return 0 if
605 struct regmap *regmap = data->regmap; in abb5zes3_rtc_check_setup()
612 * is disabled here to prevent polluting the interrupt line and in abb5zes3_rtc_check_setup()
616 * We also disable all timers and set timer interrupt to permanent (not in abb5zes3_rtc_check_setup()
628 dev_err(dev, "%s: unable to initialize clkout register (%d)\n", in abb5zes3_rtc_check_setup()
636 * we set all alarm enable bits to disable current alarm setting. in abb5zes3_rtc_check_setup()
642 dev_err(dev, "%s: unable to disable alarm setting (%d)\n", in abb5zes3_rtc_check_setup()
647 /* Set Control 1 register (RTC enabled, 24hr mode, all int. disabled) */ in abb5zes3_rtc_check_setup()
653 dev_err(dev, "%s: unable to initialize CTRL1 register (%d)\n", in abb5zes3_rtc_check_setup()
659 * Set Control 2 register (timer int. disabled, alarm status cleared). in abb5zes3_rtc_check_setup()
660 * WTAF is read-only and cleared automatically by reading the register. in abb5zes3_rtc_check_setup()
668 dev_err(dev, "%s: unable to initialize CTRL2 register (%d)\n", in abb5zes3_rtc_check_setup()
675 * (standard mode). Disable associated interrupts. Clear battery in abb5zes3_rtc_check_setup()
684 dev_err(dev, "%s: unable to initialize CTRL3 register (%d)\n", in abb5zes3_rtc_check_setup()
692 dev_err(dev, "%s: unable to read osc. integrity flag (%d)\n", in abb5zes3_rtc_check_setup()
699 …dev_err(dev, "change battery (if not already done) and then set time to reset osc. failure flag.\n… in abb5zes3_rtc_check_setup()
705 * current status to avoid reenabling this interrupt later in probe in abb5zes3_rtc_check_setup()
710 dev_err(dev, "%s: unable to read battery low flag (%d)\n", in abb5zes3_rtc_check_setup()
715 data->battery_low = reg & ABB5ZES3_REG_CTRL3_BLF; in abb5zes3_rtc_check_setup()
716 if (data->battery_low) { in abb5zes3_rtc_check_setup()
734 if (rtc_data->irq) { in abb5zes3_rtc_alarm_irq_enable()
735 if (rtc_data->timer_alarm) in abb5zes3_rtc_alarm_irq_enable()
747 struct device *dev = &client->dev; in _abb5zes3_rtc_interrupt()
749 struct rtc_device *rtc = rtc_data->rtc; in _abb5zes3_rtc_interrupt()
753 ret = regmap_bulk_read(rtc_data->regmap, 0, regs, in _abb5zes3_rtc_interrupt()
756 dev_err(dev, "%s: unable to read control section (%d)!\n", in _abb5zes3_rtc_interrupt()
762 * Check battery low detection flag and disable battery low interrupt in _abb5zes3_rtc_interrupt()
763 * generation if flag is set (interrupt can only be cleared when in _abb5zes3_rtc_interrupt()
769 _abb5zes3_rtc_battery_low_irq_enable(rtc_data->regmap, false); in _abb5zes3_rtc_interrupt()
780 /* Acknowledge and disable the alarm */ in _abb5zes3_rtc_interrupt()
794 * Acknowledge and disable the alarm. Note: WTAF in _abb5zes3_rtc_interrupt()
799 rtc_data->timer_alarm = 0; in _abb5zes3_rtc_interrupt()
824 struct device *dev = &client->dev; in abb5zes3_probe()
828 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | in abb5zes3_probe()
831 return -ENODEV; in abb5zes3_probe()
847 return -ENOMEM; in abb5zes3_probe()
849 data->regmap = regmap; in abb5zes3_probe()
856 data->rtc = devm_rtc_allocate_device(dev); in abb5zes3_probe()
857 ret = PTR_ERR_OR_ZERO(data->rtc); in abb5zes3_probe()
859 dev_err(dev, "%s: unable to allocate RTC device (%d)\n", in abb5zes3_probe()
864 if (client->irq > 0) { in abb5zes3_probe()
865 ret = devm_request_threaded_irq(dev, client->irq, NULL, in abb5zes3_probe()
871 data->irq = client->irq; in abb5zes3_probe()
873 client->irq); in abb5zes3_probe()
876 __func__, client->irq, ret); in abb5zes3_probe()
881 data->rtc->ops = &rtc_ops; in abb5zes3_probe()
882 data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; in abb5zes3_probe()
883 data->rtc->range_max = RTC_TIMESTAMP_END_2099; in abb5zes3_probe()
886 if (!data->battery_low && data->irq) { in abb5zes3_probe()
895 ret = rtc_register_device(data->rtc); in abb5zes3_probe()
898 if (ret && data->irq) in abb5zes3_probe()
909 return enable_irq_wake(rtc_data->irq); in abb5zes3_rtc_suspend()
919 return disable_irq_wake(rtc_data->irq); in abb5zes3_rtc_resume()
954 MODULE_DESCRIPTION("Abracon AB-RTCMC-32.768kHz-B5ZE-S3 RTC/Alarm driver");