1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | // |
3 | // RTC driver for Maxim MAX8997 |
4 | // |
5 | // Copyright (C) 2013 Samsung Electronics Co.Ltd |
6 | // |
7 | // based on rtc-max8998.c |
8 | |
9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
10 | |
11 | #include <linux/slab.h> |
12 | #include <linux/rtc.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/mutex.h> |
15 | #include <linux/module.h> |
16 | #include <linux/platform_device.h> |
17 | #include <linux/mfd/max8997-private.h> |
18 | #include <linux/irqdomain.h> |
19 | |
20 | /* Module parameter for WTSR function control */ |
21 | static int wtsr_en = 1; |
22 | module_param(wtsr_en, int, 0444); |
23 | MODULE_PARM_DESC(wtsr_en, "Watchdog Timeout & Software Reset (default=on)" ); |
24 | /* Module parameter for SMPL function control */ |
25 | static int smpl_en = 1; |
26 | module_param(smpl_en, int, 0444); |
27 | MODULE_PARM_DESC(smpl_en, "Sudden Momentary Power Loss (default=on)" ); |
28 | |
29 | /* RTC Control Register */ |
30 | #define BCD_EN_SHIFT 0 |
31 | #define BCD_EN_MASK (1 << BCD_EN_SHIFT) |
32 | #define MODEL24_SHIFT 1 |
33 | #define MODEL24_MASK (1 << MODEL24_SHIFT) |
34 | /* RTC Update Register1 */ |
35 | #define RTC_UDR_SHIFT 0 |
36 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) |
37 | /* WTSR and SMPL Register */ |
38 | #define WTSRT_SHIFT 0 |
39 | #define SMPLT_SHIFT 2 |
40 | #define WTSR_EN_SHIFT 6 |
41 | #define SMPL_EN_SHIFT 7 |
42 | #define WTSRT_MASK (3 << WTSRT_SHIFT) |
43 | #define SMPLT_MASK (3 << SMPLT_SHIFT) |
44 | #define WTSR_EN_MASK (1 << WTSR_EN_SHIFT) |
45 | #define SMPL_EN_MASK (1 << SMPL_EN_SHIFT) |
46 | /* RTC Hour register */ |
47 | #define HOUR_PM_SHIFT 6 |
48 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) |
49 | /* RTC Alarm Enable */ |
50 | #define ALARM_ENABLE_SHIFT 7 |
51 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) |
52 | |
53 | enum { |
54 | RTC_SEC = 0, |
55 | RTC_MIN, |
56 | RTC_HOUR, |
57 | RTC_WEEKDAY, |
58 | RTC_MONTH, |
59 | RTC_YEAR, |
60 | RTC_DATE, |
61 | RTC_NR_TIME |
62 | }; |
63 | |
64 | struct max8997_rtc_info { |
65 | struct device *dev; |
66 | struct max8997_dev *max8997; |
67 | struct i2c_client *rtc; |
68 | struct rtc_device *rtc_dev; |
69 | struct mutex lock; |
70 | int virq; |
71 | int rtc_24hr_mode; |
72 | }; |
73 | |
74 | static void max8997_rtc_data_to_tm(u8 *data, struct rtc_time *tm, |
75 | int rtc_24hr_mode) |
76 | { |
77 | tm->tm_sec = data[RTC_SEC] & 0x7f; |
78 | tm->tm_min = data[RTC_MIN] & 0x7f; |
79 | if (rtc_24hr_mode) |
80 | tm->tm_hour = data[RTC_HOUR] & 0x1f; |
81 | else { |
82 | tm->tm_hour = data[RTC_HOUR] & 0x0f; |
83 | if (data[RTC_HOUR] & HOUR_PM_MASK) |
84 | tm->tm_hour += 12; |
85 | } |
86 | |
87 | tm->tm_wday = fls(x: data[RTC_WEEKDAY] & 0x7f) - 1; |
88 | tm->tm_mday = data[RTC_DATE] & 0x1f; |
89 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; |
90 | tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; |
91 | tm->tm_yday = 0; |
92 | tm->tm_isdst = 0; |
93 | } |
94 | |
95 | static int max8997_rtc_tm_to_data(struct rtc_time *tm, u8 *data) |
96 | { |
97 | data[RTC_SEC] = tm->tm_sec; |
98 | data[RTC_MIN] = tm->tm_min; |
99 | data[RTC_HOUR] = tm->tm_hour; |
100 | data[RTC_WEEKDAY] = 1 << tm->tm_wday; |
101 | data[RTC_DATE] = tm->tm_mday; |
102 | data[RTC_MONTH] = tm->tm_mon + 1; |
103 | data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; |
104 | |
105 | if (tm->tm_year < 100) { |
106 | pr_warn("RTC cannot handle the year %d. Assume it's 2000.\n" , |
107 | 1900 + tm->tm_year); |
108 | return -EINVAL; |
109 | } |
110 | return 0; |
111 | } |
112 | |
113 | static inline int max8997_rtc_set_update_reg(struct max8997_rtc_info *info) |
114 | { |
115 | int ret; |
116 | |
117 | ret = max8997_write_reg(i2c: info->rtc, reg: MAX8997_RTC_UPDATE1, |
118 | RTC_UDR_MASK); |
119 | if (ret < 0) |
120 | dev_err(info->dev, "%s: fail to write update reg(%d)\n" , |
121 | __func__, ret); |
122 | else { |
123 | /* Minimum 16ms delay required before RTC update. |
124 | * Otherwise, we may read and update based on out-of-date |
125 | * value */ |
126 | msleep(msecs: 20); |
127 | } |
128 | |
129 | return ret; |
130 | } |
131 | |
132 | static int max8997_rtc_read_time(struct device *dev, struct rtc_time *tm) |
133 | { |
134 | struct max8997_rtc_info *info = dev_get_drvdata(dev); |
135 | u8 data[RTC_NR_TIME]; |
136 | int ret; |
137 | |
138 | mutex_lock(&info->lock); |
139 | ret = max8997_bulk_read(i2c: info->rtc, reg: MAX8997_RTC_SEC, count: RTC_NR_TIME, buf: data); |
140 | mutex_unlock(lock: &info->lock); |
141 | |
142 | if (ret < 0) { |
143 | dev_err(info->dev, "%s: fail to read time reg(%d)\n" , __func__, |
144 | ret); |
145 | return ret; |
146 | } |
147 | |
148 | max8997_rtc_data_to_tm(data, tm, rtc_24hr_mode: info->rtc_24hr_mode); |
149 | |
150 | return 0; |
151 | } |
152 | |
153 | static int max8997_rtc_set_time(struct device *dev, struct rtc_time *tm) |
154 | { |
155 | struct max8997_rtc_info *info = dev_get_drvdata(dev); |
156 | u8 data[RTC_NR_TIME]; |
157 | int ret; |
158 | |
159 | ret = max8997_rtc_tm_to_data(tm, data); |
160 | if (ret < 0) |
161 | return ret; |
162 | |
163 | mutex_lock(&info->lock); |
164 | |
165 | ret = max8997_bulk_write(i2c: info->rtc, reg: MAX8997_RTC_SEC, count: RTC_NR_TIME, buf: data); |
166 | if (ret < 0) { |
167 | dev_err(info->dev, "%s: fail to write time reg(%d)\n" , __func__, |
168 | ret); |
169 | goto out; |
170 | } |
171 | |
172 | ret = max8997_rtc_set_update_reg(info); |
173 | out: |
174 | mutex_unlock(lock: &info->lock); |
175 | return ret; |
176 | } |
177 | |
178 | static int max8997_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
179 | { |
180 | struct max8997_rtc_info *info = dev_get_drvdata(dev); |
181 | u8 data[RTC_NR_TIME]; |
182 | u8 val; |
183 | int i, ret; |
184 | |
185 | mutex_lock(&info->lock); |
186 | |
187 | ret = max8997_bulk_read(i2c: info->rtc, reg: MAX8997_RTC_ALARM1_SEC, count: RTC_NR_TIME, |
188 | buf: data); |
189 | if (ret < 0) { |
190 | dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n" , |
191 | __func__, __LINE__, ret); |
192 | goto out; |
193 | } |
194 | |
195 | max8997_rtc_data_to_tm(data, tm: &alrm->time, rtc_24hr_mode: info->rtc_24hr_mode); |
196 | |
197 | alrm->enabled = 0; |
198 | for (i = 0; i < RTC_NR_TIME; i++) { |
199 | if (data[i] & ALARM_ENABLE_MASK) { |
200 | alrm->enabled = 1; |
201 | break; |
202 | } |
203 | } |
204 | |
205 | alrm->pending = 0; |
206 | ret = max8997_read_reg(i2c: info->max8997->i2c, reg: MAX8997_REG_STATUS1, dest: &val); |
207 | if (ret < 0) { |
208 | dev_err(info->dev, "%s:%d fail to read status1 reg(%d)\n" , |
209 | __func__, __LINE__, ret); |
210 | goto out; |
211 | } |
212 | |
213 | if (val & (1 << 4)) /* RTCA1 */ |
214 | alrm->pending = 1; |
215 | |
216 | out: |
217 | mutex_unlock(lock: &info->lock); |
218 | return ret; |
219 | } |
220 | |
221 | static int max8997_rtc_stop_alarm(struct max8997_rtc_info *info) |
222 | { |
223 | u8 data[RTC_NR_TIME]; |
224 | int ret, i; |
225 | |
226 | if (!mutex_is_locked(lock: &info->lock)) |
227 | dev_warn(info->dev, "%s: should have mutex locked\n" , __func__); |
228 | |
229 | ret = max8997_bulk_read(i2c: info->rtc, reg: MAX8997_RTC_ALARM1_SEC, count: RTC_NR_TIME, |
230 | buf: data); |
231 | if (ret < 0) { |
232 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n" , |
233 | __func__, ret); |
234 | goto out; |
235 | } |
236 | |
237 | for (i = 0; i < RTC_NR_TIME; i++) |
238 | data[i] &= ~ALARM_ENABLE_MASK; |
239 | |
240 | ret = max8997_bulk_write(i2c: info->rtc, reg: MAX8997_RTC_ALARM1_SEC, count: RTC_NR_TIME, |
241 | buf: data); |
242 | if (ret < 0) { |
243 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n" , |
244 | __func__, ret); |
245 | goto out; |
246 | } |
247 | |
248 | ret = max8997_rtc_set_update_reg(info); |
249 | out: |
250 | return ret; |
251 | } |
252 | |
253 | static int max8997_rtc_start_alarm(struct max8997_rtc_info *info) |
254 | { |
255 | u8 data[RTC_NR_TIME]; |
256 | int ret; |
257 | |
258 | if (!mutex_is_locked(lock: &info->lock)) |
259 | dev_warn(info->dev, "%s: should have mutex locked\n" , __func__); |
260 | |
261 | ret = max8997_bulk_read(i2c: info->rtc, reg: MAX8997_RTC_ALARM1_SEC, count: RTC_NR_TIME, |
262 | buf: data); |
263 | if (ret < 0) { |
264 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n" , |
265 | __func__, ret); |
266 | goto out; |
267 | } |
268 | |
269 | data[RTC_SEC] |= (1 << ALARM_ENABLE_SHIFT); |
270 | data[RTC_MIN] |= (1 << ALARM_ENABLE_SHIFT); |
271 | data[RTC_HOUR] |= (1 << ALARM_ENABLE_SHIFT); |
272 | data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK; |
273 | if (data[RTC_MONTH] & 0xf) |
274 | data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT); |
275 | if (data[RTC_YEAR] & 0x7f) |
276 | data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT); |
277 | if (data[RTC_DATE] & 0x1f) |
278 | data[RTC_DATE] |= (1 << ALARM_ENABLE_SHIFT); |
279 | |
280 | ret = max8997_bulk_write(i2c: info->rtc, reg: MAX8997_RTC_ALARM1_SEC, count: RTC_NR_TIME, |
281 | buf: data); |
282 | if (ret < 0) { |
283 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n" , |
284 | __func__, ret); |
285 | goto out; |
286 | } |
287 | |
288 | ret = max8997_rtc_set_update_reg(info); |
289 | out: |
290 | return ret; |
291 | } |
292 | static int max8997_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
293 | { |
294 | struct max8997_rtc_info *info = dev_get_drvdata(dev); |
295 | u8 data[RTC_NR_TIME]; |
296 | int ret; |
297 | |
298 | ret = max8997_rtc_tm_to_data(tm: &alrm->time, data); |
299 | if (ret < 0) |
300 | return ret; |
301 | |
302 | dev_info(info->dev, "%s: %d-%02d-%02d %02d:%02d:%02d\n" , __func__, |
303 | data[RTC_YEAR] + 2000, data[RTC_MONTH], data[RTC_DATE], |
304 | data[RTC_HOUR], data[RTC_MIN], data[RTC_SEC]); |
305 | |
306 | mutex_lock(&info->lock); |
307 | |
308 | ret = max8997_rtc_stop_alarm(info); |
309 | if (ret < 0) |
310 | goto out; |
311 | |
312 | ret = max8997_bulk_write(i2c: info->rtc, reg: MAX8997_RTC_ALARM1_SEC, count: RTC_NR_TIME, |
313 | buf: data); |
314 | if (ret < 0) { |
315 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n" , |
316 | __func__, ret); |
317 | goto out; |
318 | } |
319 | |
320 | ret = max8997_rtc_set_update_reg(info); |
321 | if (ret < 0) |
322 | goto out; |
323 | |
324 | if (alrm->enabled) |
325 | ret = max8997_rtc_start_alarm(info); |
326 | out: |
327 | mutex_unlock(lock: &info->lock); |
328 | return ret; |
329 | } |
330 | |
331 | static int max8997_rtc_alarm_irq_enable(struct device *dev, |
332 | unsigned int enabled) |
333 | { |
334 | struct max8997_rtc_info *info = dev_get_drvdata(dev); |
335 | int ret; |
336 | |
337 | mutex_lock(&info->lock); |
338 | if (enabled) |
339 | ret = max8997_rtc_start_alarm(info); |
340 | else |
341 | ret = max8997_rtc_stop_alarm(info); |
342 | mutex_unlock(lock: &info->lock); |
343 | |
344 | return ret; |
345 | } |
346 | |
347 | static irqreturn_t max8997_rtc_alarm_irq(int irq, void *data) |
348 | { |
349 | struct max8997_rtc_info *info = data; |
350 | |
351 | dev_info(info->dev, "%s:irq(%d)\n" , __func__, irq); |
352 | |
353 | rtc_update_irq(rtc: info->rtc_dev, num: 1, RTC_IRQF | RTC_AF); |
354 | |
355 | return IRQ_HANDLED; |
356 | } |
357 | |
358 | static const struct rtc_class_ops max8997_rtc_ops = { |
359 | .read_time = max8997_rtc_read_time, |
360 | .set_time = max8997_rtc_set_time, |
361 | .read_alarm = max8997_rtc_read_alarm, |
362 | .set_alarm = max8997_rtc_set_alarm, |
363 | .alarm_irq_enable = max8997_rtc_alarm_irq_enable, |
364 | }; |
365 | |
366 | static void max8997_rtc_enable_wtsr(struct max8997_rtc_info *info, bool enable) |
367 | { |
368 | int ret; |
369 | u8 val, mask; |
370 | |
371 | if (!wtsr_en) |
372 | return; |
373 | |
374 | if (enable) |
375 | val = (1 << WTSR_EN_SHIFT) | (3 << WTSRT_SHIFT); |
376 | else |
377 | val = 0; |
378 | |
379 | mask = WTSR_EN_MASK | WTSRT_MASK; |
380 | |
381 | dev_info(info->dev, "%s: %s WTSR\n" , __func__, |
382 | enable ? "enable" : "disable" ); |
383 | |
384 | ret = max8997_update_reg(i2c: info->rtc, reg: MAX8997_RTC_WTSR_SMPL, val, mask); |
385 | if (ret < 0) { |
386 | dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n" , |
387 | __func__, ret); |
388 | return; |
389 | } |
390 | |
391 | max8997_rtc_set_update_reg(info); |
392 | } |
393 | |
394 | static void max8997_rtc_enable_smpl(struct max8997_rtc_info *info, bool enable) |
395 | { |
396 | int ret; |
397 | u8 val, mask; |
398 | |
399 | if (!smpl_en) |
400 | return; |
401 | |
402 | if (enable) |
403 | val = (1 << SMPL_EN_SHIFT) | (0 << SMPLT_SHIFT); |
404 | else |
405 | val = 0; |
406 | |
407 | mask = SMPL_EN_MASK | SMPLT_MASK; |
408 | |
409 | dev_info(info->dev, "%s: %s SMPL\n" , __func__, |
410 | enable ? "enable" : "disable" ); |
411 | |
412 | ret = max8997_update_reg(i2c: info->rtc, reg: MAX8997_RTC_WTSR_SMPL, val, mask); |
413 | if (ret < 0) { |
414 | dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n" , |
415 | __func__, ret); |
416 | return; |
417 | } |
418 | |
419 | max8997_rtc_set_update_reg(info); |
420 | |
421 | val = 0; |
422 | max8997_read_reg(i2c: info->rtc, reg: MAX8997_RTC_WTSR_SMPL, dest: &val); |
423 | pr_info("WTSR_SMPL(0x%02x)\n" , val); |
424 | } |
425 | |
426 | static int max8997_rtc_init_reg(struct max8997_rtc_info *info) |
427 | { |
428 | u8 data[2]; |
429 | int ret; |
430 | |
431 | /* Set RTC control register : Binary mode, 24hour mdoe */ |
432 | data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); |
433 | data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); |
434 | |
435 | info->rtc_24hr_mode = 1; |
436 | |
437 | ret = max8997_bulk_write(i2c: info->rtc, reg: MAX8997_RTC_CTRLMASK, count: 2, buf: data); |
438 | if (ret < 0) { |
439 | dev_err(info->dev, "%s: fail to write controlm reg(%d)\n" , |
440 | __func__, ret); |
441 | return ret; |
442 | } |
443 | |
444 | ret = max8997_rtc_set_update_reg(info); |
445 | return ret; |
446 | } |
447 | |
448 | static int max8997_rtc_probe(struct platform_device *pdev) |
449 | { |
450 | struct max8997_dev *max8997 = dev_get_drvdata(dev: pdev->dev.parent); |
451 | struct max8997_rtc_info *info; |
452 | int ret, virq; |
453 | |
454 | info = devm_kzalloc(dev: &pdev->dev, size: sizeof(struct max8997_rtc_info), |
455 | GFP_KERNEL); |
456 | if (!info) |
457 | return -ENOMEM; |
458 | |
459 | mutex_init(&info->lock); |
460 | info->dev = &pdev->dev; |
461 | info->max8997 = max8997; |
462 | info->rtc = max8997->rtc; |
463 | |
464 | platform_set_drvdata(pdev, data: info); |
465 | |
466 | ret = max8997_rtc_init_reg(info); |
467 | |
468 | if (ret < 0) { |
469 | dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n" , ret); |
470 | return ret; |
471 | } |
472 | |
473 | max8997_rtc_enable_wtsr(info, enable: true); |
474 | max8997_rtc_enable_smpl(info, enable: true); |
475 | |
476 | device_init_wakeup(dev: &pdev->dev, enable: 1); |
477 | |
478 | info->rtc_dev = devm_rtc_device_register(dev: &pdev->dev, name: "max8997-rtc" , |
479 | ops: &max8997_rtc_ops, THIS_MODULE); |
480 | |
481 | if (IS_ERR(ptr: info->rtc_dev)) { |
482 | ret = PTR_ERR(ptr: info->rtc_dev); |
483 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n" , ret); |
484 | return ret; |
485 | } |
486 | |
487 | virq = irq_create_mapping(host: max8997->irq_domain, hwirq: MAX8997_PMICIRQ_RTCA1); |
488 | if (!virq) { |
489 | dev_err(&pdev->dev, "Failed to create mapping alarm IRQ\n" ); |
490 | ret = -ENXIO; |
491 | goto err_out; |
492 | } |
493 | info->virq = virq; |
494 | |
495 | ret = devm_request_threaded_irq(dev: &pdev->dev, irq: virq, NULL, |
496 | thread_fn: max8997_rtc_alarm_irq, irqflags: 0, |
497 | devname: "rtc-alarm0" , dev_id: info); |
498 | if (ret < 0) |
499 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n" , |
500 | info->virq, ret); |
501 | |
502 | err_out: |
503 | return ret; |
504 | } |
505 | |
506 | static void max8997_rtc_shutdown(struct platform_device *pdev) |
507 | { |
508 | struct max8997_rtc_info *info = platform_get_drvdata(pdev); |
509 | |
510 | max8997_rtc_enable_wtsr(info, enable: false); |
511 | max8997_rtc_enable_smpl(info, enable: false); |
512 | } |
513 | |
514 | static const struct platform_device_id rtc_id[] = { |
515 | { "max8997-rtc" , 0 }, |
516 | {}, |
517 | }; |
518 | MODULE_DEVICE_TABLE(platform, rtc_id); |
519 | |
520 | static struct platform_driver max8997_rtc_driver = { |
521 | .driver = { |
522 | .name = "max8997-rtc" , |
523 | }, |
524 | .probe = max8997_rtc_probe, |
525 | .shutdown = max8997_rtc_shutdown, |
526 | .id_table = rtc_id, |
527 | }; |
528 | |
529 | module_platform_driver(max8997_rtc_driver); |
530 | |
531 | MODULE_DESCRIPTION("Maxim MAX8997 RTC driver" ); |
532 | MODULE_AUTHOR("<ms925.kim@samsung.com>" ); |
533 | MODULE_LICENSE("GPL" ); |
534 | |