Lines Matching +full:chip +full:- +full:relative

1 // SPDX-License-Identifier: GPL-2.0-or-later
104 * The year parameter passed to the driver is usually an offset relative to
106 * relative to the minimum year allowed by the hardware.
108 #define SUNXI_YEAR_OFF(x) ((x)->min - 1900)
146 struct sunxi_rtc_dev *chip = (struct sunxi_rtc_dev *) id; in sunxi_rtc_alarmirq() local
149 val = readl(chip->base + SUNXI_ALRM_IRQ_STA); in sunxi_rtc_alarmirq()
153 writel(val, chip->base + SUNXI_ALRM_IRQ_STA); in sunxi_rtc_alarmirq()
155 rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF); in sunxi_rtc_alarmirq()
163 static void sunxi_rtc_setaie(unsigned int to, struct sunxi_rtc_dev *chip) in sunxi_rtc_setaie() argument
169 alrm_val = readl(chip->base + SUNXI_ALRM_EN); in sunxi_rtc_setaie()
172 alrm_irq_val = readl(chip->base + SUNXI_ALRM_IRQ_EN); in sunxi_rtc_setaie()
176 chip->base + SUNXI_ALRM_IRQ_STA); in sunxi_rtc_setaie()
179 writel(alrm_val, chip->base + SUNXI_ALRM_EN); in sunxi_rtc_setaie()
180 writel(alrm_irq_val, chip->base + SUNXI_ALRM_IRQ_EN); in sunxi_rtc_setaie()
185 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); in sunxi_rtc_getalarm() local
186 struct rtc_time *alrm_tm = &wkalrm->time; in sunxi_rtc_getalarm()
191 alrm = readl(chip->base + SUNXI_ALRM_DHMS); in sunxi_rtc_getalarm()
192 date = readl(chip->base + SUNXI_RTC_YMD); in sunxi_rtc_getalarm()
194 alrm_tm->tm_sec = SUNXI_ALRM_GET_SEC_VALUE(alrm); in sunxi_rtc_getalarm()
195 alrm_tm->tm_min = SUNXI_ALRM_GET_MIN_VALUE(alrm); in sunxi_rtc_getalarm()
196 alrm_tm->tm_hour = SUNXI_ALRM_GET_HOUR_VALUE(alrm); in sunxi_rtc_getalarm()
198 alrm_tm->tm_mday = SUNXI_DATE_GET_DAY_VALUE(date); in sunxi_rtc_getalarm()
199 alrm_tm->tm_mon = SUNXI_DATE_GET_MON_VALUE(date); in sunxi_rtc_getalarm()
200 alrm_tm->tm_year = SUNXI_DATE_GET_YEAR_VALUE(date, in sunxi_rtc_getalarm()
201 chip->data_year->mask); in sunxi_rtc_getalarm()
203 alrm_tm->tm_mon -= 1; in sunxi_rtc_getalarm()
206 * switch from (data_year->min)-relative offset to in sunxi_rtc_getalarm()
207 * a (1900)-relative one in sunxi_rtc_getalarm()
209 alrm_tm->tm_year += SUNXI_YEAR_OFF(chip->data_year); in sunxi_rtc_getalarm()
211 alrm_en = readl(chip->base + SUNXI_ALRM_IRQ_EN); in sunxi_rtc_getalarm()
213 wkalrm->enabled = 1; in sunxi_rtc_getalarm()
220 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); in sunxi_rtc_gettime() local
227 date = readl(chip->base + SUNXI_RTC_YMD); in sunxi_rtc_gettime()
228 time = readl(chip->base + SUNXI_RTC_HMS); in sunxi_rtc_gettime()
229 } while ((date != readl(chip->base + SUNXI_RTC_YMD)) || in sunxi_rtc_gettime()
230 (time != readl(chip->base + SUNXI_RTC_HMS))); in sunxi_rtc_gettime()
232 rtc_tm->tm_sec = SUNXI_TIME_GET_SEC_VALUE(time); in sunxi_rtc_gettime()
233 rtc_tm->tm_min = SUNXI_TIME_GET_MIN_VALUE(time); in sunxi_rtc_gettime()
234 rtc_tm->tm_hour = SUNXI_TIME_GET_HOUR_VALUE(time); in sunxi_rtc_gettime()
236 rtc_tm->tm_mday = SUNXI_DATE_GET_DAY_VALUE(date); in sunxi_rtc_gettime()
237 rtc_tm->tm_mon = SUNXI_DATE_GET_MON_VALUE(date); in sunxi_rtc_gettime()
238 rtc_tm->tm_year = SUNXI_DATE_GET_YEAR_VALUE(date, in sunxi_rtc_gettime()
239 chip->data_year->mask); in sunxi_rtc_gettime()
241 rtc_tm->tm_mon -= 1; in sunxi_rtc_gettime()
244 * switch from (data_year->min)-relative offset to in sunxi_rtc_gettime()
245 * a (1900)-relative one in sunxi_rtc_gettime()
247 rtc_tm->tm_year += SUNXI_YEAR_OFF(chip->data_year); in sunxi_rtc_gettime()
254 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); in sunxi_rtc_setalarm() local
255 struct rtc_time *alrm_tm = &wkalrm->time; in sunxi_rtc_setalarm()
268 return -EINVAL; in sunxi_rtc_setalarm()
274 return -EINVAL; in sunxi_rtc_setalarm()
278 dev_err(dev, "Day must be in the range 0 - 255\n"); in sunxi_rtc_setalarm()
279 return -EINVAL; in sunxi_rtc_setalarm()
284 time_gap -= time_gap_day * SEC_IN_DAY; in sunxi_rtc_setalarm()
286 time_gap -= time_gap_hour * SEC_IN_HOUR; in sunxi_rtc_setalarm()
288 time_gap -= time_gap_min * SEC_IN_MIN; in sunxi_rtc_setalarm()
290 sunxi_rtc_setaie(0, chip); in sunxi_rtc_setalarm()
291 writel(0, chip->base + SUNXI_ALRM_DHMS); in sunxi_rtc_setalarm()
298 writel(alrm, chip->base + SUNXI_ALRM_DHMS); in sunxi_rtc_setalarm()
300 writel(0, chip->base + SUNXI_ALRM_IRQ_EN); in sunxi_rtc_setalarm()
301 writel(SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN, chip->base + SUNXI_ALRM_IRQ_EN); in sunxi_rtc_setalarm()
303 sunxi_rtc_setaie(wkalrm->enabled, chip); in sunxi_rtc_setalarm()
308 static int sunxi_rtc_wait(struct sunxi_rtc_dev *chip, int offset, in sunxi_rtc_wait() argument
315 reg = readl(chip->base + offset); in sunxi_rtc_wait()
323 return -ETIMEDOUT; in sunxi_rtc_wait()
328 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); in sunxi_rtc_settime() local
334 * the input rtc_tm->tm_year is the offset relative to 1900. We use in sunxi_rtc_settime()
339 year = rtc_tm->tm_year + 1900; in sunxi_rtc_settime()
340 if (year < chip->data_year->min || year > chip->data_year->max) { in sunxi_rtc_settime()
341 dev_err(dev, "rtc only supports year in range %u - %u\n", in sunxi_rtc_settime()
342 chip->data_year->min, chip->data_year->max); in sunxi_rtc_settime()
343 return -EINVAL; in sunxi_rtc_settime()
346 rtc_tm->tm_year -= SUNXI_YEAR_OFF(chip->data_year); in sunxi_rtc_settime()
347 rtc_tm->tm_mon += 1; in sunxi_rtc_settime()
349 date = SUNXI_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) | in sunxi_rtc_settime()
350 SUNXI_DATE_SET_MON_VALUE(rtc_tm->tm_mon) | in sunxi_rtc_settime()
351 SUNXI_DATE_SET_YEAR_VALUE(rtc_tm->tm_year, in sunxi_rtc_settime()
352 chip->data_year->mask); in sunxi_rtc_settime()
355 date |= SUNXI_LEAP_SET_VALUE(1, chip->data_year->leap_shift); in sunxi_rtc_settime()
357 time = SUNXI_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) | in sunxi_rtc_settime()
358 SUNXI_TIME_SET_MIN_VALUE(rtc_tm->tm_min) | in sunxi_rtc_settime()
359 SUNXI_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour); in sunxi_rtc_settime()
361 writel(0, chip->base + SUNXI_RTC_HMS); in sunxi_rtc_settime()
362 writel(0, chip->base + SUNXI_RTC_YMD); in sunxi_rtc_settime()
364 writel(time, chip->base + SUNXI_RTC_HMS); in sunxi_rtc_settime()
367 * After writing the RTC HH-MM-SS register, the in sunxi_rtc_settime()
372 if (sunxi_rtc_wait(chip, SUNXI_LOSC_CTRL, in sunxi_rtc_settime()
375 return -1; in sunxi_rtc_settime()
378 writel(date, chip->base + SUNXI_RTC_YMD); in sunxi_rtc_settime()
381 * After writing the RTC YY-MM-DD register, the in sunxi_rtc_settime()
386 if (sunxi_rtc_wait(chip, SUNXI_LOSC_CTRL, in sunxi_rtc_settime()
389 return -1; in sunxi_rtc_settime()
397 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); in sunxi_rtc_alarm_irq_enable() local
400 sunxi_rtc_setaie(enabled, chip); in sunxi_rtc_alarm_irq_enable()
414 { .compatible = "allwinner,sun4i-a10-rtc", .data = &data_year_param[0] },
415 { .compatible = "allwinner,sun7i-a20-rtc", .data = &data_year_param[1] },
422 struct sunxi_rtc_dev *chip; in sunxi_rtc_probe() local
425 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); in sunxi_rtc_probe()
426 if (!chip) in sunxi_rtc_probe()
427 return -ENOMEM; in sunxi_rtc_probe()
429 platform_set_drvdata(pdev, chip); in sunxi_rtc_probe()
430 chip->dev = &pdev->dev; in sunxi_rtc_probe()
432 chip->rtc = devm_rtc_allocate_device(&pdev->dev); in sunxi_rtc_probe()
433 if (IS_ERR(chip->rtc)) in sunxi_rtc_probe()
434 return PTR_ERR(chip->rtc); in sunxi_rtc_probe()
436 chip->base = devm_platform_ioremap_resource(pdev, 0); in sunxi_rtc_probe()
437 if (IS_ERR(chip->base)) in sunxi_rtc_probe()
438 return PTR_ERR(chip->base); in sunxi_rtc_probe()
440 chip->irq = platform_get_irq(pdev, 0); in sunxi_rtc_probe()
441 if (chip->irq < 0) in sunxi_rtc_probe()
442 return chip->irq; in sunxi_rtc_probe()
443 ret = devm_request_irq(&pdev->dev, chip->irq, sunxi_rtc_alarmirq, in sunxi_rtc_probe()
444 0, dev_name(&pdev->dev), chip); in sunxi_rtc_probe()
446 dev_err(&pdev->dev, "Could not request IRQ\n"); in sunxi_rtc_probe()
450 chip->data_year = of_device_get_match_data(&pdev->dev); in sunxi_rtc_probe()
451 if (!chip->data_year) { in sunxi_rtc_probe()
452 dev_err(&pdev->dev, "Unable to setup RTC data\n"); in sunxi_rtc_probe()
453 return -ENODEV; in sunxi_rtc_probe()
457 writel(0, chip->base + SUNXI_ALRM_DHMS); in sunxi_rtc_probe()
460 writel(0, chip->base + SUNXI_ALRM_EN); in sunxi_rtc_probe()
463 writel(0, chip->base + SUNXI_ALRM_IRQ_EN); in sunxi_rtc_probe()
466 writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND, chip->base + in sunxi_rtc_probe()
469 chip->rtc->ops = &sunxi_rtc_ops; in sunxi_rtc_probe()
471 return devm_rtc_register_device(chip->rtc); in sunxi_rtc_probe()
477 .name = "sunxi-rtc",