• Home
  • Raw
  • Download

Lines Matching +full:snvs +full:- +full:rtc

1 // SPDX-License-Identifier: GPL-2.0+
3 // Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
12 #include <linux/rtc.h>
35 /* The maximum RTC clock cycles that are allowed to pass between two
37 * bigger difference is expected. The RTC frequency is 32kHz. With 320 cycles
44 struct rtc_device *rtc; member
56 regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &msb); in rtc_read_lpsrt()
57 regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &lsb); in rtc_read_lpsrt()
78 diff = read1 - read2; in rtc_read_lp_counter()
79 } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout); in rtc_read_lp_counter()
81 dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); in rtc_read_lp_counter()
83 /* Convert 47-bit counter to 32-bit raw second count */ in rtc_read_lp_counter()
94 regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); in rtc_read_lp_counter_lsb()
97 regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); in rtc_read_lp_counter_lsb()
98 diff = count1 - count2; in rtc_read_lp_counter_lsb()
99 } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout); in rtc_read_lp_counter_lsb()
101 dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); in rtc_read_lp_counter_lsb()
102 return -ETIMEDOUT; in rtc_read_lp_counter_lsb()
120 /* Wait for 3 CKIL cycles, about 61.0-91.5 µs */ in rtc_write_sync_lp()
125 elapsed = count2 - count1; /* wrap around _is_ handled! */ in rtc_write_sync_lp()
126 } while (elapsed < 3 && --timeout); in rtc_write_sync_lp()
128 dev_err(&data->rtc->dev, "Timeout waiting for LPSRT Counter to change\n"); in rtc_write_sync_lp()
129 return -ETIMEDOUT; in rtc_write_sync_lp()
139 regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_SRTC_ENV, in snvs_rtc_enable()
142 while (--timeout) { in snvs_rtc_enable()
143 regmap_read(data->regmap, data->offset + SNVS_LPCR, &lpcr); in snvs_rtc_enable()
155 return -ETIMEDOUT; in snvs_rtc_enable()
166 if (data->clk) { in snvs_rtc_read_time()
167 ret = clk_enable(data->clk); in snvs_rtc_read_time()
175 if (data->clk) in snvs_rtc_read_time()
176 clk_disable(data->clk); in snvs_rtc_read_time()
187 if (data->clk) { in snvs_rtc_set_time()
188 ret = clk_enable(data->clk); in snvs_rtc_set_time()
193 /* Disable RTC first */ in snvs_rtc_set_time()
198 /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */ in snvs_rtc_set_time()
199 regmap_write(data->regmap, data->offset + SNVS_LPSRTCLR, time << CNTR_TO_SECS_SH); in snvs_rtc_set_time()
200 regmap_write(data->regmap, data->offset + SNVS_LPSRTCMR, time >> (32 - CNTR_TO_SECS_SH)); in snvs_rtc_set_time()
202 /* Enable RTC again */ in snvs_rtc_set_time()
205 if (data->clk) in snvs_rtc_set_time()
206 clk_disable(data->clk); in snvs_rtc_set_time()
217 if (data->clk) { in snvs_rtc_read_alarm()
218 ret = clk_enable(data->clk); in snvs_rtc_read_alarm()
223 regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar); in snvs_rtc_read_alarm()
224 rtc_time64_to_tm(lptar, &alrm->time); in snvs_rtc_read_alarm()
226 regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr); in snvs_rtc_read_alarm()
227 alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0; in snvs_rtc_read_alarm()
229 if (data->clk) in snvs_rtc_read_alarm()
230 clk_disable(data->clk); in snvs_rtc_read_alarm()
240 if (data->clk) { in snvs_rtc_alarm_irq_enable()
241 ret = clk_enable(data->clk); in snvs_rtc_alarm_irq_enable()
246 regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, in snvs_rtc_alarm_irq_enable()
252 if (data->clk) in snvs_rtc_alarm_irq_enable()
253 clk_disable(data->clk); in snvs_rtc_alarm_irq_enable()
261 unsigned long time = rtc_tm_to_time64(&alrm->time); in snvs_rtc_set_alarm()
264 if (data->clk) { in snvs_rtc_set_alarm()
265 ret = clk_enable(data->clk); in snvs_rtc_set_alarm()
270 regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0); in snvs_rtc_set_alarm()
274 regmap_write(data->regmap, data->offset + SNVS_LPTAR, time); in snvs_rtc_set_alarm()
277 regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA); in snvs_rtc_set_alarm()
279 if (data->clk) in snvs_rtc_set_alarm()
280 clk_disable(data->clk); in snvs_rtc_set_alarm()
282 return snvs_rtc_alarm_irq_enable(dev, alrm->enabled); in snvs_rtc_set_alarm()
300 if (data->clk) in snvs_rtc_irq_handler()
301 clk_enable(data->clk); in snvs_rtc_irq_handler()
303 regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr); in snvs_rtc_irq_handler()
308 /* RTC alarm should be one-shot */ in snvs_rtc_irq_handler()
311 rtc_update_irq(data->rtc, 1, events); in snvs_rtc_irq_handler()
315 regmap_write(data->regmap, data->offset + SNVS_LPSR, lpsr); in snvs_rtc_irq_handler()
317 if (data->clk) in snvs_rtc_irq_handler()
318 clk_disable(data->clk); in snvs_rtc_irq_handler()
341 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); in snvs_rtc_probe()
343 return -ENOMEM; in snvs_rtc_probe()
345 data->rtc = devm_rtc_allocate_device(&pdev->dev); in snvs_rtc_probe()
346 if (IS_ERR(data->rtc)) in snvs_rtc_probe()
347 return PTR_ERR(data->rtc); in snvs_rtc_probe()
349 data->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap"); in snvs_rtc_probe()
351 if (IS_ERR(data->regmap)) { in snvs_rtc_probe()
352 dev_warn(&pdev->dev, "snvs rtc: you use old dts file, please update it\n"); in snvs_rtc_probe()
358 data->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, &snvs_rtc_config); in snvs_rtc_probe()
360 data->offset = SNVS_LPREGISTER_OFFSET; in snvs_rtc_probe()
361 of_property_read_u32(pdev->dev.of_node, "offset", &data->offset); in snvs_rtc_probe()
364 if (IS_ERR(data->regmap)) { in snvs_rtc_probe()
365 dev_err(&pdev->dev, "Can't find snvs syscon\n"); in snvs_rtc_probe()
366 return -ENODEV; in snvs_rtc_probe()
369 data->irq = platform_get_irq(pdev, 0); in snvs_rtc_probe()
370 if (data->irq < 0) in snvs_rtc_probe()
371 return data->irq; in snvs_rtc_probe()
373 data->clk = devm_clk_get(&pdev->dev, "snvs-rtc"); in snvs_rtc_probe()
374 if (IS_ERR(data->clk)) { in snvs_rtc_probe()
375 data->clk = NULL; in snvs_rtc_probe()
377 ret = clk_prepare_enable(data->clk); in snvs_rtc_probe()
379 dev_err(&pdev->dev, in snvs_rtc_probe()
380 "Could not prepare or enable the snvs clock\n"); in snvs_rtc_probe()
385 ret = devm_add_action_or_reset(&pdev->dev, snvs_rtc_action, data->clk); in snvs_rtc_probe()
392 regmap_write(data->regmap, data->offset + SNVS_LPPGDR, SNVS_LPPGDR_INIT); in snvs_rtc_probe()
395 regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff); in snvs_rtc_probe()
397 /* Enable RTC */ in snvs_rtc_probe()
400 dev_err(&pdev->dev, "failed to enable rtc %d\n", ret); in snvs_rtc_probe()
404 device_init_wakeup(&pdev->dev, true); in snvs_rtc_probe()
405 ret = dev_pm_set_wake_irq(&pdev->dev, data->irq); in snvs_rtc_probe()
407 dev_err(&pdev->dev, "failed to enable irq wake\n"); in snvs_rtc_probe()
409 ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler, in snvs_rtc_probe()
410 IRQF_SHARED, "rtc alarm", &pdev->dev); in snvs_rtc_probe()
412 dev_err(&pdev->dev, "failed to request irq %d: %d\n", in snvs_rtc_probe()
413 data->irq, ret); in snvs_rtc_probe()
417 data->rtc->ops = &snvs_rtc_ops; in snvs_rtc_probe()
418 data->rtc->range_max = U32_MAX; in snvs_rtc_probe()
420 return rtc_register_device(data->rtc); in snvs_rtc_probe()
427 if (data->clk) in snvs_rtc_suspend_noirq()
428 clk_disable(data->clk); in snvs_rtc_suspend_noirq()
437 if (data->clk) in snvs_rtc_resume_noirq()
438 return clk_enable(data->clk); in snvs_rtc_resume_noirq()
448 { .compatible = "fsl,sec-v4.0-mon-rtc-lp", },
464 MODULE_DESCRIPTION("Freescale SNVS RTC Driver");