/* RK808 has a shadowed register for saving a "frozen" RTC time. * When user setting "GET_TIME" to 1, the time will save in this shadowed * register. If set "READSEL" to 1, user read rtc time register, actually * get the time of that moment. If we need the real time, clr this bit.
*/ #define BIT_RTC_CTRL_REG_RTC_GET_TIME BIT(6) #define BIT_RTC_CTRL_REG_RTC_READSEL_M BIT(7) #define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M BIT(3) #define RTC_STATUS_MASK 0xFE
/* * The Rockchip calendar used by the RK808 counts November with 31 days. We use * these translation functions to convert its dates to/from the Gregorian * calendar used by the rest of the world. We arbitrarily define Jan 1st, 2016 * as the day when both calendars were in sync, and treat all other dates * relative to that. * NOTE: Other system software (e.g. firmware) that reads the same hardware must * implement this exact same conversion algorithm, with the same anchor date.
*/ static time64_t nov2dec_transitions(struct rtc_time *tm)
{ return (tm->tm_year + 1900) - 2016 + (tm->tm_mon + 1 > 11 ? 1 : 0);
}
staticvoid rockchip_to_gregorian(struct rtc_time *tm)
{ /* If it's Nov 31st, rtc_tm_to_time64() will count that like Dec 1st */
time64_t time = rtc_tm_to_time64(tm);
rtc_time64_to_tm(time + nov2dec_transitions(tm) * 86400, tm);
}
/* Compensate if we went back over Nov 31st (will work up to 2381) */ if (nov2dec_transitions(tm) < extra_days) { if (tm->tm_mon + 1 == 11)
tm->tm_mday++; /* This may result in 31! */ else
rtc_time64_to_tm(time - (extra_days - 1) * 86400, tm);
}
}
/* Read current time and date in RTC */ staticint rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
{ struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
u8 rtc_data[NUM_TIME_REGS]; int ret;
/* Force an update of the shadowed registers right now */
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_RTC_GET_TIME,
BIT_RTC_CTRL_REG_RTC_GET_TIME); if (ret) {
dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret); return ret;
}
/* * After we set the GET_TIME bit, the rtc time can't be read * immediately. So we should wait up to 31.25 us, about one cycle of * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
*/
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_RTC_GET_TIME,
0); if (ret) {
dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret); return ret;
}
ret = regmap_bulk_read(rk808_rtc->regmap, rk808_rtc->creg->seconds_reg,
rtc_data, NUM_TIME_REGS); if (ret) {
dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret); return ret;
}
/* Set current time and date in RTC */ staticint rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
u8 rtc_data[NUM_TIME_REGS]; int ret;
ret = regmap_read(rk808_rtc->regmap, rk808_rtc->creg->int_reg, &int_reg); if (ret) {
dev_err(dev, "Failed to read RTC INT REG: %d\n", ret); return ret;
}
if (enabled) return rk808_rtc_start_alarm(rk808_rtc);
return rk808_rtc_stop_alarm(rk808_rtc);
}
/* * We will just handle setting the frequency and make use the framework for * reading the periodic interupts. * * @freq: Current periodic IRQ freq: * bit 0: every second * bit 1: every minute * bit 2: every hour * bit 3: every day
*/ static irqreturn_t rk808_alarm_irq(int irq, void *data)
{ struct rk808_rtc *rk808_rtc = data; int ret;
ret = regmap_write(rk808_rtc->regmap, rk808_rtc->creg->status_reg,
RTC_STATUS_MASK); if (ret) {
dev_err(&rk808_rtc->rtc->dev, "%s:Failed to update RTC status: %d\n", __func__, ret); return ret;
}
#ifdef CONFIG_PM_SLEEP /* Turn off the alarm if it should not be a wake source. */ staticint rk808_rtc_suspend(struct device *dev)
{ struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
enable_irq_wake(rk808_rtc->irq);
return 0;
}
/* Enable the alarm if it should be enabled (in case it was disabled to * prevent use as a wake source).
*/ staticint rk808_rtc_resume(struct device *dev)
{ struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
disable_irq_wake(rk808_rtc->irq);
MODULE_DESCRIPTION("RTC driver for the rk808 series PMICs");
MODULE_AUTHOR("Chris Zhong ");
MODULE_AUTHOR("Zhang Qing ");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:rk808-rtc");
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.