Lines Matching +full:mpfs +full:- +full:rtc
1 // SPDX-License-Identifier: GPL-2.0
3 * Microchip MPFS RTC driver
5 * Copyright (c) 2021-2022 Microchip Corporation. All rights reserved.
20 #include <linux/rtc.h>
57 struct rtc_device *rtc; member
65 ctrl = readl(rtcdev->base + CONTROL_REG); in mpfs_rtc_start()
68 writel(ctrl, rtcdev->base + CONTROL_REG); in mpfs_rtc_start()
73 u32 val = readl(rtcdev->base + CONTROL_REG); in mpfs_rtc_clear_irq()
77 writel(val, rtcdev->base + CONTROL_REG); in mpfs_rtc_clear_irq()
83 (void)readl(rtcdev->base + CONTROL_REG); in mpfs_rtc_clear_irq()
91 time = readl(rtcdev->base + DATETIME_LOWER_REG); in mpfs_rtc_readtime()
92 time |= ((u64)readl(rtcdev->base + DATETIME_UPPER_REG) & DATETIME_UPPER_MASK) << 32; in mpfs_rtc_readtime()
107 writel((u32)time, rtcdev->base + DATETIME_LOWER_REG); in mpfs_rtc_settime()
108 writel((u32)(time >> 32) & DATETIME_UPPER_MASK, rtcdev->base + DATETIME_UPPER_REG); in mpfs_rtc_settime()
110 ctrl = readl(rtcdev->base + CONTROL_REG); in mpfs_rtc_settime()
113 writel(ctrl, rtcdev->base + CONTROL_REG); in mpfs_rtc_settime()
116 false, rtcdev->base + CONTROL_REG); in mpfs_rtc_settime()
118 dev_err(dev, "timed out uploading time to rtc"); in mpfs_rtc_settime()
129 u32 mode = readl(rtcdev->base + MODE_REG); in mpfs_rtc_readalarm()
132 alrm->enabled = mode & MODE_WAKE_EN; in mpfs_rtc_readalarm()
134 time = (u64)readl(rtcdev->base + ALARM_LOWER_REG) << 32; in mpfs_rtc_readalarm()
135 time |= (readl(rtcdev->base + ALARM_UPPER_REG) & ALARM_UPPER_MASK); in mpfs_rtc_readalarm()
136 rtc_time64_to_tm(time, &alrm->time); in mpfs_rtc_readalarm()
148 ctrl = readl(rtcdev->base + CONTROL_REG); in mpfs_rtc_setalarm()
150 writel(ctrl, rtcdev->base + CONTROL_REG); in mpfs_rtc_setalarm()
152 time = rtc_tm_to_time64(&alrm->time); in mpfs_rtc_setalarm()
154 writel((u32)time, rtcdev->base + ALARM_LOWER_REG); in mpfs_rtc_setalarm()
155 writel((u32)(time >> 32) & ALARM_UPPER_MASK, rtcdev->base + ALARM_UPPER_REG); in mpfs_rtc_setalarm()
158 writel(GENMASK(31, 0), rtcdev->base + COMPARE_LOWER_REG); in mpfs_rtc_setalarm()
159 writel(GENMASK(29, 0), rtcdev->base + COMPARE_UPPER_REG); in mpfs_rtc_setalarm()
161 /* Configure the RTC to enable the alarm. */ in mpfs_rtc_setalarm()
162 ctrl = readl(rtcdev->base + CONTROL_REG); in mpfs_rtc_setalarm()
163 mode = readl(rtcdev->base + MODE_REG); in mpfs_rtc_setalarm()
164 if (alrm->enabled) { in mpfs_rtc_setalarm()
172 writel(ctrl, rtcdev->base + CONTROL_REG); in mpfs_rtc_setalarm()
173 writel(mode, rtcdev->base + MODE_REG); in mpfs_rtc_setalarm()
183 ctrl = readl(rtcdev->base + CONTROL_REG); in mpfs_rtc_alarm_irq_enable()
191 writel(ctrl, rtcdev->base + CONTROL_REG); in mpfs_rtc_alarm_irq_enable()
202 rtc_update_irq(rtcdev->rtc, 1, RTC_IRQF | RTC_AF); in mpfs_rtc_wakeup_irq_handler()
222 rtcdev = devm_kzalloc(&pdev->dev, sizeof(struct mpfs_rtc_dev), GFP_KERNEL); in mpfs_rtc_probe()
224 return -ENOMEM; in mpfs_rtc_probe()
228 rtcdev->rtc = devm_rtc_allocate_device(&pdev->dev); in mpfs_rtc_probe()
229 if (IS_ERR(rtcdev->rtc)) in mpfs_rtc_probe()
230 return PTR_ERR(rtcdev->rtc); in mpfs_rtc_probe()
232 rtcdev->rtc->ops = &mpfs_rtc_ops; in mpfs_rtc_probe()
235 rtcdev->rtc->range_max = GENMASK_ULL(42, 0); in mpfs_rtc_probe()
237 clk = devm_clk_get_enabled(&pdev->dev, "rtc"); in mpfs_rtc_probe()
241 rtcdev->base = devm_platform_ioremap_resource(pdev, 0); in mpfs_rtc_probe()
242 if (IS_ERR(rtcdev->base)) { in mpfs_rtc_probe()
243 dev_dbg(&pdev->dev, "invalid ioremap resources\n"); in mpfs_rtc_probe()
244 return PTR_ERR(rtcdev->base); in mpfs_rtc_probe()
249 dev_dbg(&pdev->dev, "could not get wakeup irq\n"); in mpfs_rtc_probe()
252 ret = devm_request_irq(&pdev->dev, wakeup_irq, mpfs_rtc_wakeup_irq_handler, 0, in mpfs_rtc_probe()
253 dev_name(&pdev->dev), rtcdev); in mpfs_rtc_probe()
255 dev_dbg(&pdev->dev, "could not request wakeup irq\n"); in mpfs_rtc_probe()
260 prescaler = clk_get_rate(devm_clk_get(&pdev->dev, "rtcref")) - 1; in mpfs_rtc_probe()
262 dev_dbg(&pdev->dev, "invalid prescaler %lu\n", prescaler); in mpfs_rtc_probe()
263 return -EINVAL; in mpfs_rtc_probe()
266 writel(prescaler, rtcdev->base + PRESCALER_REG); in mpfs_rtc_probe()
267 dev_info(&pdev->dev, "prescaler set to: %lu\n", prescaler); in mpfs_rtc_probe()
269 device_init_wakeup(&pdev->dev, true); in mpfs_rtc_probe()
270 ret = dev_pm_set_wake_irq(&pdev->dev, wakeup_irq); in mpfs_rtc_probe()
272 dev_err(&pdev->dev, "failed to enable irq wake\n"); in mpfs_rtc_probe()
274 return devm_rtc_register_device(rtcdev->rtc); in mpfs_rtc_probe()
279 dev_pm_clear_wake_irq(&pdev->dev); in mpfs_rtc_remove()
283 { .compatible = "microchip,mpfs-rtc" },