Lines Matching +full:rtc +full:-

1 // SPDX-License-Identifier: (GPL-2.0-only OR MIT)
9 #include <linux/clk-provider.h>
14 #include <linux/rtc.h>
17 /* rtc oscillator rate */
21 #define RTC_CTRL (0x0 << 2) /* Control RTC */
26 #define RTC_COUNTER_REG (0x1 << 2) /* Program RTC counter initial value */
28 #define RTC_ALARM0_REG (0x2 << 2) /* Program RTC alarm0 value */
30 #define RTC_SEC_ADJUST_REG (0x6 << 2) /* Control second-based timing adjustment */
35 #define RTC_INT_MASK (0x8 << 2) /* RTC interrupt mask */
38 #define RTC_INT_CLR (0x9 << 2) /* Clear RTC interrupt */
41 #define RTC_OSCIN_CTRL0 (0xa << 2) /* Control RTC clk from 24M */
42 #define RTC_OSCIN_CTRL1 (0xb << 2) /* Control RTC clk from 24M */
48 #define RTC_INT_STATUS (0xc << 2) /* RTC interrupt status */
51 #define RTC_REAL_TIME (0xd << 2) /* RTC time value */
101 struct aml_rtc_data *rtc = dev_get_drvdata(dev); in aml_rtc_read_time() local
104 /* if RTC disabled, read time failed */ in aml_rtc_read_time()
105 if (!rtc->rtc_enabled) in aml_rtc_read_time()
106 return -EINVAL; in aml_rtc_read_time()
108 regmap_read(rtc->map, RTC_REAL_TIME, &time_sec); in aml_rtc_read_time()
109 if (rtc->config->gray_stored) in aml_rtc_read_time()
119 struct aml_rtc_data *rtc = dev_get_drvdata(dev); in aml_rtc_set_time() local
122 /* if RTC disabled, first enable it */ in aml_rtc_set_time()
123 if (!rtc->rtc_enabled) { in aml_rtc_set_time()
124 regmap_write_bits(rtc->map, RTC_CTRL, RTC_ENABLE, RTC_ENABLE); in aml_rtc_set_time()
126 rtc->rtc_enabled = regmap_test_bits(rtc->map, RTC_CTRL, RTC_ENABLE); in aml_rtc_set_time()
127 if (!rtc->rtc_enabled) in aml_rtc_set_time()
128 return -EINVAL; in aml_rtc_set_time()
132 if (rtc->config->gray_stored) in aml_rtc_set_time()
134 regmap_write(rtc->map, RTC_COUNTER_REG, time_sec); in aml_rtc_set_time()
142 struct aml_rtc_data *rtc = dev_get_drvdata(dev); in aml_rtc_set_alarm() local
145 /* if RTC disabled, set alarm failed */ in aml_rtc_set_alarm()
146 if (!rtc->rtc_enabled) in aml_rtc_set_alarm()
147 return -EINVAL; in aml_rtc_set_alarm()
149 regmap_update_bits(rtc->map, RTC_CTRL, in aml_rtc_set_alarm()
151 regmap_update_bits(rtc->map, RTC_INT_MASK, in aml_rtc_set_alarm()
154 alarm_sec = rtc_tm_to_time64(&alarm->time); in aml_rtc_set_alarm()
155 if (rtc->config->gray_stored) in aml_rtc_set_alarm()
157 regmap_write(rtc->map, RTC_ALARM0_REG, alarm_sec); in aml_rtc_set_alarm()
159 dev_dbg(dev, "%s: alarm->enabled=%d alarm_set=%llds\n", __func__, in aml_rtc_set_alarm()
160 alarm->enabled, alarm_sec); in aml_rtc_set_alarm()
167 struct aml_rtc_data *rtc = dev_get_drvdata(dev); in aml_rtc_read_alarm() local
172 /* if RTC disabled, read alarm failed */ in aml_rtc_read_alarm()
173 if (!rtc->rtc_enabled) in aml_rtc_read_alarm()
174 return -EINVAL; in aml_rtc_read_alarm()
176 regmap_read(rtc->map, RTC_ALARM0_REG, &alarm_sec); in aml_rtc_read_alarm()
177 if (rtc->config->gray_stored) in aml_rtc_read_alarm()
179 rtc_time64_to_tm(alarm_sec, &alarm->time); in aml_rtc_read_alarm()
181 alarm_enable = regmap_test_bits(rtc->map, RTC_CTRL, RTC_ALRM0_EN); in aml_rtc_read_alarm()
182 alarm_mask = regmap_test_bits(rtc->map, RTC_INT_MASK, RTC_ALRM0_IRQ_MSK); in aml_rtc_read_alarm()
183 alarm->enabled = (alarm_enable && !alarm_mask) ? 1 : 0; in aml_rtc_read_alarm()
184 dev_dbg(dev, "%s: alarm->enabled=%d alarm=%us\n", __func__, in aml_rtc_read_alarm()
185 alarm->enabled, alarm_sec); in aml_rtc_read_alarm()
192 struct aml_rtc_data *rtc = dev_get_drvdata(dev); in aml_rtc_read_offset() local
197 /* if RTC disabled, read offset failed */ in aml_rtc_read_offset()
198 if (!rtc->rtc_enabled) in aml_rtc_read_offset()
199 return -EINVAL; in aml_rtc_read_offset()
201 regmap_read(rtc->map, RTC_SEC_ADJUST_REG, &reg_val); in aml_rtc_read_offset()
210 val = -val; in aml_rtc_read_offset()
219 struct aml_rtc_data *rtc = dev_get_drvdata(dev); in aml_rtc_set_offset() local
225 /* if RTC disabled, set offset failed */ in aml_rtc_set_offset()
226 if (!rtc->rtc_enabled) in aml_rtc_set_offset()
227 return -EINVAL; in aml_rtc_set_offset()
232 match_counter = 1000000000 / abs(offset) - 1; in aml_rtc_set_offset()
234 return -EINVAL; in aml_rtc_set_offset()
240 regmap_write(rtc->map, RTC_SEC_ADJUST_REG, reg_val); in aml_rtc_set_offset()
247 struct aml_rtc_data *rtc = dev_get_drvdata(dev); in aml_rtc_alarm_enable() local
250 regmap_update_bits(rtc->map, RTC_CTRL, in aml_rtc_alarm_enable()
252 regmap_update_bits(rtc->map, RTC_INT_MASK, in aml_rtc_alarm_enable()
255 regmap_update_bits(rtc->map, RTC_INT_MASK, in aml_rtc_alarm_enable()
257 regmap_update_bits(rtc->map, RTC_CTRL, in aml_rtc_alarm_enable()
276 struct aml_rtc_data *rtc = (struct aml_rtc_data *)data; in aml_rtc_handler() local
278 regmap_write(rtc->map, RTC_ALARM0_REG, 0); in aml_rtc_handler()
279 regmap_write(rtc->map, RTC_INT_CLR, RTC_ALRM0_IRQ_STATUS); in aml_rtc_handler()
281 rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); in aml_rtc_handler()
286 static void aml_rtc_init(struct aml_rtc_data *rtc) in aml_rtc_init() argument
290 rtc->rtc_enabled = regmap_test_bits(rtc->map, RTC_CTRL, RTC_ENABLE); in aml_rtc_init()
291 if (!rtc->rtc_enabled) { in aml_rtc_init()
292 if (clk_get_rate(rtc->rtc_clk) == OSC_24M) { in aml_rtc_init()
294 regmap_write_bits(rtc->map, RTC_CTRL, RTC_OSC_SEL, RTC_OSC_SEL); in aml_rtc_init()
297 * Set RTC oscillator to freq_out to freq_in/((N0*M0+N1*M1)/(M0+M1)) in aml_rtc_init()
305 regmap_write_bits(rtc->map, RTC_OSCIN_CTRL0, RTC_OSCIN_IN_EN in aml_rtc_init()
312 regmap_write_bits(rtc->map, RTC_OSCIN_CTRL1, RTC_OSCIN_OUT_N0M0 in aml_rtc_init()
316 regmap_write_bits(rtc->map, RTC_CTRL, RTC_OSC_SEL, 0); in aml_rtc_init()
319 regmap_write_bits(rtc->map, RTC_INT_MASK, in aml_rtc_init()
321 regmap_write_bits(rtc->map, RTC_CTRL, RTC_ALRM0_EN, 0); in aml_rtc_init()
326 struct device *dev = &pdev->dev; in aml_rtc_probe()
327 struct aml_rtc_data *rtc; in aml_rtc_probe() local
331 rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL); in aml_rtc_probe()
332 if (!rtc) in aml_rtc_probe()
333 return -ENOMEM; in aml_rtc_probe()
335 rtc->config = of_device_get_match_data(dev); in aml_rtc_probe()
336 if (!rtc->config) in aml_rtc_probe()
337 return -ENODEV; in aml_rtc_probe()
343 rtc->map = devm_regmap_init_mmio(dev, base, &aml_rtc_regmap_config); in aml_rtc_probe()
344 if (IS_ERR(rtc->map)) in aml_rtc_probe()
345 return dev_err_probe(dev, PTR_ERR(rtc->map), "regmap init failed\n"); in aml_rtc_probe()
347 rtc->irq = platform_get_irq(pdev, 0); in aml_rtc_probe()
348 if (rtc->irq < 0) in aml_rtc_probe()
349 return rtc->irq; in aml_rtc_probe()
351 rtc->rtc_clk = devm_clk_get(dev, "osc"); in aml_rtc_probe()
352 if (IS_ERR(rtc->rtc_clk)) in aml_rtc_probe()
353 return dev_err_probe(dev, PTR_ERR(rtc->rtc_clk), in aml_rtc_probe()
354 "failed to find rtc clock\n"); in aml_rtc_probe()
355 if (clk_get_rate(rtc->rtc_clk) != OSC_32K && clk_get_rate(rtc->rtc_clk) != OSC_24M) in aml_rtc_probe()
356 return dev_err_probe(dev, -EINVAL, "Invalid clock configuration\n"); in aml_rtc_probe()
358 rtc->sys_clk = devm_clk_get_enabled(dev, "sys"); in aml_rtc_probe()
359 if (IS_ERR(rtc->sys_clk)) in aml_rtc_probe()
360 return dev_err_probe(dev, PTR_ERR(rtc->sys_clk), in aml_rtc_probe()
361 "failed to get_enable rtc sys clk\n"); in aml_rtc_probe()
362 aml_rtc_init(rtc); in aml_rtc_probe()
365 platform_set_drvdata(pdev, rtc); in aml_rtc_probe()
367 rtc->rtc_dev = devm_rtc_allocate_device(dev); in aml_rtc_probe()
368 if (IS_ERR(rtc->rtc_dev)) { in aml_rtc_probe()
369 ret = PTR_ERR(rtc->rtc_dev); in aml_rtc_probe()
373 ret = devm_request_irq(dev, rtc->irq, aml_rtc_handler, in aml_rtc_probe()
374 IRQF_ONESHOT, "aml-rtc alarm", rtc); in aml_rtc_probe()
377 rtc->irq, ret); in aml_rtc_probe()
381 rtc->rtc_dev->ops = &aml_rtc_ops; in aml_rtc_probe()
382 rtc->rtc_dev->range_min = 0; in aml_rtc_probe()
383 rtc->rtc_dev->range_max = U32_MAX; in aml_rtc_probe()
385 ret = devm_rtc_register_device(rtc->rtc_dev); in aml_rtc_probe()
387 dev_err_probe(&pdev->dev, ret, "Failed to register RTC device: %d\n", ret); in aml_rtc_probe()
393 clk_disable_unprepare(rtc->sys_clk); in aml_rtc_probe()
402 struct aml_rtc_data *rtc = dev_get_drvdata(dev); in aml_rtc_suspend() local
405 enable_irq_wake(rtc->irq); in aml_rtc_suspend()
412 struct aml_rtc_data *rtc = dev_get_drvdata(dev); in aml_rtc_resume() local
415 disable_irq_wake(rtc->irq); in aml_rtc_resume()
426 struct aml_rtc_data *rtc = dev_get_drvdata(&pdev->dev); in aml_rtc_remove() local
428 clk_disable_unprepare(rtc->sys_clk); in aml_rtc_remove()
429 device_init_wakeup(&pdev->dev, false); in aml_rtc_remove()
441 .compatible = "amlogic,a4-rtc",
445 .compatible = "amlogic,a5-rtc",
456 .name = "aml-rtc",
463 MODULE_DESCRIPTION("Amlogic RTC driver");