Lines Matching +full:pm8941 +full:- +full:rtc
1 // SPDX-License-Identifier: GPL-2.0-only
3 * pm8xxx RTC driver
5 * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
10 #include <linux/nvmem-consumer.h>
12 #include <linux/rtc.h>
30 * struct pm8xxx_rtc_regs - describe RTC registers per PMIC versions
36 * @alarm_rw: base address of alarm read-write registers
50 * struct pm8xxx_rtc - RTC driver internal structure
51 * @rtc: RTC device
61 struct rtc_device *rtc; member
77 buf = nvmem_cell_read(rtc_dd->nvmem_cell, &len); in pm8xxx_rtc_read_nvmem_offset()
80 dev_dbg(rtc_dd->dev, "failed to read nvmem offset: %d\n", rc); in pm8xxx_rtc_read_nvmem_offset()
85 dev_dbg(rtc_dd->dev, "unexpected nvmem cell size %zu\n", len); in pm8xxx_rtc_read_nvmem_offset()
87 return -EINVAL; in pm8xxx_rtc_read_nvmem_offset()
90 rtc_dd->offset = get_unaligned_le32(buf); in pm8xxx_rtc_read_nvmem_offset()
104 rc = nvmem_cell_write(rtc_dd->nvmem_cell, buf, sizeof(buf)); in pm8xxx_rtc_write_nvmem_offset()
106 dev_dbg(rtc_dd->dev, "failed to write nvmem offset: %d\n", rc); in pm8xxx_rtc_write_nvmem_offset()
115 if (!rtc_dd->nvmem_cell) in pm8xxx_rtc_read_offset()
123 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_rtc_read_raw()
128 rc = regmap_bulk_read(rtc_dd->regmap, regs->read, value, sizeof(value)); in pm8xxx_rtc_read_raw()
136 rc = regmap_read(rtc_dd->regmap, regs->read, ®); in pm8xxx_rtc_read_raw()
141 rc = regmap_bulk_read(rtc_dd->regmap, regs->read, value, in pm8xxx_rtc_read_raw()
158 if (!rtc_dd->nvmem_cell) in pm8xxx_rtc_update_offset()
159 return -ENODEV; in pm8xxx_rtc_update_offset()
165 offset = secs - raw_secs; in pm8xxx_rtc_update_offset()
167 if (offset == rtc_dd->offset) in pm8xxx_rtc_update_offset()
174 rtc_dd->offset = offset; in pm8xxx_rtc_update_offset()
180 * Steps to write the RTC registers.
182 * 2. Disable rtc if enabled.
185 * 5. Enable rtc if disabled in step 2.
190 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in __pm8xxx_rtc_set_time()
197 rc = regmap_update_bits_check(rtc_dd->regmap, regs->alarm_ctrl, in __pm8xxx_rtc_set_time()
198 regs->alarm_en, 0, &alarm_enabled); in __pm8xxx_rtc_set_time()
202 /* Disable RTC */ in __pm8xxx_rtc_set_time()
203 rc = regmap_update_bits(rtc_dd->regmap, regs->ctrl, PM8xxx_RTC_ENABLE, 0); in __pm8xxx_rtc_set_time()
208 rc = regmap_write(rtc_dd->regmap, regs->write, 0); in __pm8xxx_rtc_set_time()
213 rc = regmap_bulk_write(rtc_dd->regmap, regs->write + 1, in __pm8xxx_rtc_set_time()
214 &value[1], sizeof(value) - 1); in __pm8xxx_rtc_set_time()
219 rc = regmap_write(rtc_dd->regmap, regs->write, value[0]); in __pm8xxx_rtc_set_time()
223 /* Enable RTC */ in __pm8xxx_rtc_set_time()
224 rc = regmap_update_bits(rtc_dd->regmap, regs->ctrl, PM8xxx_RTC_ENABLE, in __pm8xxx_rtc_set_time()
230 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, in __pm8xxx_rtc_set_time()
231 regs->alarm_en, regs->alarm_en); in __pm8xxx_rtc_set_time()
247 if (rtc_dd->allow_set_time) in pm8xxx_rtc_set_time()
256 secs - rtc_dd->offset, rtc_dd->offset); in pm8xxx_rtc_set_time()
270 secs += rtc_dd->offset; in pm8xxx_rtc_read_time()
274 secs - rtc_dd->offset, rtc_dd->offset); in pm8xxx_rtc_read_time()
281 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_rtc_set_alarm()
286 secs = rtc_tm_to_time64(&alarm->time); in pm8xxx_rtc_set_alarm()
287 secs -= rtc_dd->offset; in pm8xxx_rtc_set_alarm()
290 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, in pm8xxx_rtc_set_alarm()
291 regs->alarm_en, 0); in pm8xxx_rtc_set_alarm()
295 rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value, in pm8xxx_rtc_set_alarm()
300 if (alarm->enabled) { in pm8xxx_rtc_set_alarm()
301 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, in pm8xxx_rtc_set_alarm()
302 regs->alarm_en, regs->alarm_en); in pm8xxx_rtc_set_alarm()
307 dev_dbg(dev, "set alarm: %ptRd %ptRt\n", &alarm->time, &alarm->time); in pm8xxx_rtc_set_alarm()
315 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_rtc_read_alarm()
321 rc = regmap_bulk_read(rtc_dd->regmap, regs->alarm_rw, value, in pm8xxx_rtc_read_alarm()
327 secs += rtc_dd->offset; in pm8xxx_rtc_read_alarm()
328 rtc_time64_to_tm(secs, &alarm->time); in pm8xxx_rtc_read_alarm()
330 rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); in pm8xxx_rtc_read_alarm()
334 alarm->enabled = !!(ctrl_reg & PM8xxx_RTC_ALARM_ENABLE); in pm8xxx_rtc_read_alarm()
336 dev_dbg(dev, "read alarm: %ptRd %ptRt\n", &alarm->time, &alarm->time); in pm8xxx_rtc_read_alarm()
344 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_rtc_alarm_irq_enable()
350 val = regs->alarm_en; in pm8xxx_rtc_alarm_irq_enable()
354 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, in pm8xxx_rtc_alarm_irq_enable()
355 regs->alarm_en, val); in pm8xxx_rtc_alarm_irq_enable()
361 rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value, in pm8xxx_rtc_alarm_irq_enable()
381 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_alarm_trigger()
384 rtc_update_irq(rtc_dd->rtc, 1, RTC_IRQF | RTC_AF); in pm8xxx_alarm_trigger()
387 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, in pm8xxx_alarm_trigger()
388 regs->alarm_en, 0); in pm8xxx_alarm_trigger()
393 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl2, in pm8xxx_alarm_trigger()
403 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_rtc_enable()
405 return regmap_update_bits(rtc_dd->regmap, regs->ctrl, PM8xxx_RTC_ENABLE, in pm8xxx_rtc_enable()
450 { .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs },
451 { .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs },
452 { .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs },
453 { .compatible = "qcom,pmk8350-rtc", .data = &pmk8350_regs },
464 match = of_match_node(pm8xxx_id_table, pdev->dev.of_node); in pm8xxx_rtc_probe()
466 return -ENXIO; in pm8xxx_rtc_probe()
468 rtc_dd = devm_kzalloc(&pdev->dev, sizeof(*rtc_dd), GFP_KERNEL); in pm8xxx_rtc_probe()
470 return -ENOMEM; in pm8xxx_rtc_probe()
472 rtc_dd->regmap = dev_get_regmap(pdev->dev.parent, NULL); in pm8xxx_rtc_probe()
473 if (!rtc_dd->regmap) in pm8xxx_rtc_probe()
474 return -ENXIO; in pm8xxx_rtc_probe()
476 rtc_dd->alarm_irq = platform_get_irq(pdev, 0); in pm8xxx_rtc_probe()
477 if (rtc_dd->alarm_irq < 0) in pm8xxx_rtc_probe()
478 return -ENXIO; in pm8xxx_rtc_probe()
480 rtc_dd->allow_set_time = of_property_read_bool(pdev->dev.of_node, in pm8xxx_rtc_probe()
481 "allow-set-time"); in pm8xxx_rtc_probe()
483 rtc_dd->nvmem_cell = devm_nvmem_cell_get(&pdev->dev, "offset"); in pm8xxx_rtc_probe()
484 if (IS_ERR(rtc_dd->nvmem_cell)) { in pm8xxx_rtc_probe()
485 rc = PTR_ERR(rtc_dd->nvmem_cell); in pm8xxx_rtc_probe()
486 if (rc != -ENOENT) in pm8xxx_rtc_probe()
488 rtc_dd->nvmem_cell = NULL; in pm8xxx_rtc_probe()
491 rtc_dd->regs = match->data; in pm8xxx_rtc_probe()
492 rtc_dd->dev = &pdev->dev; in pm8xxx_rtc_probe()
494 if (!rtc_dd->allow_set_time) { in pm8xxx_rtc_probe()
506 device_init_wakeup(&pdev->dev, 1); in pm8xxx_rtc_probe()
508 rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev); in pm8xxx_rtc_probe()
509 if (IS_ERR(rtc_dd->rtc)) in pm8xxx_rtc_probe()
510 return PTR_ERR(rtc_dd->rtc); in pm8xxx_rtc_probe()
512 rtc_dd->rtc->ops = &pm8xxx_rtc_ops; in pm8xxx_rtc_probe()
513 rtc_dd->rtc->range_max = U32_MAX; in pm8xxx_rtc_probe()
515 rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->alarm_irq, in pm8xxx_rtc_probe()
522 rc = devm_rtc_register_device(rtc_dd->rtc); in pm8xxx_rtc_probe()
526 rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq); in pm8xxx_rtc_probe()
535 dev_pm_clear_wake_irq(&pdev->dev); in pm8xxx_remove()
542 .name = "rtc-pm8xxx",
549 MODULE_ALIAS("platform:rtc-pm8xxx");
550 MODULE_DESCRIPTION("PMIC8xxx RTC driver");