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.
11 #include <linux/nvmem-consumer.h>
13 #include <linux/rtc.h>
32 * struct pm8xxx_rtc_regs - describe RTC registers per PMIC versions
38 * @alarm_rw: base address of alarm read-write registers
57 * struct pm8xxx_rtc - RTC driver internal structure
58 * @rtc: RTC device
65 * @rtc_info: qcom uefi rtc-info structure
71 struct rtc_device *rtc; member
97 struct qcom_uefi_rtc_info *rtc_info = &rtc_dd->rtc_info; in pm8xxx_rtc_read_uefi_offset()
99 struct device *dev = rtc_dd->dev; in pm8xxx_rtc_read_uefi_offset()
119 return -EINVAL; in pm8xxx_rtc_read_uefi_offset()
125 offset_gps = le32_to_cpu(rtc_info->offset_gps); in pm8xxx_rtc_read_uefi_offset()
126 rtc_dd->offset = offset_gps + (u32)RTC_TIMESTAMP_EPOCH_GPS; in pm8xxx_rtc_read_uefi_offset()
133 struct qcom_uefi_rtc_info *rtc_info = &rtc_dd->rtc_info; in pm8xxx_rtc_write_uefi_offset()
135 struct device *dev = rtc_dd->dev; in pm8xxx_rtc_write_uefi_offset()
140 offset_gps = offset - (u32)RTC_TIMESTAMP_EPOCH_GPS; in pm8xxx_rtc_write_uefi_offset()
142 rtc_info->offset_gps = cpu_to_le32(offset_gps); in pm8xxx_rtc_write_uefi_offset()
160 return -ENODEV; in pm8xxx_rtc_read_uefi_offset()
165 return -ENODEV; in pm8xxx_rtc_write_uefi_offset()
176 buf = nvmem_cell_read(rtc_dd->nvmem_cell, &len); in pm8xxx_rtc_read_nvmem_offset()
179 dev_dbg(rtc_dd->dev, "failed to read nvmem offset: %d\n", rc); in pm8xxx_rtc_read_nvmem_offset()
184 dev_dbg(rtc_dd->dev, "unexpected nvmem cell size %zu\n", len); in pm8xxx_rtc_read_nvmem_offset()
186 return -EINVAL; in pm8xxx_rtc_read_nvmem_offset()
189 rtc_dd->offset = get_unaligned_le32(buf); in pm8xxx_rtc_read_nvmem_offset()
203 rc = nvmem_cell_write(rtc_dd->nvmem_cell, buf, sizeof(buf)); in pm8xxx_rtc_write_nvmem_offset()
205 dev_dbg(rtc_dd->dev, "failed to write nvmem offset: %d\n", rc); in pm8xxx_rtc_write_nvmem_offset()
214 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_rtc_read_raw()
219 rc = regmap_bulk_read(rtc_dd->regmap, regs->read, value, sizeof(value)); in pm8xxx_rtc_read_raw()
227 rc = regmap_read(rtc_dd->regmap, regs->read, &reg); in pm8xxx_rtc_read_raw()
232 rc = regmap_bulk_read(rtc_dd->regmap, regs->read, value, in pm8xxx_rtc_read_raw()
249 if (!rtc_dd->nvmem_cell && !rtc_dd->use_uefi) in pm8xxx_rtc_update_offset()
250 return -ENODEV; in pm8xxx_rtc_update_offset()
256 offset = secs - raw_secs; in pm8xxx_rtc_update_offset()
258 if (offset == rtc_dd->offset) in pm8xxx_rtc_update_offset()
265 if (abs_diff(offset, rtc_dd->offset) < 30) { in pm8xxx_rtc_update_offset()
266 rtc_dd->offset_dirty = true; in pm8xxx_rtc_update_offset()
270 if (rtc_dd->nvmem_cell) in pm8xxx_rtc_update_offset()
278 rtc_dd->offset_dirty = false; in pm8xxx_rtc_update_offset()
280 rtc_dd->offset = offset; in pm8xxx_rtc_update_offset()
286 * Steps to write the RTC registers.
288 * 2. Disable rtc if enabled.
291 * 5. Enable rtc if disabled in step 2.
296 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in __pm8xxx_rtc_set_time()
303 rc = regmap_update_bits_check(rtc_dd->regmap, regs->alarm_ctrl, in __pm8xxx_rtc_set_time()
304 regs->alarm_en, 0, &alarm_enabled); in __pm8xxx_rtc_set_time()
308 /* Disable RTC */ in __pm8xxx_rtc_set_time()
309 rc = regmap_update_bits(rtc_dd->regmap, regs->ctrl, PM8xxx_RTC_ENABLE, 0); in __pm8xxx_rtc_set_time()
314 rc = regmap_write(rtc_dd->regmap, regs->write, 0); in __pm8xxx_rtc_set_time()
319 rc = regmap_bulk_write(rtc_dd->regmap, regs->write + 1, in __pm8xxx_rtc_set_time()
320 &value[1], sizeof(value) - 1); in __pm8xxx_rtc_set_time()
325 rc = regmap_write(rtc_dd->regmap, regs->write, value[0]); in __pm8xxx_rtc_set_time()
329 /* Enable RTC */ in __pm8xxx_rtc_set_time()
330 rc = regmap_update_bits(rtc_dd->regmap, regs->ctrl, PM8xxx_RTC_ENABLE, in __pm8xxx_rtc_set_time()
336 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, in __pm8xxx_rtc_set_time()
337 regs->alarm_en, regs->alarm_en); in __pm8xxx_rtc_set_time()
353 if (rtc_dd->allow_set_time) in pm8xxx_rtc_set_time()
362 secs - rtc_dd->offset, rtc_dd->offset); in pm8xxx_rtc_set_time()
376 secs += rtc_dd->offset; in pm8xxx_rtc_read_time()
380 secs - rtc_dd->offset, rtc_dd->offset); in pm8xxx_rtc_read_time()
387 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_rtc_set_alarm()
392 secs = rtc_tm_to_time64(&alarm->time); in pm8xxx_rtc_set_alarm()
393 secs -= rtc_dd->offset; in pm8xxx_rtc_set_alarm()
396 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, in pm8xxx_rtc_set_alarm()
397 regs->alarm_en, 0); in pm8xxx_rtc_set_alarm()
401 rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value, in pm8xxx_rtc_set_alarm()
406 if (alarm->enabled) { in pm8xxx_rtc_set_alarm()
407 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, in pm8xxx_rtc_set_alarm()
408 regs->alarm_en, regs->alarm_en); in pm8xxx_rtc_set_alarm()
413 dev_dbg(dev, "set alarm: %ptRd %ptRt\n", &alarm->time, &alarm->time); in pm8xxx_rtc_set_alarm()
421 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_rtc_read_alarm()
427 rc = regmap_bulk_read(rtc_dd->regmap, regs->alarm_rw, value, in pm8xxx_rtc_read_alarm()
433 secs += rtc_dd->offset; in pm8xxx_rtc_read_alarm()
434 rtc_time64_to_tm(secs, &alarm->time); in pm8xxx_rtc_read_alarm()
436 rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); in pm8xxx_rtc_read_alarm()
440 alarm->enabled = !!(ctrl_reg & PM8xxx_RTC_ALARM_ENABLE); in pm8xxx_rtc_read_alarm()
442 dev_dbg(dev, "read alarm: %ptRd %ptRt\n", &alarm->time, &alarm->time); in pm8xxx_rtc_read_alarm()
450 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_rtc_alarm_irq_enable()
456 val = regs->alarm_en; in pm8xxx_rtc_alarm_irq_enable()
460 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, in pm8xxx_rtc_alarm_irq_enable()
461 regs->alarm_en, val); in pm8xxx_rtc_alarm_irq_enable()
467 rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value, in pm8xxx_rtc_alarm_irq_enable()
487 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_alarm_trigger()
490 rtc_update_irq(rtc_dd->rtc, 1, RTC_IRQF | RTC_AF); in pm8xxx_alarm_trigger()
493 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, in pm8xxx_alarm_trigger()
494 regs->alarm_en, 0); in pm8xxx_alarm_trigger()
499 rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl2, in pm8xxx_alarm_trigger()
509 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; in pm8xxx_rtc_enable()
511 return regmap_update_bits(rtc_dd->regmap, regs->ctrl, PM8xxx_RTC_ENABLE, in pm8xxx_rtc_enable()
556 { .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs },
557 { .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs },
558 { .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs },
559 { .compatible = "qcom,pmk8350-rtc", .data = &pmk8350_regs },
568 rtc_dd->nvmem_cell = devm_nvmem_cell_get(rtc_dd->dev, "offset"); in pm8xxx_rtc_probe_offset()
569 if (IS_ERR(rtc_dd->nvmem_cell)) { in pm8xxx_rtc_probe_offset()
570 rc = PTR_ERR(rtc_dd->nvmem_cell); in pm8xxx_rtc_probe_offset()
571 if (rc != -ENOENT) in pm8xxx_rtc_probe_offset()
573 rtc_dd->nvmem_cell = NULL; in pm8xxx_rtc_probe_offset()
582 rtc_dd->use_uefi = true; in pm8xxx_rtc_probe_offset()
594 match = of_match_node(pm8xxx_id_table, pdev->dev.of_node); in pm8xxx_rtc_probe()
596 return -ENXIO; in pm8xxx_rtc_probe()
598 rtc_dd = devm_kzalloc(&pdev->dev, sizeof(*rtc_dd), GFP_KERNEL); in pm8xxx_rtc_probe()
600 return -ENOMEM; in pm8xxx_rtc_probe()
602 rtc_dd->regs = match->data; in pm8xxx_rtc_probe()
603 rtc_dd->dev = &pdev->dev; in pm8xxx_rtc_probe()
605 rtc_dd->regmap = dev_get_regmap(pdev->dev.parent, NULL); in pm8xxx_rtc_probe()
606 if (!rtc_dd->regmap) in pm8xxx_rtc_probe()
607 return -ENXIO; in pm8xxx_rtc_probe()
609 if (!of_property_read_bool(pdev->dev.of_node, "qcom,no-alarm")) { in pm8xxx_rtc_probe()
610 rtc_dd->alarm_irq = platform_get_irq(pdev, 0); in pm8xxx_rtc_probe()
611 if (rtc_dd->alarm_irq < 0) in pm8xxx_rtc_probe()
612 return -ENXIO; in pm8xxx_rtc_probe()
615 rtc_dd->allow_set_time = of_property_read_bool(pdev->dev.of_node, in pm8xxx_rtc_probe()
616 "allow-set-time"); in pm8xxx_rtc_probe()
617 if (!rtc_dd->allow_set_time) { in pm8xxx_rtc_probe()
629 rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev); in pm8xxx_rtc_probe()
630 if (IS_ERR(rtc_dd->rtc)) in pm8xxx_rtc_probe()
631 return PTR_ERR(rtc_dd->rtc); in pm8xxx_rtc_probe()
633 rtc_dd->rtc->ops = &pm8xxx_rtc_ops; in pm8xxx_rtc_probe()
634 rtc_dd->rtc->range_max = U32_MAX; in pm8xxx_rtc_probe()
636 if (rtc_dd->alarm_irq) { in pm8xxx_rtc_probe()
637 rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->alarm_irq, in pm8xxx_rtc_probe()
644 rc = devm_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq); in pm8xxx_rtc_probe()
648 devm_device_init_wakeup(&pdev->dev); in pm8xxx_rtc_probe()
650 clear_bit(RTC_FEATURE_ALARM, rtc_dd->rtc->features); in pm8xxx_rtc_probe()
653 return devm_rtc_register_device(rtc_dd->rtc); in pm8xxx_rtc_probe()
660 if (rtc_dd->offset_dirty) { in pm8xxx_shutdown()
661 if (rtc_dd->nvmem_cell) in pm8xxx_shutdown()
662 pm8xxx_rtc_write_nvmem_offset(rtc_dd, rtc_dd->offset); in pm8xxx_shutdown()
664 pm8xxx_rtc_write_uefi_offset(rtc_dd, rtc_dd->offset); in pm8xxx_shutdown()
672 .name = "rtc-pm8xxx",
679 MODULE_ALIAS("platform:rtc-pm8xxx");
680 MODULE_DESCRIPTION("PMIC8xxx RTC driver");