diff options
author | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-09-24 10:49:01 -0400 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-09-28 08:36:47 -0400 |
commit | 38ab97aebe47831e576095e58dac31860152b0fa (patch) | |
tree | 9a44dd1f86636a890e13b346dd3dfa93271b6a09 | |
parent | b56295dd337a35402663b230ac62260cbe7ee5ac (diff) |
rtc: ab8500: let the core handle range
Let the core handle offsetting and windowing the RTC range.
The RTC has a 24 bit counter for minutes plus a seconds counter.
Keep the epoch at the beginning of 2000.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
-rw-r--r-- | drivers/rtc/rtc-ab8500.c | 53 |
1 files changed, 4 insertions, 49 deletions
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index e97015e5c63e..2e2671b84ab0 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #define RTC_STATUS_DATA 0x01 | 46 | #define RTC_STATUS_DATA 0x01 |
47 | 47 | ||
48 | #define COUNTS_PER_SEC (0xF000 / 60) | 48 | #define COUNTS_PER_SEC (0xF000 / 60) |
49 | #define AB8500_RTC_EPOCH 2000 | ||
50 | 49 | ||
51 | static const u8 ab8500_rtc_time_regs[] = { | 50 | static const u8 ab8500_rtc_time_regs[] = { |
52 | AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG, | 51 | AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG, |
@@ -59,23 +58,6 @@ static const u8 ab8500_rtc_alarm_regs[] = { | |||
59 | AB8500_RTC_ALRM_MIN_LOW_REG | 58 | AB8500_RTC_ALRM_MIN_LOW_REG |
60 | }; | 59 | }; |
61 | 60 | ||
62 | /* Calculate the seconds from 1970 to 01-01-2000 00:00:00 */ | ||
63 | static unsigned long get_elapsed_seconds(int year) | ||
64 | { | ||
65 | unsigned long secs; | ||
66 | struct rtc_time tm = { | ||
67 | .tm_year = year - 1900, | ||
68 | .tm_mday = 1, | ||
69 | }; | ||
70 | |||
71 | /* | ||
72 | * This function calculates secs from 1970 and not from | ||
73 | * 1900, even if we supply the offset from year 1900. | ||
74 | */ | ||
75 | rtc_tm_to_time(&tm, &secs); | ||
76 | return secs; | ||
77 | } | ||
78 | |||
79 | static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | 61 | static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) |
80 | { | 62 | { |
81 | unsigned long timeout = jiffies + HZ; | 63 | unsigned long timeout = jiffies + HZ; |
@@ -118,9 +100,6 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
118 | secs = secs / COUNTS_PER_SEC; | 100 | secs = secs / COUNTS_PER_SEC; |
119 | secs = secs + (mins * 60); | 101 | secs = secs + (mins * 60); |
120 | 102 | ||
121 | /* Add back the initially subtracted number of seconds */ | ||
122 | secs += get_elapsed_seconds(AB8500_RTC_EPOCH); | ||
123 | |||
124 | rtc_time_to_tm(secs, tm); | 103 | rtc_time_to_tm(secs, tm); |
125 | return 0; | 104 | return 0; |
126 | } | 105 | } |
@@ -131,21 +110,8 @@ static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
131 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; | 110 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; |
132 | unsigned long no_secs, no_mins, secs = 0; | 111 | unsigned long no_secs, no_mins, secs = 0; |
133 | 112 | ||
134 | if (tm->tm_year < (AB8500_RTC_EPOCH - 1900)) { | ||
135 | dev_dbg(dev, "year should be equal to or greater than %d\n", | ||
136 | AB8500_RTC_EPOCH); | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | |||
140 | /* Get the number of seconds since 1970 */ | ||
141 | rtc_tm_to_time(tm, &secs); | 113 | rtc_tm_to_time(tm, &secs); |
142 | 114 | ||
143 | /* | ||
144 | * Convert it to the number of seconds since 01-01-2000 00:00:00, since | ||
145 | * we only have a small counter in the RTC. | ||
146 | */ | ||
147 | secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); | ||
148 | |||
149 | no_mins = secs / 60; | 115 | no_mins = secs / 60; |
150 | 116 | ||
151 | no_secs = secs % 60; | 117 | no_secs = secs % 60; |
@@ -202,9 +168,6 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
202 | mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]); | 168 | mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]); |
203 | secs = mins * 60; | 169 | secs = mins * 60; |
204 | 170 | ||
205 | /* Add back the initially subtracted number of seconds */ | ||
206 | secs += get_elapsed_seconds(AB8500_RTC_EPOCH); | ||
207 | |||
208 | rtc_time_to_tm(secs, &alarm->time); | 171 | rtc_time_to_tm(secs, &alarm->time); |
209 | 172 | ||
210 | return rtc_valid_tm(&alarm->time); | 173 | return rtc_valid_tm(&alarm->time); |
@@ -224,12 +187,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
224 | unsigned long mins, secs = 0, cursec = 0; | 187 | unsigned long mins, secs = 0, cursec = 0; |
225 | struct rtc_time curtm; | 188 | struct rtc_time curtm; |
226 | 189 | ||
227 | if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) { | ||
228 | dev_dbg(dev, "year should be equal to or greater than %d\n", | ||
229 | AB8500_RTC_EPOCH); | ||
230 | return -EINVAL; | ||
231 | } | ||
232 | |||
233 | /* Get the number of seconds since 1970 */ | 190 | /* Get the number of seconds since 1970 */ |
234 | rtc_tm_to_time(&alarm->time, &secs); | 191 | rtc_tm_to_time(&alarm->time, &secs); |
235 | 192 | ||
@@ -245,12 +202,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
245 | return -EINVAL; | 202 | return -EINVAL; |
246 | } | 203 | } |
247 | 204 | ||
248 | /* | ||
249 | * Convert it to the number of seconds since 01-01-2000 00:00:00, since | ||
250 | * we only have a small counter in the RTC. | ||
251 | */ | ||
252 | secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); | ||
253 | |||
254 | mins = secs / 60; | 205 | mins = secs / 60; |
255 | 206 | ||
256 | buf[2] = mins & 0xFF; | 207 | buf[2] = mins & 0xFF; |
@@ -445,6 +396,10 @@ static int ab8500_rtc_probe(struct platform_device *pdev) | |||
445 | 396 | ||
446 | rtc->uie_unsupported = 1; | 397 | rtc->uie_unsupported = 1; |
447 | 398 | ||
399 | rtc->range_max = (1ULL << 24) * 60 - 1; // 24-bit minutes + 59 secs | ||
400 | rtc->start_secs = RTC_TIMESTAMP_BEGIN_2000; | ||
401 | rtc->set_start_time = true; | ||
402 | |||
448 | err = rtc_add_group(rtc, &ab8500_rtc_sysfs_files); | 403 | err = rtc_add_group(rtc, &ab8500_rtc_sysfs_files); |
449 | if (err) | 404 | if (err) |
450 | return err; | 405 | return err; |