/* * The RTC was not started or is stopped and thus does not carry the * proper time/date.
*/
val = readl(rtc->base + RZN1_RTC_CTL2); if (val & RZN1_RTC_CTL2_STOPPED) return -EINVAL;
val = readl(rtc->base + RZN1_RTC_CTL2); if (!(val & RZN1_RTC_CTL2_STOPPED)) { /* Hold the counter if it was counting up */
writel(RZN1_RTC_CTL2_WAIT, rtc->base + RZN1_RTC_CTL2);
/* Wait for the counter to stop: two 32k clock cycles */
usleep_range(61, 100);
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, val,
val & RZN1_RTC_CTL2_WST, 0, 100); if (ret) return ret;
}
val = bin2bcd(tm->tm_sec);
val |= bin2bcd(tm->tm_min) << RZN1_RTC_TIME_MIN_SHIFT;
val |= bin2bcd(tm->tm_hour) << RZN1_RTC_TIME_HOUR_SHIFT;
writel(val, rtc->base + RZN1_RTC_TIME);
val = tm->tm_wday;
val |= bin2bcd(tm->tm_mday) << RZN1_RTC_CAL_DAY_SHIFT;
val |= bin2bcd(tm->tm_mon + 1) << RZN1_RTC_CAL_MON_SHIFT;
val |= bin2bcd(tm->tm_year - 100) << RZN1_RTC_CAL_YEAR_SHIFT;
writel(val, rtc->base + RZN1_RTC_CAL);
if (enable) { /* * Use alarm interrupt if alarm time is at least a minute away * or less than a minute but in the next minute. Otherwise use * 1 second interrupt to wait for the proper second
*/ do {
ctl1 &= ~(RZN1_RTC_CTL1_ALME | RZN1_RTC_CTL1_1SE);
ret = rzn1_rtc_read_time(dev, &tm_now); if (ret) return ret;
ret = rzn1_rtc_read_time(dev, &tm_now); if (ret) return ret;
/* We cannot set alarms more than one week ahead */
farest = rtc_tm_to_time64(&tm_now) + rtc->rtcdev->alarm_offset_max;
alarm = rtc_tm_to_time64(tm); if (time_after(alarm, farest)) return -ERANGE;
/* Convert alarm day into week day */
days_ahead = tm->tm_mday - tm_now.tm_mday;
wday = (tm_now.tm_wday + days_ahead) % 7;
staticint rzn1_rtc_set_offset(struct device *dev, long offset)
{ struct rzn1_rtc *rtc = dev_get_drvdata(dev); int stepsh, stepsl, steps;
u32 subu = 0, ctl2; int ret;
/* * Check which resolution mode (every 20 or 60s) can be used. * Between 2 and 124 clock pulses can be added or substracted. * * In 20s mode, the minimum resolution is 2 / (32768 * 20) which is * close to 3051 ppb. In 60s mode, the resolution is closer to 1017.
*/
stepsh = DIV_ROUND_CLOSEST(offset, 1017);
stepsl = DIV_ROUND_CLOSEST(offset, 3051);
ret = devm_pm_runtime_enable(&pdev->dev); if (ret < 0) return ret;
ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) return ret;
/* Only switch to scmp if we have an xtal clock with a valid rate and != 32768 */
xtal = devm_clk_get_optional(&pdev->dev, "xtal"); if (IS_ERR(xtal)) {
ret = PTR_ERR(xtal); goto dis_runtime_pm;
} elseif (xtal) {
rate = clk_get_rate(xtal);
if (rate < 32000 || rate > BIT(22)) {
ret = -EOPNOTSUPP; goto dis_runtime_pm;
}
if (rate != 32768)
scmp_val = RZN1_RTC_CTL0_SLSB_SCMP;
}
/* Disable controller during SUBU/SCMP setup */
val = readl(rtc->base + RZN1_RTC_CTL0) & ~RZN1_RTC_CTL0_CE;
writel(val, rtc->base + RZN1_RTC_CTL0); /* Wait 2-4 32k clock cycles for the disabled controller */
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL0, val,
!(val & RZN1_RTC_CTL0_CEST), 62, 123); if (ret) goto dis_runtime_pm;
/* Set desired modes leaving the controller disabled */
writel(RZN1_RTC_CTL0_AMPM | scmp_val, rtc->base + RZN1_RTC_CTL0);
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.