rtc: tps6586x: let the core handle rtc range
Let the core handle offsetting and windowing the RTC range. The RTC has a 40-bit counter counting at 1024 Hz. So its maximum value is 2^(40-10) - 1. Also, let the core handle the offset instead of coding it in the callbacks. Keep the default epoch at the beginning of 2009 (this will fail in 2043). Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
parent
63d2206307
commit
180c92c4ae
|
@ -58,7 +58,6 @@ struct tps6586x_rtc {
|
||||||
struct rtc_device *rtc;
|
struct rtc_device *rtc;
|
||||||
int irq;
|
int irq;
|
||||||
bool irq_en;
|
bool irq_en;
|
||||||
time64_t epoch_start;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct device *to_tps6586x_dev(struct device *dev)
|
static inline struct device *to_tps6586x_dev(struct device *dev)
|
||||||
|
@ -68,7 +67,6 @@ static inline struct device *to_tps6586x_dev(struct device *dev)
|
||||||
|
|
||||||
static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||||
{
|
{
|
||||||
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
|
|
||||||
struct device *tps_dev = to_tps6586x_dev(dev);
|
struct device *tps_dev = to_tps6586x_dev(dev);
|
||||||
unsigned long long ticks = 0;
|
unsigned long long ticks = 0;
|
||||||
time64_t seconds;
|
time64_t seconds;
|
||||||
|
@ -88,14 +86,13 @@ static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||||
}
|
}
|
||||||
|
|
||||||
seconds = ticks >> 10;
|
seconds = ticks >> 10;
|
||||||
seconds += rtc->epoch_start;
|
rtc_time64_to_tm(seconds, tm);
|
||||||
rtc_time_to_tm(seconds, tm);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||||
{
|
{
|
||||||
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
|
|
||||||
struct device *tps_dev = to_tps6586x_dev(dev);
|
struct device *tps_dev = to_tps6586x_dev(dev);
|
||||||
unsigned long long ticks;
|
unsigned long long ticks;
|
||||||
time64_t seconds;
|
time64_t seconds;
|
||||||
|
@ -103,11 +100,6 @@ static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
seconds = rtc_tm_to_time64(tm);
|
seconds = rtc_tm_to_time64(tm);
|
||||||
if (seconds < rtc->epoch_start) {
|
|
||||||
dev_err(dev, "requested time unsupported\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
seconds -= rtc->epoch_start;
|
|
||||||
|
|
||||||
ticks = (unsigned long long)seconds << 10;
|
ticks = (unsigned long long)seconds << 10;
|
||||||
buff[0] = (ticks >> 32) & 0xff;
|
buff[0] = (ticks >> 32) & 0xff;
|
||||||
|
@ -155,7 +147,6 @@ static int tps6586x_rtc_alarm_irq_enable(struct device *dev,
|
||||||
|
|
||||||
static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||||
{
|
{
|
||||||
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
|
|
||||||
struct device *tps_dev = to_tps6586x_dev(dev);
|
struct device *tps_dev = to_tps6586x_dev(dev);
|
||||||
time64_t seconds;
|
time64_t seconds;
|
||||||
unsigned long ticks;
|
unsigned long ticks;
|
||||||
|
@ -168,18 +159,12 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||||
|
|
||||||
seconds = rtc_tm_to_time64(&alrm->time);
|
seconds = rtc_tm_to_time64(&alrm->time);
|
||||||
|
|
||||||
if (alrm->enabled && (seconds < rtc->epoch_start)) {
|
|
||||||
dev_err(dev, "can't set alarm to requested time\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = tps6586x_rtc_alarm_irq_enable(dev, alrm->enabled);
|
ret = tps6586x_rtc_alarm_irq_enable(dev, alrm->enabled);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "can't set alarm irq, err %d\n", ret);
|
dev_err(dev, "can't set alarm irq, err %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
seconds -= rtc->epoch_start;
|
|
||||||
ret = tps6586x_reads(tps_dev, RTC_COUNT4_DUMMYREAD,
|
ret = tps6586x_reads(tps_dev, RTC_COUNT4_DUMMYREAD,
|
||||||
sizeof(rbuff), rbuff);
|
sizeof(rbuff), rbuff);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -210,7 +195,6 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||||
|
|
||||||
static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||||
{
|
{
|
||||||
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
|
|
||||||
struct device *tps_dev = to_tps6586x_dev(dev);
|
struct device *tps_dev = to_tps6586x_dev(dev);
|
||||||
unsigned long ticks;
|
unsigned long ticks;
|
||||||
time64_t seconds;
|
time64_t seconds;
|
||||||
|
@ -225,7 +209,6 @@ static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||||
|
|
||||||
ticks = (buff[0] << 16) | (buff[1] << 8) | buff[2];
|
ticks = (buff[0] << 16) | (buff[1] << 8) | buff[2];
|
||||||
seconds = ticks >> 10;
|
seconds = ticks >> 10;
|
||||||
seconds += rtc->epoch_start;
|
|
||||||
|
|
||||||
rtc_time64_to_tm(seconds, &alrm->time);
|
rtc_time64_to_tm(seconds, &alrm->time);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -260,9 +243,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
|
||||||
rtc->dev = &pdev->dev;
|
rtc->dev = &pdev->dev;
|
||||||
rtc->irq = platform_get_irq(pdev, 0);
|
rtc->irq = platform_get_irq(pdev, 0);
|
||||||
|
|
||||||
/* Set epoch start as 00:00:00:01:01:2009 */
|
|
||||||
rtc->epoch_start = mktime64(2009, 1, 1, 0, 0, 0);
|
|
||||||
|
|
||||||
/* 1 kHz tick mode, enable tick counting */
|
/* 1 kHz tick mode, enable tick counting */
|
||||||
ret = tps6586x_update(tps_dev, RTC_CTRL,
|
ret = tps6586x_update(tps_dev, RTC_CTRL,
|
||||||
RTC_ENABLE | OSC_SRC_SEL |
|
RTC_ENABLE | OSC_SRC_SEL |
|
||||||
|
@ -284,6 +264,9 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc->rtc->ops = &tps6586x_rtc_ops;
|
rtc->rtc->ops = &tps6586x_rtc_ops;
|
||||||
|
rtc->rtc->range_max = (1ULL << 30) - 1; /* 30-bit seconds */
|
||||||
|
rtc->rtc->start_secs = mktime64(2009, 1, 1, 0, 0, 0);
|
||||||
|
rtc->rtc->set_start_time = true;
|
||||||
|
|
||||||
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
|
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
|
||||||
tps6586x_rtc_irq,
|
tps6586x_rtc_irq,
|
||||||
|
|
Loading…
Reference in a new issue