/* * Read current time and date in RTC
*/ staticint wm8350_rtc_readtime(struct device *dev, struct rtc_time *tm)
{ struct wm8350 *wm8350 = dev_get_drvdata(dev);
u16 time1[4], time2[4]; int retries = WM8350_GET_TIME_RETRIES, ret;
/* * Read the time twice and compare. * If time1 == time2, then time is valid else retry.
*/ do {
ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES,
4, time1); if (ret < 0) return ret;
ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES,
4, time2); if (ret < 0) return ret;
dev_err(dev, "timed out reading RTC time\n"); return -EIO;
}
/* * Set current time and date in RTC
*/ staticint wm8350_rtc_settime(struct device *dev, struct rtc_time *tm)
{ struct wm8350 *wm8350 = dev_get_drvdata(dev);
u16 time[4];
u16 rtc_ctrl; int ret, retries = WM8350_SET_TIME_RETRIES;
/* Make it one shot */
ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL,
WM8350_RTC_ALMSET); if (ret != 0) {
dev_err(&(wm8350->rtc.pdev->dev), "Failed to disable alarm: %d\n", ret);
}
timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); if (timectl & WM8350_RTC_BCD) {
dev_err(&pdev->dev, "RTC BCD mode not supported\n"); return -EINVAL;
} if (timectl & WM8350_RTC_12HR) {
dev_err(&pdev->dev, "RTC 12 hour mode not supported\n"); return -EINVAL;
}
/* enable the RTC if it's not already enabled */
power5 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5); if (!(power5 & WM8350_RTC_TICK_ENA)) {
wm8350_reg_unlock(wm8350);
ret = wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5,
WM8350_RTC_TICK_ENA); if (ret < 0) {
dev_err(&pdev->dev, "failed to enable RTC: %d\n", ret); return ret;
}
wm8350_reg_lock(wm8350);
}
if (timectl & WM8350_RTC_STS) { int retries;
ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL,
WM8350_RTC_SET); if (ret < 0) {
dev_err(&pdev->dev, "failed to start: %d\n", ret); return ret;
}
retries = WM8350_SET_TIME_RETRIES; do {
timectl = wm8350_reg_read(wm8350,
WM8350_RTC_TIME_CONTROL);
} while (timectl & WM8350_RTC_STS && --retries);
if (retries == 0) {
dev_err(&pdev->dev, "failed to start: timeout\n"); return -ENODEV;
}
}
device_init_wakeup(&pdev->dev, true);
wm_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm8350",
&wm8350_rtc_ops, THIS_MODULE); if (IS_ERR(wm_rtc->rtc)) return PTR_ERR(wm_rtc->rtc);
ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC,
wm8350_rtc_update_handler, 0, "RTC Seconds", wm8350); if (ret) return ret;
wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM,
wm8350_rtc_alarm_handler, 0, "RTC Alarm", wm8350); if (ret) {
wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.