blob: 55396bb3de2188ca85cce47fad9f891ed18a503c [file] [log] [blame]
Jonghwa Leefca1dd02013-02-21 16:44:26 -08001/*
2 * RTC driver for Maxim MAX77686
3 *
4 * Copyright (C) 2012 Samsung Electronics Co.Ltd
5 *
6 * based on rtc-max8997.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/max77686-private.h>
22#include <linux/irqdomain.h>
23#include <linux/regmap.h>
24
25/* RTC Control Register */
26#define BCD_EN_SHIFT 0
Jingoo Hanac60bf32013-04-29 16:18:31 -070027#define BCD_EN_MASK (1 << BCD_EN_SHIFT)
Jonghwa Leefca1dd02013-02-21 16:44:26 -080028#define MODEL24_SHIFT 1
29#define MODEL24_MASK (1 << MODEL24_SHIFT)
30/* RTC Update Register1 */
31#define RTC_UDR_SHIFT 0
32#define RTC_UDR_MASK (1 << RTC_UDR_SHIFT)
33#define RTC_RBUDR_SHIFT 4
34#define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT)
Jonghwa Leefca1dd02013-02-21 16:44:26 -080035/* RTC Hour register */
36#define HOUR_PM_SHIFT 6
37#define HOUR_PM_MASK (1 << HOUR_PM_SHIFT)
38/* RTC Alarm Enable */
39#define ALARM_ENABLE_SHIFT 7
40#define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT)
41
42#define MAX77686_RTC_UPDATE_DELAY 16
Jonghwa Leefca1dd02013-02-21 16:44:26 -080043
44enum {
45 RTC_SEC = 0,
46 RTC_MIN,
47 RTC_HOUR,
48 RTC_WEEKDAY,
49 RTC_MONTH,
50 RTC_YEAR,
51 RTC_DATE,
52 RTC_NR_TIME
53};
54
55struct max77686_rtc_info {
56 struct device *dev;
57 struct max77686_dev *max77686;
58 struct i2c_client *rtc;
59 struct rtc_device *rtc_dev;
60 struct mutex lock;
61
62 struct regmap *regmap;
63
64 int virq;
65 int rtc_24hr_mode;
66};
67
68enum MAX77686_RTC_OP {
69 MAX77686_RTC_WRITE,
70 MAX77686_RTC_READ,
71};
72
73static inline int max77686_rtc_calculate_wday(u8 shifted)
74{
75 int counter = -1;
76 while (shifted) {
77 shifted >>= 1;
78 counter++;
79 }
80 return counter;
81}
82
83static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm,
84 int rtc_24hr_mode)
85{
86 tm->tm_sec = data[RTC_SEC] & 0x7f;
87 tm->tm_min = data[RTC_MIN] & 0x7f;
88 if (rtc_24hr_mode)
89 tm->tm_hour = data[RTC_HOUR] & 0x1f;
90 else {
91 tm->tm_hour = data[RTC_HOUR] & 0x0f;
92 if (data[RTC_HOUR] & HOUR_PM_MASK)
93 tm->tm_hour += 12;
94 }
95
96 tm->tm_wday = max77686_rtc_calculate_wday(data[RTC_WEEKDAY] & 0x7f);
97 tm->tm_mday = data[RTC_DATE] & 0x1f;
98 tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
99 tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100;
100 tm->tm_yday = 0;
101 tm->tm_isdst = 0;
102}
103
104static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data)
105{
106 data[RTC_SEC] = tm->tm_sec;
107 data[RTC_MIN] = tm->tm_min;
108 data[RTC_HOUR] = tm->tm_hour;
109 data[RTC_WEEKDAY] = 1 << tm->tm_wday;
110 data[RTC_DATE] = tm->tm_mday;
111 data[RTC_MONTH] = tm->tm_mon + 1;
Sachin Kamatcdf5f4a2013-07-03 15:05:55 -0700112 data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800113
114 if (tm->tm_year < 100) {
115 pr_warn("%s: MAX77686 RTC cannot handle the year %d."
116 "Assume it's 2000.\n", __func__, 1900 + tm->tm_year);
117 return -EINVAL;
118 }
119 return 0;
120}
121
122static int max77686_rtc_update(struct max77686_rtc_info *info,
123 enum MAX77686_RTC_OP op)
124{
125 int ret;
126 unsigned int data;
127
128 if (op == MAX77686_RTC_WRITE)
129 data = 1 << RTC_UDR_SHIFT;
130 else
131 data = 1 << RTC_RBUDR_SHIFT;
132
133 ret = regmap_update_bits(info->max77686->rtc_regmap,
134 MAX77686_RTC_UPDATE0, data, data);
135 if (ret < 0)
136 dev_err(info->dev, "%s: fail to write update reg(ret=%d, data=0x%x)\n",
137 __func__, ret, data);
138 else {
139 /* Minimum 16ms delay required before RTC update. */
140 msleep(MAX77686_RTC_UPDATE_DELAY);
141 }
142
143 return ret;
144}
145
146static int max77686_rtc_read_time(struct device *dev, struct rtc_time *tm)
147{
148 struct max77686_rtc_info *info = dev_get_drvdata(dev);
149 u8 data[RTC_NR_TIME];
150 int ret;
151
152 mutex_lock(&info->lock);
153
154 ret = max77686_rtc_update(info, MAX77686_RTC_READ);
155 if (ret < 0)
156 goto out;
157
158 ret = regmap_bulk_read(info->max77686->rtc_regmap,
159 MAX77686_RTC_SEC, data, RTC_NR_TIME);
160 if (ret < 0) {
161 dev_err(info->dev, "%s: fail to read time reg(%d)\n", __func__, ret);
162 goto out;
163 }
164
165 max77686_rtc_data_to_tm(data, tm, info->rtc_24hr_mode);
166
167 ret = rtc_valid_tm(tm);
168
169out:
170 mutex_unlock(&info->lock);
171 return ret;
172}
173
174static int max77686_rtc_set_time(struct device *dev, struct rtc_time *tm)
175{
176 struct max77686_rtc_info *info = dev_get_drvdata(dev);
177 u8 data[RTC_NR_TIME];
178 int ret;
179
180 ret = max77686_rtc_tm_to_data(tm, data);
181 if (ret < 0)
182 return ret;
183
184 mutex_lock(&info->lock);
185
186 ret = regmap_bulk_write(info->max77686->rtc_regmap,
187 MAX77686_RTC_SEC, data, RTC_NR_TIME);
188 if (ret < 0) {
189 dev_err(info->dev, "%s: fail to write time reg(%d)\n", __func__,
190 ret);
191 goto out;
192 }
193
194 ret = max77686_rtc_update(info, MAX77686_RTC_WRITE);
195
196out:
197 mutex_unlock(&info->lock);
198 return ret;
199}
200
201static int max77686_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
202{
203 struct max77686_rtc_info *info = dev_get_drvdata(dev);
204 u8 data[RTC_NR_TIME];
205 unsigned int val;
206 int i, ret;
207
208 mutex_lock(&info->lock);
209
210 ret = max77686_rtc_update(info, MAX77686_RTC_READ);
211 if (ret < 0)
212 goto out;
213
214 ret = regmap_bulk_read(info->max77686->rtc_regmap,
215 MAX77686_ALARM1_SEC, data, RTC_NR_TIME);
216 if (ret < 0) {
217 dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n",
218 __func__, __LINE__, ret);
219 goto out;
220 }
221
222 max77686_rtc_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
223
224 alrm->enabled = 0;
225 for (i = 0; i < RTC_NR_TIME; i++) {
226 if (data[i] & ALARM_ENABLE_MASK) {
227 alrm->enabled = 1;
228 break;
229 }
230 }
231
232 alrm->pending = 0;
Sangjung Woo1748cbf2013-09-11 14:24:21 -0700233 ret = regmap_read(info->max77686->regmap, MAX77686_REG_STATUS2, &val);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800234 if (ret < 0) {
Sangjung Woo1748cbf2013-09-11 14:24:21 -0700235 dev_err(info->dev, "%s:%d fail to read status2 reg(%d)\n",
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800236 __func__, __LINE__, ret);
237 goto out;
238 }
239
240 if (val & (1 << 4)) /* RTCA1 */
241 alrm->pending = 1;
242
243out:
244 mutex_unlock(&info->lock);
245 return 0;
246}
247
248static int max77686_rtc_stop_alarm(struct max77686_rtc_info *info)
249{
250 u8 data[RTC_NR_TIME];
251 int ret, i;
252 struct rtc_time tm;
253
254 if (!mutex_is_locked(&info->lock))
255 dev_warn(info->dev, "%s: should have mutex locked\n", __func__);
256
257 ret = max77686_rtc_update(info, MAX77686_RTC_READ);
258 if (ret < 0)
259 goto out;
260
261 ret = regmap_bulk_read(info->max77686->rtc_regmap,
262 MAX77686_ALARM1_SEC, data, RTC_NR_TIME);
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 max77686_rtc_data_to_tm(data, &tm, info->rtc_24hr_mode);
270
271 for (i = 0; i < RTC_NR_TIME; i++)
272 data[i] &= ~ALARM_ENABLE_MASK;
273
274 ret = regmap_bulk_write(info->max77686->rtc_regmap,
275 MAX77686_ALARM1_SEC, data, RTC_NR_TIME);
276 if (ret < 0) {
277 dev_err(info->dev, "%s: fail to write alarm reg(%d)\n",
278 __func__, ret);
279 goto out;
280 }
281
282 ret = max77686_rtc_update(info, MAX77686_RTC_WRITE);
283out:
284 return ret;
285}
286
287static int max77686_rtc_start_alarm(struct max77686_rtc_info *info)
288{
289 u8 data[RTC_NR_TIME];
290 int ret;
291 struct rtc_time tm;
292
293 if (!mutex_is_locked(&info->lock))
294 dev_warn(info->dev, "%s: should have mutex locked\n", __func__);
295
296 ret = max77686_rtc_update(info, MAX77686_RTC_READ);
297 if (ret < 0)
298 goto out;
299
300 ret = regmap_bulk_read(info->max77686->rtc_regmap,
301 MAX77686_ALARM1_SEC, data, RTC_NR_TIME);
302 if (ret < 0) {
303 dev_err(info->dev, "%s: fail to read alarm reg(%d)\n",
304 __func__, ret);
305 goto out;
306 }
307
308 max77686_rtc_data_to_tm(data, &tm, info->rtc_24hr_mode);
309
310 data[RTC_SEC] |= (1 << ALARM_ENABLE_SHIFT);
311 data[RTC_MIN] |= (1 << ALARM_ENABLE_SHIFT);
312 data[RTC_HOUR] |= (1 << ALARM_ENABLE_SHIFT);
313 data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK;
314 if (data[RTC_MONTH] & 0xf)
315 data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT);
316 if (data[RTC_YEAR] & 0x7f)
317 data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT);
318 if (data[RTC_DATE] & 0x1f)
319 data[RTC_DATE] |= (1 << ALARM_ENABLE_SHIFT);
320
321 ret = regmap_bulk_write(info->max77686->rtc_regmap,
322 MAX77686_ALARM1_SEC, data, RTC_NR_TIME);
323 if (ret < 0) {
324 dev_err(info->dev, "%s: fail to write alarm reg(%d)\n",
325 __func__, ret);
326 goto out;
327 }
328
329 ret = max77686_rtc_update(info, MAX77686_RTC_WRITE);
330out:
331 return ret;
332}
333
334static int max77686_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
335{
336 struct max77686_rtc_info *info = dev_get_drvdata(dev);
337 u8 data[RTC_NR_TIME];
338 int ret;
339
340 ret = max77686_rtc_tm_to_data(&alrm->time, data);
341 if (ret < 0)
342 return ret;
343
344 mutex_lock(&info->lock);
345
346 ret = max77686_rtc_stop_alarm(info);
347 if (ret < 0)
348 goto out;
349
350 ret = regmap_bulk_write(info->max77686->rtc_regmap,
351 MAX77686_ALARM1_SEC, data, RTC_NR_TIME);
352
353 if (ret < 0) {
354 dev_err(info->dev, "%s: fail to write alarm reg(%d)\n",
355 __func__, ret);
356 goto out;
357 }
358
359 ret = max77686_rtc_update(info, MAX77686_RTC_WRITE);
360 if (ret < 0)
361 goto out;
362
363 if (alrm->enabled)
364 ret = max77686_rtc_start_alarm(info);
365out:
366 mutex_unlock(&info->lock);
367 return ret;
368}
369
370static int max77686_rtc_alarm_irq_enable(struct device *dev,
371 unsigned int enabled)
372{
373 struct max77686_rtc_info *info = dev_get_drvdata(dev);
374 int ret;
375
376 mutex_lock(&info->lock);
377 if (enabled)
378 ret = max77686_rtc_start_alarm(info);
379 else
380 ret = max77686_rtc_stop_alarm(info);
381 mutex_unlock(&info->lock);
382
383 return ret;
384}
385
386static irqreturn_t max77686_rtc_alarm_irq(int irq, void *data)
387{
388 struct max77686_rtc_info *info = data;
389
390 dev_info(info->dev, "%s:irq(%d)\n", __func__, irq);
391
392 rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
393
394 return IRQ_HANDLED;
395}
396
397static const struct rtc_class_ops max77686_rtc_ops = {
398 .read_time = max77686_rtc_read_time,
399 .set_time = max77686_rtc_set_time,
400 .read_alarm = max77686_rtc_read_alarm,
401 .set_alarm = max77686_rtc_set_alarm,
402 .alarm_irq_enable = max77686_rtc_alarm_irq_enable,
403};
404
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800405static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
406{
407 u8 data[2];
408 int ret;
409
410 /* Set RTC control register : Binary mode, 24hour mdoe */
411 data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
412 data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
413
414 info->rtc_24hr_mode = 1;
415
416 ret = regmap_bulk_write(info->max77686->rtc_regmap, MAX77686_RTC_CONTROLM, data, 2);
417 if (ret < 0) {
418 dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
419 __func__, ret);
420 return ret;
421 }
422
423 ret = max77686_rtc_update(info, MAX77686_RTC_WRITE);
424 return ret;
425}
426
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800427static int max77686_rtc_probe(struct platform_device *pdev)
428{
429 struct max77686_dev *max77686 = dev_get_drvdata(pdev->dev.parent);
430 struct max77686_rtc_info *info;
Javier Martinez Canillas6f1c1e72014-07-04 22:24:04 +0200431 int ret;
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800432
Jingoo Han3cebeb52013-02-21 16:45:24 -0800433 dev_info(&pdev->dev, "%s\n", __func__);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800434
Jingoo Han0f64f852013-04-29 16:18:30 -0700435 info = devm_kzalloc(&pdev->dev, sizeof(struct max77686_rtc_info),
436 GFP_KERNEL);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800437 if (!info)
438 return -ENOMEM;
439
440 mutex_init(&info->lock);
441 info->dev = &pdev->dev;
442 info->max77686 = max77686;
443 info->rtc = max77686->rtc;
Javier Martinez Canillas6f1c1e72014-07-04 22:24:04 +0200444
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800445 platform_set_drvdata(pdev, info);
446
447 ret = max77686_rtc_init_reg(info);
448
449 if (ret < 0) {
450 dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret);
451 goto err_rtc;
452 }
453
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800454 device_init_wakeup(&pdev->dev, 1);
455
Jingoo Hanf56950e2013-04-29 16:19:05 -0700456 info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc",
457 &max77686_rtc_ops, THIS_MODULE);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800458
459 if (IS_ERR(info->rtc_dev)) {
Jingoo Han3cebeb52013-02-21 16:45:24 -0800460 dev_info(&pdev->dev, "%s: fail\n", __func__);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800461
462 ret = PTR_ERR(info->rtc_dev);
463 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
464 if (ret == 0)
465 ret = -EINVAL;
466 goto err_rtc;
467 }
Javier Martinez Canillas6f1c1e72014-07-04 22:24:04 +0200468
Javier Martinez Canillas1745d6d2014-10-13 15:52:59 -0700469 if (!max77686->rtc_irq_data) {
470 ret = -EINVAL;
471 dev_err(&pdev->dev, "%s: no RTC regmap IRQ chip\n", __func__);
472 goto err_rtc;
473 }
474
Javier Martinez Canillas6f1c1e72014-07-04 22:24:04 +0200475 info->virq = regmap_irq_get_virq(max77686->rtc_irq_data,
476 MAX77686_RTCIRQ_RTCA1);
477 if (!info->virq) {
Sachin Kamatad819032013-04-29 16:20:12 -0700478 ret = -ENXIO;
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800479 goto err_rtc;
Sachin Kamatad819032013-04-29 16:20:12 -0700480 }
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800481
Javier Martinez Canillas6f1c1e72014-07-04 22:24:04 +0200482 ret = devm_request_threaded_irq(&pdev->dev, info->virq, NULL,
483 max77686_rtc_alarm_irq, 0, "rtc-alarm1", info);
Sachin Kamatad819032013-04-29 16:20:12 -0700484 if (ret < 0)
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800485 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
486 info->virq, ret);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800487
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800488err_rtc:
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800489 return ret;
490}
491
Doug Andersone7f7fc72014-10-13 15:52:55 -0700492#ifdef CONFIG_PM_SLEEP
493static int max77686_rtc_suspend(struct device *dev)
494{
495 if (device_may_wakeup(dev)) {
496 struct max77686_rtc_info *info = dev_get_drvdata(dev);
497
498 return enable_irq_wake(info->virq);
499 }
500
501 return 0;
502}
503
504static int max77686_rtc_resume(struct device *dev)
505{
506 if (device_may_wakeup(dev)) {
507 struct max77686_rtc_info *info = dev_get_drvdata(dev);
508
509 return disable_irq_wake(info->virq);
510 }
511
512 return 0;
513}
514#endif
515
516static SIMPLE_DEV_PM_OPS(max77686_rtc_pm_ops,
517 max77686_rtc_suspend, max77686_rtc_resume);
518
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800519static const struct platform_device_id rtc_id[] = {
520 { "max77686-rtc", 0 },
521 {},
522};
523
524static struct platform_driver max77686_rtc_driver = {
525 .driver = {
526 .name = "max77686-rtc",
527 .owner = THIS_MODULE,
Doug Andersone7f7fc72014-10-13 15:52:55 -0700528 .pm = &max77686_rtc_pm_ops,
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800529 },
530 .probe = max77686_rtc_probe,
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800531 .id_table = rtc_id,
532};
533
Jingoo Han0c58ff52013-04-29 16:18:28 -0700534module_platform_driver(max77686_rtc_driver);
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800535
536MODULE_DESCRIPTION("Maxim MAX77686 RTC driver");
Jingoo Hanf5b1d3c2013-04-29 16:18:29 -0700537MODULE_AUTHOR("Chiwoong Byun <woong.byun@samsung.com>");
Jonghwa Leefca1dd02013-02-21 16:44:26 -0800538MODULE_LICENSE("GPL");