1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * RTC driver for tps6594 PMIC |
4 | * |
5 | * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/ |
6 | */ |
7 | |
8 | #include <linux/bcd.h> |
9 | #include <linux/errno.h> |
10 | #include <linux/init.h> |
11 | #include <linux/interrupt.h> |
12 | #include <linux/kernel.h> |
13 | #include <linux/limits.h> |
14 | #include <linux/math64.h> |
15 | #include <linux/module.h> |
16 | #include <linux/platform_device.h> |
17 | #include <linux/mod_devicetable.h> |
18 | #include <linux/property.h> |
19 | #include <linux/rtc.h> |
20 | #include <linux/types.h> |
21 | #include <linux/units.h> |
22 | |
23 | #include <linux/mfd/tps6594.h> |
24 | |
25 | // Total number of RTC registers needed to set time |
26 | #define NUM_TIME_REGS (TPS6594_REG_RTC_WEEKS - TPS6594_REG_RTC_SECONDS + 1) |
27 | |
28 | // Total number of RTC alarm registers |
29 | #define NUM_TIME_ALARM_REGS (NUM_TIME_REGS - 1) |
30 | |
31 | /* |
32 | * Min and max values supported by 'offset' interface (swapped sign). |
33 | * After conversion, the values do not exceed the range [-32767, 33767] |
34 | * which COMP_REG must conform to. |
35 | */ |
36 | #define MIN_OFFSET (-277774) |
37 | #define MAX_OFFSET (277774) |
38 | |
39 | // Number of ticks per hour |
40 | #define TICKS_PER_HOUR (32768 * 3600) |
41 | |
42 | // Multiplier for ppb conversions |
43 | #define PPB_MULT NANO |
44 | |
45 | static int tps6594_rtc_alarm_irq_enable(struct device *dev, |
46 | unsigned int enabled) |
47 | { |
48 | struct tps6594 *tps = dev_get_drvdata(dev: dev->parent); |
49 | u8 val; |
50 | |
51 | val = enabled ? TPS6594_BIT_IT_ALARM : 0; |
52 | |
53 | return regmap_update_bits(map: tps->regmap, TPS6594_REG_RTC_INTERRUPTS, |
54 | TPS6594_BIT_IT_ALARM, val); |
55 | } |
56 | |
57 | /* Pulse GET_TIME field of RTC_CTRL_1 to store a timestamp in shadow registers. */ |
58 | static int tps6594_rtc_shadow_timestamp(struct device *dev, struct tps6594 *tps) |
59 | { |
60 | int ret; |
61 | |
62 | /* |
63 | * Set GET_TIME to 0. Next time we set GET_TIME to 1 we will be sure to store |
64 | * an up-to-date timestamp. |
65 | */ |
66 | ret = regmap_clear_bits(map: tps->regmap, TPS6594_REG_RTC_CTRL_1, |
67 | TPS6594_BIT_GET_TIME); |
68 | if (ret < 0) |
69 | return ret; |
70 | |
71 | /* |
72 | * Copy content of RTC registers to shadow registers or latches to read |
73 | * a coherent timestamp. |
74 | */ |
75 | return regmap_set_bits(map: tps->regmap, TPS6594_REG_RTC_CTRL_1, |
76 | TPS6594_BIT_GET_TIME); |
77 | } |
78 | |
79 | static int tps6594_rtc_read_time(struct device *dev, struct rtc_time *tm) |
80 | { |
81 | unsigned char rtc_data[NUM_TIME_REGS]; |
82 | struct tps6594 *tps = dev_get_drvdata(dev: dev->parent); |
83 | int ret; |
84 | |
85 | // Check if RTC is running. |
86 | ret = regmap_test_bits(map: tps->regmap, TPS6594_REG_RTC_STATUS, |
87 | TPS6594_BIT_RUN); |
88 | if (ret < 0) |
89 | return ret; |
90 | if (ret == 0) |
91 | return -EINVAL; |
92 | |
93 | ret = tps6594_rtc_shadow_timestamp(dev, tps); |
94 | if (ret < 0) |
95 | return ret; |
96 | |
97 | // Read shadowed RTC registers. |
98 | ret = regmap_bulk_read(map: tps->regmap, TPS6594_REG_RTC_SECONDS, val: rtc_data, |
99 | NUM_TIME_REGS); |
100 | if (ret < 0) |
101 | return ret; |
102 | |
103 | tm->tm_sec = bcd2bin(rtc_data[0]); |
104 | tm->tm_min = bcd2bin(rtc_data[1]); |
105 | tm->tm_hour = bcd2bin(rtc_data[2]); |
106 | tm->tm_mday = bcd2bin(rtc_data[3]); |
107 | tm->tm_mon = bcd2bin(rtc_data[4]) - 1; |
108 | tm->tm_year = bcd2bin(rtc_data[5]) + 100; |
109 | tm->tm_wday = bcd2bin(rtc_data[6]); |
110 | |
111 | return 0; |
112 | } |
113 | |
114 | static int tps6594_rtc_set_time(struct device *dev, struct rtc_time *tm) |
115 | { |
116 | unsigned char rtc_data[NUM_TIME_REGS]; |
117 | struct tps6594 *tps = dev_get_drvdata(dev: dev->parent); |
118 | int ret; |
119 | |
120 | rtc_data[0] = bin2bcd(tm->tm_sec); |
121 | rtc_data[1] = bin2bcd(tm->tm_min); |
122 | rtc_data[2] = bin2bcd(tm->tm_hour); |
123 | rtc_data[3] = bin2bcd(tm->tm_mday); |
124 | rtc_data[4] = bin2bcd(tm->tm_mon + 1); |
125 | rtc_data[5] = bin2bcd(tm->tm_year - 100); |
126 | rtc_data[6] = bin2bcd(tm->tm_wday); |
127 | |
128 | // Stop RTC while updating the RTC time registers. |
129 | ret = regmap_clear_bits(map: tps->regmap, TPS6594_REG_RTC_CTRL_1, |
130 | TPS6594_BIT_STOP_RTC); |
131 | if (ret < 0) |
132 | return ret; |
133 | |
134 | // Update all the time registers in one shot. |
135 | ret = regmap_bulk_write(map: tps->regmap, TPS6594_REG_RTC_SECONDS, val: rtc_data, |
136 | NUM_TIME_REGS); |
137 | if (ret < 0) |
138 | return ret; |
139 | |
140 | // Start back RTC. |
141 | return regmap_set_bits(map: tps->regmap, TPS6594_REG_RTC_CTRL_1, |
142 | TPS6594_BIT_STOP_RTC); |
143 | } |
144 | |
145 | static int tps6594_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) |
146 | { |
147 | unsigned char alarm_data[NUM_TIME_ALARM_REGS]; |
148 | u32 int_val; |
149 | struct tps6594 *tps = dev_get_drvdata(dev: dev->parent); |
150 | int ret; |
151 | |
152 | ret = regmap_bulk_read(map: tps->regmap, TPS6594_REG_ALARM_SECONDS, |
153 | val: alarm_data, NUM_TIME_ALARM_REGS); |
154 | if (ret < 0) |
155 | return ret; |
156 | |
157 | alm->time.tm_sec = bcd2bin(alarm_data[0]); |
158 | alm->time.tm_min = bcd2bin(alarm_data[1]); |
159 | alm->time.tm_hour = bcd2bin(alarm_data[2]); |
160 | alm->time.tm_mday = bcd2bin(alarm_data[3]); |
161 | alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1; |
162 | alm->time.tm_year = bcd2bin(alarm_data[5]) + 100; |
163 | |
164 | ret = regmap_read(map: tps->regmap, TPS6594_REG_RTC_INTERRUPTS, val: &int_val); |
165 | if (ret < 0) |
166 | return ret; |
167 | |
168 | alm->enabled = int_val & TPS6594_BIT_IT_ALARM; |
169 | |
170 | return 0; |
171 | } |
172 | |
173 | static int tps6594_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) |
174 | { |
175 | unsigned char alarm_data[NUM_TIME_ALARM_REGS]; |
176 | struct tps6594 *tps = dev_get_drvdata(dev: dev->parent); |
177 | int ret; |
178 | |
179 | // Disable alarm irq before changing the alarm timestamp. |
180 | ret = tps6594_rtc_alarm_irq_enable(dev, enabled: 0); |
181 | if (ret) |
182 | return ret; |
183 | |
184 | alarm_data[0] = bin2bcd(alm->time.tm_sec); |
185 | alarm_data[1] = bin2bcd(alm->time.tm_min); |
186 | alarm_data[2] = bin2bcd(alm->time.tm_hour); |
187 | alarm_data[3] = bin2bcd(alm->time.tm_mday); |
188 | alarm_data[4] = bin2bcd(alm->time.tm_mon + 1); |
189 | alarm_data[5] = bin2bcd(alm->time.tm_year - 100); |
190 | |
191 | // Update all the alarm registers in one shot. |
192 | ret = regmap_bulk_write(map: tps->regmap, TPS6594_REG_ALARM_SECONDS, |
193 | val: alarm_data, NUM_TIME_ALARM_REGS); |
194 | if (ret < 0) |
195 | return ret; |
196 | |
197 | if (alm->enabled) |
198 | ret = tps6594_rtc_alarm_irq_enable(dev, enabled: 1); |
199 | |
200 | return ret; |
201 | } |
202 | |
203 | static int tps6594_rtc_set_calibration(struct device *dev, int calibration) |
204 | { |
205 | struct tps6594 *tps = dev_get_drvdata(dev: dev->parent); |
206 | __le16 value; |
207 | int ret; |
208 | |
209 | /* |
210 | * TPS6594 uses two's complement 16 bit value for compensation of RTC |
211 | * crystal inaccuracies. One time every hour when seconds counter |
212 | * increments from 0 to 1 compensation value will be added to internal |
213 | * RTC counter value. |
214 | * |
215 | * Valid range for compensation value: [-32767 .. 32767]. |
216 | */ |
217 | if (calibration < S16_MIN + 1 || calibration > S16_MAX) |
218 | return -ERANGE; |
219 | |
220 | value = cpu_to_le16(calibration); |
221 | |
222 | // Update all the compensation registers in one shot. |
223 | ret = regmap_bulk_write(map: tps->regmap, TPS6594_REG_RTC_COMP_LSB, val: &value, |
224 | val_count: sizeof(value)); |
225 | if (ret < 0) |
226 | return ret; |
227 | |
228 | // Enable automatic compensation. |
229 | return regmap_set_bits(map: tps->regmap, TPS6594_REG_RTC_CTRL_1, |
230 | TPS6594_BIT_AUTO_COMP); |
231 | } |
232 | |
233 | static int tps6594_rtc_get_calibration(struct device *dev, int *calibration) |
234 | { |
235 | struct tps6594 *tps = dev_get_drvdata(dev: dev->parent); |
236 | unsigned int ctrl; |
237 | __le16 value; |
238 | int ret; |
239 | |
240 | ret = regmap_read(map: tps->regmap, TPS6594_REG_RTC_CTRL_1, val: &ctrl); |
241 | if (ret < 0) |
242 | return ret; |
243 | |
244 | // If automatic compensation is not enabled report back zero. |
245 | if (!(ctrl & TPS6594_BIT_AUTO_COMP)) { |
246 | *calibration = 0; |
247 | return 0; |
248 | } |
249 | |
250 | ret = regmap_bulk_read(map: tps->regmap, TPS6594_REG_RTC_COMP_LSB, val: &value, |
251 | val_count: sizeof(value)); |
252 | if (ret < 0) |
253 | return ret; |
254 | |
255 | *calibration = le16_to_cpu(value); |
256 | |
257 | return 0; |
258 | } |
259 | |
260 | static int tps6594_rtc_read_offset(struct device *dev, long *offset) |
261 | { |
262 | int calibration; |
263 | s64 tmp; |
264 | int ret; |
265 | |
266 | ret = tps6594_rtc_get_calibration(dev, calibration: &calibration); |
267 | if (ret < 0) |
268 | return ret; |
269 | |
270 | // Convert from RTC calibration register format to ppb format. |
271 | tmp = calibration * PPB_MULT; |
272 | |
273 | if (tmp < 0) |
274 | tmp -= TICKS_PER_HOUR / 2LL; |
275 | else |
276 | tmp += TICKS_PER_HOUR / 2LL; |
277 | tmp = div_s64(dividend: tmp, TICKS_PER_HOUR); |
278 | |
279 | /* |
280 | * SAFETY: |
281 | * Computatiion is the reverse operation of the one done in |
282 | * `tps6594_rtc_set_offset`. The safety remarks applie here too. |
283 | */ |
284 | |
285 | /* |
286 | * Offset value operates in negative way, so swap sign. |
287 | * See 8.3.10.5, (32768 - COMP_REG). |
288 | */ |
289 | *offset = (long)-tmp; |
290 | |
291 | return 0; |
292 | } |
293 | |
294 | static int tps6594_rtc_set_offset(struct device *dev, long offset) |
295 | { |
296 | int calibration; |
297 | s64 tmp; |
298 | |
299 | // Make sure offset value is within supported range. |
300 | if (offset < MIN_OFFSET || offset > MAX_OFFSET) |
301 | return -ERANGE; |
302 | |
303 | // Convert from ppb format to RTC calibration register format. |
304 | |
305 | tmp = offset * TICKS_PER_HOUR; |
306 | if (tmp < 0) |
307 | tmp -= PPB_MULT / 2LL; |
308 | else |
309 | tmp += PPB_MULT / 2LL; |
310 | tmp = div_s64(dividend: tmp, PPB_MULT); |
311 | |
312 | /* |
313 | * SAFETY: |
314 | * - tmp = offset * TICK_PER_HOUR : |
315 | * `offset` can't be more than 277774, so `tmp` can't exceed 277774000000000 |
316 | * which is lower than the maximum value in an `s64` (2^63-1). No overflow here. |
317 | * |
318 | * - tmp += TICK_PER_HOUR / 2LL : |
319 | * tmp will have a maximum value of 277774117964800 which is still inferior to 2^63-1. |
320 | */ |
321 | |
322 | // Offset value operates in negative way, so swap sign. |
323 | calibration = (int)-tmp; |
324 | |
325 | return tps6594_rtc_set_calibration(dev, calibration); |
326 | } |
327 | |
328 | static irqreturn_t tps6594_rtc_interrupt(int irq, void *rtc) |
329 | { |
330 | struct device *dev = rtc; |
331 | struct tps6594 *tps = dev_get_drvdata(dev: dev->parent); |
332 | struct rtc_device *rtc_dev = dev_get_drvdata(dev); |
333 | int ret; |
334 | u32 rtc_reg; |
335 | |
336 | ret = regmap_read(map: tps->regmap, TPS6594_REG_RTC_STATUS, val: &rtc_reg); |
337 | if (ret) |
338 | return IRQ_NONE; |
339 | |
340 | rtc_update_irq(rtc: rtc_dev, num: 1, RTC_IRQF | RTC_AF); |
341 | |
342 | return IRQ_HANDLED; |
343 | } |
344 | |
345 | static const struct rtc_class_ops tps6594_rtc_ops = { |
346 | .read_time = tps6594_rtc_read_time, |
347 | .set_time = tps6594_rtc_set_time, |
348 | .read_alarm = tps6594_rtc_read_alarm, |
349 | .set_alarm = tps6594_rtc_set_alarm, |
350 | .alarm_irq_enable = tps6594_rtc_alarm_irq_enable, |
351 | .read_offset = tps6594_rtc_read_offset, |
352 | .set_offset = tps6594_rtc_set_offset, |
353 | }; |
354 | |
355 | static int tps6594_rtc_probe(struct platform_device *pdev) |
356 | { |
357 | struct tps6594 *tps = dev_get_drvdata(dev: pdev->dev.parent); |
358 | struct device *dev = &pdev->dev; |
359 | struct rtc_device *rtc; |
360 | int irq; |
361 | int ret; |
362 | |
363 | rtc = devm_kzalloc(dev, size: sizeof(*rtc), GFP_KERNEL); |
364 | if (!rtc) |
365 | return -ENOMEM; |
366 | |
367 | rtc = devm_rtc_allocate_device(dev); |
368 | if (IS_ERR(ptr: rtc)) |
369 | return PTR_ERR(ptr: rtc); |
370 | |
371 | // Enable crystal oscillator. |
372 | ret = regmap_set_bits(map: tps->regmap, TPS6594_REG_RTC_CTRL_2, |
373 | TPS6594_BIT_XTAL_EN); |
374 | if (ret < 0) |
375 | return ret; |
376 | |
377 | ret = regmap_test_bits(map: tps->regmap, TPS6594_REG_RTC_STATUS, |
378 | TPS6594_BIT_RUN); |
379 | if (ret < 0) |
380 | return ret; |
381 | // RTC not running. |
382 | if (ret == 0) { |
383 | ret = regmap_set_bits(map: tps->regmap, TPS6594_REG_RTC_CTRL_1, |
384 | TPS6594_BIT_STOP_RTC); |
385 | if (ret < 0) |
386 | return ret; |
387 | |
388 | /* |
389 | * On some boards, a 40 ms delay is needed before BIT_RUN is set. |
390 | * 80 ms should provide sufficient margin. |
391 | */ |
392 | mdelay(80); |
393 | |
394 | /* |
395 | * RTC should be running now. Check if this is the case. |
396 | * If not it might be a missing oscillator. |
397 | */ |
398 | ret = regmap_test_bits(map: tps->regmap, TPS6594_REG_RTC_STATUS, |
399 | TPS6594_BIT_RUN); |
400 | if (ret < 0) |
401 | return ret; |
402 | if (ret == 0) |
403 | return -ENODEV; |
404 | |
405 | // Stop RTC until first call to `tps6594_rtc_set_time`. |
406 | ret = regmap_clear_bits(map: tps->regmap, TPS6594_REG_RTC_CTRL_1, |
407 | TPS6594_BIT_STOP_RTC); |
408 | if (ret < 0) |
409 | return ret; |
410 | } |
411 | |
412 | platform_set_drvdata(pdev, data: rtc); |
413 | |
414 | irq = platform_get_irq_byname(pdev, TPS6594_IRQ_NAME_ALARM); |
415 | if (irq < 0) |
416 | return dev_err_probe(dev, err: irq, fmt: "Failed to get irq\n" ); |
417 | |
418 | ret = devm_request_threaded_irq(dev, irq, NULL, thread_fn: tps6594_rtc_interrupt, |
419 | IRQF_ONESHOT, TPS6594_IRQ_NAME_ALARM, |
420 | dev_id: dev); |
421 | if (ret < 0) |
422 | return dev_err_probe(dev, err: ret, |
423 | fmt: "Failed to request_threaded_irq\n" ); |
424 | |
425 | ret = device_init_wakeup(dev, enable: true); |
426 | if (ret < 0) |
427 | return dev_err_probe(dev, err: ret, |
428 | fmt: "Failed to init rtc as wakeup source\n" ); |
429 | |
430 | rtc->ops = &tps6594_rtc_ops; |
431 | rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; |
432 | rtc->range_max = RTC_TIMESTAMP_END_2099; |
433 | |
434 | return devm_rtc_register_device(rtc); |
435 | } |
436 | |
437 | static const struct platform_device_id tps6594_rtc_id_table[] = { |
438 | { "tps6594-rtc" , }, |
439 | {} |
440 | }; |
441 | MODULE_DEVICE_TABLE(platform, tps6594_rtc_id_table); |
442 | |
443 | static struct platform_driver tps6594_rtc_driver = { |
444 | .probe = tps6594_rtc_probe, |
445 | .driver = { |
446 | .name = "tps6594-rtc" , |
447 | }, |
448 | .id_table = tps6594_rtc_id_table, |
449 | }; |
450 | |
451 | module_platform_driver(tps6594_rtc_driver); |
452 | MODULE_AUTHOR("Esteban Blanc <eblanc@baylibre.com>" ); |
453 | MODULE_DESCRIPTION("TPS6594 RTC driver" ); |
454 | MODULE_LICENSE("GPL" ); |
455 | |