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