Lines Matching +full:clkout +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"
71 #define ABB5ZES3_REG_ALRM_MN 0x0A /* Alarm - minute register */
73 #define ABB5ZES3_REG_ALRM_HR 0x0B /* Alarm - hours register */
75 #define ABB5ZES3_REG_ALRM_DT 0x0C /* Alarm - date register */
77 #define ABB5ZES3_REG_ALRM_DW 0x0D /* Alarm - day of the week reg. */
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 */
149 return -ENODEV; in abb5zes3_i2c_validate_chip()
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()
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()
286 return -EINVAL; in sec_from_timer_a()
301 struct rtc_time rtc_tm, *alarm_tm = &alarm->time; in _abb5zes3_rtc_read_timer()
313 ret = regmap_bulk_read(data->regmap, ABB5ZES3_REG_TIM_CLK, regs, 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()
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()
424 if (data->timer_alarm) in abb5zes3_rtc_read_alarm()
440 struct rtc_time *alarm_tm = &alarm->time; in _abb5zes3_rtc_set_alarm()
445 if (!alarm->enabled) { in _abb5zes3_rtc_set_alarm()
473 return -EINVAL; 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()
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()
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()
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()
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()
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()
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()
660 * WTAF is read-only and cleared automatically by reading the register. in abb5zes3_rtc_check_setup()
675 * (standard mode). Disable associated interrupts. Clear battery 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()
762 * Check battery low detection flag and disable battery low interrupt 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()
823 struct device *dev = &client->dev; in abb5zes3_probe()
827 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | in abb5zes3_probe()
830 return -ENODEV; in abb5zes3_probe()
846 return -ENOMEM; in abb5zes3_probe()
848 data->regmap = regmap; in abb5zes3_probe()
855 data->rtc = devm_rtc_allocate_device(dev); in abb5zes3_probe()
856 ret = PTR_ERR_OR_ZERO(data->rtc); in abb5zes3_probe()
863 if (client->irq > 0) { in abb5zes3_probe()
864 ret = devm_request_threaded_irq(dev, client->irq, NULL, in abb5zes3_probe()
870 data->irq = client->irq; in abb5zes3_probe()
872 client->irq); in abb5zes3_probe()
875 __func__, client->irq, ret); in abb5zes3_probe()
880 data->rtc->ops = &rtc_ops; in abb5zes3_probe()
881 data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; in abb5zes3_probe()
882 data->rtc->range_max = RTC_TIMESTAMP_END_2099; in abb5zes3_probe()
885 if (!data->battery_low && data->irq) { in abb5zes3_probe()
894 ret = devm_rtc_register_device(data->rtc); in abb5zes3_probe()
897 if (ret && data->irq) in abb5zes3_probe()
908 return enable_irq_wake(rtc_data->irq); in abb5zes3_rtc_suspend()
918 return disable_irq_wake(rtc_data->irq); in abb5zes3_rtc_resume()
953 MODULE_DESCRIPTION("Abracon AB-RTCMC-32.768kHz-B5ZE-S3 RTC/Alarm driver");