]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/rtc/rtc-s5m.c
ASoC: wm8523: Use IS_ENABLED() macro
[karo-tx-linux.git] / drivers / rtc / rtc-s5m.c
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd
3  *      http://www.samsung.com
4  *
5  *  Copyright (C) 2013 Google, Inc
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  */
17
18 #include <linux/module.h>
19 #include <linux/i2c.h>
20 #include <linux/slab.h>
21 #include <linux/bcd.h>
22 #include <linux/bitops.h>
23 #include <linux/regmap.h>
24 #include <linux/rtc.h>
25 #include <linux/delay.h>
26 #include <linux/platform_device.h>
27 #include <linux/mfd/samsung/core.h>
28 #include <linux/mfd/samsung/irq.h>
29 #include <linux/mfd/samsung/rtc.h>
30
31 struct s5m_rtc_info {
32         struct device *dev;
33         struct sec_pmic_dev *s5m87xx;
34         struct regmap *rtc;
35         struct rtc_device *rtc_dev;
36         int irq;
37         int device_type;
38         int rtc_24hr_mode;
39         bool wtsr_smpl;
40 };
41
42 static void s5m8767_data_to_tm(u8 *data, struct rtc_time *tm,
43                                int rtc_24hr_mode)
44 {
45         tm->tm_sec = data[RTC_SEC] & 0x7f;
46         tm->tm_min = data[RTC_MIN] & 0x7f;
47         if (rtc_24hr_mode) {
48                 tm->tm_hour = data[RTC_HOUR] & 0x1f;
49         } else {
50                 tm->tm_hour = data[RTC_HOUR] & 0x0f;
51                 if (data[RTC_HOUR] & HOUR_PM_MASK)
52                         tm->tm_hour += 12;
53         }
54
55         tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f);
56         tm->tm_mday = data[RTC_DATE] & 0x1f;
57         tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
58         tm->tm_year = (data[RTC_YEAR1] & 0x7f) + 100;
59         tm->tm_yday = 0;
60         tm->tm_isdst = 0;
61 }
62
63 static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data)
64 {
65         data[RTC_SEC] = tm->tm_sec;
66         data[RTC_MIN] = tm->tm_min;
67
68         if (tm->tm_hour >= 12)
69                 data[RTC_HOUR] = tm->tm_hour | HOUR_PM_MASK;
70         else
71                 data[RTC_HOUR] = tm->tm_hour & ~HOUR_PM_MASK;
72
73         data[RTC_WEEKDAY] = 1 << tm->tm_wday;
74         data[RTC_DATE] = tm->tm_mday;
75         data[RTC_MONTH] = tm->tm_mon + 1;
76         data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
77
78         if (tm->tm_year < 100) {
79                 pr_err("s5m8767 RTC cannot handle the year %d.\n",
80                        1900 + tm->tm_year);
81                 return -EINVAL;
82         } else {
83                 return 0;
84         }
85 }
86
87 static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
88 {
89         int ret;
90         unsigned int data;
91
92         ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data);
93         if (ret < 0) {
94                 dev_err(info->dev, "failed to read update reg(%d)\n", ret);
95                 return ret;
96         }
97
98         data |= RTC_TIME_EN_MASK;
99         data |= RTC_UDR_MASK;
100
101         ret = regmap_write(info->rtc, SEC_RTC_UDR_CON, data);
102         if (ret < 0) {
103                 dev_err(info->dev, "failed to write update reg(%d)\n", ret);
104                 return ret;
105         }
106
107         do {
108                 ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data);
109         } while ((data & RTC_UDR_MASK) && !ret);
110
111         return ret;
112 }
113
114 static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
115 {
116         int ret;
117         unsigned int data;
118
119         ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data);
120         if (ret < 0) {
121                 dev_err(info->dev, "%s: fail to read update reg(%d)\n",
122                         __func__, ret);
123                 return ret;
124         }
125
126         data &= ~RTC_TIME_EN_MASK;
127         data |= RTC_UDR_MASK;
128
129         ret = regmap_write(info->rtc, SEC_RTC_UDR_CON, data);
130         if (ret < 0) {
131                 dev_err(info->dev, "%s: fail to write update reg(%d)\n",
132                         __func__, ret);
133                 return ret;
134         }
135
136         do {
137                 ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data);
138         } while ((data & RTC_UDR_MASK) && !ret);
139
140         return ret;
141 }
142
143 static void s5m8763_data_to_tm(u8 *data, struct rtc_time *tm)
144 {
145         tm->tm_sec = bcd2bin(data[RTC_SEC]);
146         tm->tm_min = bcd2bin(data[RTC_MIN]);
147
148         if (data[RTC_HOUR] & HOUR_12) {
149                 tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f);
150                 if (data[RTC_HOUR] & HOUR_PM)
151                         tm->tm_hour += 12;
152         } else {
153                 tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);
154         }
155
156         tm->tm_wday = data[RTC_WEEKDAY] & 0x07;
157         tm->tm_mday = bcd2bin(data[RTC_DATE]);
158         tm->tm_mon = bcd2bin(data[RTC_MONTH]);
159         tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100;
160         tm->tm_year -= 1900;
161 }
162
163 static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data)
164 {
165         data[RTC_SEC] = bin2bcd(tm->tm_sec);
166         data[RTC_MIN] = bin2bcd(tm->tm_min);
167         data[RTC_HOUR] = bin2bcd(tm->tm_hour);
168         data[RTC_WEEKDAY] = tm->tm_wday;
169         data[RTC_DATE] = bin2bcd(tm->tm_mday);
170         data[RTC_MONTH] = bin2bcd(tm->tm_mon);
171         data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100);
172         data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100);
173 }
174
175 static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
176 {
177         struct s5m_rtc_info *info = dev_get_drvdata(dev);
178         u8 data[8];
179         int ret;
180
181         ret = regmap_bulk_read(info->rtc, SEC_RTC_SEC, data, 8);
182         if (ret < 0)
183                 return ret;
184
185         switch (info->device_type) {
186         case S5M8763X:
187                 s5m8763_data_to_tm(data, tm);
188                 break;
189
190         case S5M8767X:
191                 s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode);
192                 break;
193
194         default:
195                 return -EINVAL;
196         }
197
198         dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
199                 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
200                 tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
201
202         return rtc_valid_tm(tm);
203 }
204
205 static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
206 {
207         struct s5m_rtc_info *info = dev_get_drvdata(dev);
208         u8 data[8];
209         int ret = 0;
210
211         switch (info->device_type) {
212         case S5M8763X:
213                 s5m8763_tm_to_data(tm, data);
214                 break;
215         case S5M8767X:
216                 ret = s5m8767_tm_to_data(tm, data);
217                 break;
218         default:
219                 return -EINVAL;
220         }
221
222         if (ret < 0)
223                 return ret;
224
225         dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
226                 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
227                 tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
228
229         ret = regmap_raw_write(info->rtc, SEC_RTC_SEC, data, 8);
230         if (ret < 0)
231                 return ret;
232
233         ret = s5m8767_rtc_set_time_reg(info);
234
235         return ret;
236 }
237
238 static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
239 {
240         struct s5m_rtc_info *info = dev_get_drvdata(dev);
241         u8 data[8];
242         unsigned int val;
243         int ret, i;
244
245         ret = regmap_bulk_read(info->rtc, SEC_ALARM0_SEC, data, 8);
246         if (ret < 0)
247                 return ret;
248
249         switch (info->device_type) {
250         case S5M8763X:
251                 s5m8763_data_to_tm(data, &alrm->time);
252                 ret = regmap_read(info->rtc, SEC_ALARM0_CONF, &val);
253                 if (ret < 0)
254                         return ret;
255
256                 alrm->enabled = !!val;
257
258                 ret = regmap_read(info->rtc, SEC_RTC_STATUS, &val);
259                 if (ret < 0)
260                         return ret;
261
262                 break;
263
264         case S5M8767X:
265                 s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
266                 dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
267                         1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
268                         alrm->time.tm_mday, alrm->time.tm_hour,
269                         alrm->time.tm_min, alrm->time.tm_sec,
270                         alrm->time.tm_wday);
271
272                 alrm->enabled = 0;
273                 for (i = 0; i < 7; i++) {
274                         if (data[i] & ALARM_ENABLE_MASK) {
275                                 alrm->enabled = 1;
276                                 break;
277                         }
278                 }
279
280                 alrm->pending = 0;
281                 ret = regmap_read(info->rtc, SEC_RTC_STATUS, &val);
282                 if (ret < 0)
283                         return ret;
284                 break;
285
286         default:
287                 return -EINVAL;
288         }
289
290         if (val & ALARM0_STATUS)
291                 alrm->pending = 1;
292         else
293                 alrm->pending = 0;
294
295         return 0;
296 }
297
298 static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
299 {
300         u8 data[8];
301         int ret, i;
302         struct rtc_time tm;
303
304         ret = regmap_bulk_read(info->rtc, SEC_ALARM0_SEC, data, 8);
305         if (ret < 0)
306                 return ret;
307
308         s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
309         dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
310                 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
311                 tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
312
313         switch (info->device_type) {
314         case S5M8763X:
315                 ret = regmap_write(info->rtc, SEC_ALARM0_CONF, 0);
316                 break;
317
318         case S5M8767X:
319                 for (i = 0; i < 7; i++)
320                         data[i] &= ~ALARM_ENABLE_MASK;
321
322                 ret = regmap_raw_write(info->rtc, SEC_ALARM0_SEC, data, 8);
323                 if (ret < 0)
324                         return ret;
325
326                 ret = s5m8767_rtc_set_alarm_reg(info);
327
328                 break;
329
330         default:
331                 return -EINVAL;
332         }
333
334         return ret;
335 }
336
337 static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
338 {
339         int ret;
340         u8 data[8];
341         u8 alarm0_conf;
342         struct rtc_time tm;
343
344         ret = regmap_bulk_read(info->rtc, SEC_ALARM0_SEC, data, 8);
345         if (ret < 0)
346                 return ret;
347
348         s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
349         dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
350                 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
351                 tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
352
353         switch (info->device_type) {
354         case S5M8763X:
355                 alarm0_conf = 0x77;
356                 ret = regmap_write(info->rtc, SEC_ALARM0_CONF, alarm0_conf);
357                 break;
358
359         case S5M8767X:
360                 data[RTC_SEC] |= ALARM_ENABLE_MASK;
361                 data[RTC_MIN] |= ALARM_ENABLE_MASK;
362                 data[RTC_HOUR] |= ALARM_ENABLE_MASK;
363                 data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK;
364                 if (data[RTC_DATE] & 0x1f)
365                         data[RTC_DATE] |= ALARM_ENABLE_MASK;
366                 if (data[RTC_MONTH] & 0xf)
367                         data[RTC_MONTH] |= ALARM_ENABLE_MASK;
368                 if (data[RTC_YEAR1] & 0x7f)
369                         data[RTC_YEAR1] |= ALARM_ENABLE_MASK;
370
371                 ret = regmap_raw_write(info->rtc, SEC_ALARM0_SEC, data, 8);
372                 if (ret < 0)
373                         return ret;
374                 ret = s5m8767_rtc_set_alarm_reg(info);
375
376                 break;
377
378         default:
379                 return -EINVAL;
380         }
381
382         return ret;
383 }
384
385 static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
386 {
387         struct s5m_rtc_info *info = dev_get_drvdata(dev);
388         u8 data[8];
389         int ret;
390
391         switch (info->device_type) {
392         case S5M8763X:
393                 s5m8763_tm_to_data(&alrm->time, data);
394                 break;
395
396         case S5M8767X:
397                 s5m8767_tm_to_data(&alrm->time, data);
398                 break;
399
400         default:
401                 return -EINVAL;
402         }
403
404         dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
405                 1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
406                 alrm->time.tm_mday, alrm->time.tm_hour, alrm->time.tm_min,
407                 alrm->time.tm_sec, alrm->time.tm_wday);
408
409         ret = s5m_rtc_stop_alarm(info);
410         if (ret < 0)
411                 return ret;
412
413         ret = regmap_raw_write(info->rtc, SEC_ALARM0_SEC, data, 8);
414         if (ret < 0)
415                 return ret;
416
417         ret = s5m8767_rtc_set_alarm_reg(info);
418         if (ret < 0)
419                 return ret;
420
421         if (alrm->enabled)
422                 ret = s5m_rtc_start_alarm(info);
423
424         return ret;
425 }
426
427 static int s5m_rtc_alarm_irq_enable(struct device *dev,
428                                     unsigned int enabled)
429 {
430         struct s5m_rtc_info *info = dev_get_drvdata(dev);
431
432         if (enabled)
433                 return s5m_rtc_start_alarm(info);
434         else
435                 return s5m_rtc_stop_alarm(info);
436 }
437
438 static irqreturn_t s5m_rtc_alarm_irq(int irq, void *data)
439 {
440         struct s5m_rtc_info *info = data;
441
442         rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
443
444         return IRQ_HANDLED;
445 }
446
447 static const struct rtc_class_ops s5m_rtc_ops = {
448         .read_time = s5m_rtc_read_time,
449         .set_time = s5m_rtc_set_time,
450         .read_alarm = s5m_rtc_read_alarm,
451         .set_alarm = s5m_rtc_set_alarm,
452         .alarm_irq_enable = s5m_rtc_alarm_irq_enable,
453 };
454
455 static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable)
456 {
457         int ret;
458         ret = regmap_update_bits(info->rtc, SEC_WTSR_SMPL_CNTL,
459                                  WTSR_ENABLE_MASK,
460                                  enable ? WTSR_ENABLE_MASK : 0);
461         if (ret < 0)
462                 dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n",
463                         __func__, ret);
464 }
465
466 static void s5m_rtc_enable_smpl(struct s5m_rtc_info *info, bool enable)
467 {
468         int ret;
469         ret = regmap_update_bits(info->rtc, SEC_WTSR_SMPL_CNTL,
470                                  SMPL_ENABLE_MASK,
471                                  enable ? SMPL_ENABLE_MASK : 0);
472         if (ret < 0)
473                 dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n",
474                         __func__, ret);
475 }
476
477 static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
478 {
479         u8 data[2];
480         unsigned int tp_read;
481         int ret;
482         struct rtc_time tm;
483
484         ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &tp_read);
485         if (ret < 0) {
486                 dev_err(info->dev, "%s: fail to read control reg(%d)\n",
487                         __func__, ret);
488                 return ret;
489         }
490
491         /* Set RTC control register : Binary mode, 24hour mode */
492         data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
493         data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
494
495         info->rtc_24hr_mode = 1;
496         ret = regmap_raw_write(info->rtc, SEC_ALARM0_CONF, data, 2);
497         if (ret < 0) {
498                 dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
499                         __func__, ret);
500                 return ret;
501         }
502
503         /* In first boot time, Set rtc time to 1/1/2012 00:00:00(SUN) */
504         if ((tp_read & RTC_TCON_MASK) == 0) {
505                 dev_dbg(info->dev, "rtc init\n");
506                 tm.tm_sec = 0;
507                 tm.tm_min = 0;
508                 tm.tm_hour = 0;
509                 tm.tm_wday = 0;
510                 tm.tm_mday = 1;
511                 tm.tm_mon = 0;
512                 tm.tm_year = 112;
513                 tm.tm_yday = 0;
514                 tm.tm_isdst = 0;
515                 ret = s5m_rtc_set_time(info->dev, &tm);
516         }
517
518         ret = regmap_update_bits(info->rtc, SEC_RTC_UDR_CON,
519                                  RTC_TCON_MASK, tp_read | RTC_TCON_MASK);
520         if (ret < 0)
521                 dev_err(info->dev, "%s: fail to update TCON reg(%d)\n",
522                         __func__, ret);
523
524         return ret;
525 }
526
527 static int s5m_rtc_probe(struct platform_device *pdev)
528 {
529         struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent);
530         struct sec_platform_data *pdata = s5m87xx->pdata;
531         struct s5m_rtc_info *info;
532         int ret;
533
534         if (!pdata) {
535                 dev_err(pdev->dev.parent, "Platform data not supplied\n");
536                 return -ENODEV;
537         }
538
539         info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
540         if (!info)
541                 return -ENOMEM;
542
543         info->dev = &pdev->dev;
544         info->s5m87xx = s5m87xx;
545         info->rtc = s5m87xx->rtc;
546         info->device_type = s5m87xx->device_type;
547         info->wtsr_smpl = s5m87xx->wtsr_smpl;
548
549         switch (pdata->device_type) {
550         case S5M8763X:
551                 info->irq = s5m87xx->irq_base + S5M8763_IRQ_ALARM0;
552                 break;
553
554         case S5M8767X:
555                 info->irq = s5m87xx->irq_base + S5M8767_IRQ_RTCA1;
556                 break;
557
558         default:
559                 ret = -EINVAL;
560                 dev_err(&pdev->dev, "Unsupported device type: %d\n", ret);
561                 return ret;
562         }
563
564         platform_set_drvdata(pdev, info);
565
566         ret = s5m8767_rtc_init_reg(info);
567
568         if (info->wtsr_smpl) {
569                 s5m_rtc_enable_wtsr(info, true);
570                 s5m_rtc_enable_smpl(info, true);
571         }
572
573         device_init_wakeup(&pdev->dev, 1);
574
575         info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc",
576                                                  &s5m_rtc_ops, THIS_MODULE);
577
578         if (IS_ERR(info->rtc_dev))
579                 return PTR_ERR(info->rtc_dev);
580
581         ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
582                                         s5m_rtc_alarm_irq, 0, "rtc-alarm0",
583                                         info);
584         if (ret < 0)
585                 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
586                         info->irq, ret);
587
588         return ret;
589 }
590
591 static void s5m_rtc_shutdown(struct platform_device *pdev)
592 {
593         struct s5m_rtc_info *info = platform_get_drvdata(pdev);
594         int i;
595         unsigned int val = 0;
596         if (info->wtsr_smpl) {
597                 for (i = 0; i < 3; i++) {
598                         s5m_rtc_enable_wtsr(info, false);
599                         regmap_read(info->rtc, SEC_WTSR_SMPL_CNTL, &val);
600                         pr_debug("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val);
601                         if (val & WTSR_ENABLE_MASK)
602                                 pr_emerg("%s: fail to disable WTSR\n",
603                                          __func__);
604                         else {
605                                 pr_info("%s: success to disable WTSR\n",
606                                         __func__);
607                                 break;
608                         }
609                 }
610         }
611         /* Disable SMPL when power off */
612         s5m_rtc_enable_smpl(info, false);
613 }
614
615 static const struct platform_device_id s5m_rtc_id[] = {
616         { "s5m-rtc", 0 },
617 };
618
619 static struct platform_driver s5m_rtc_driver = {
620         .driver         = {
621                 .name   = "s5m-rtc",
622                 .owner  = THIS_MODULE,
623         },
624         .probe          = s5m_rtc_probe,
625         .shutdown       = s5m_rtc_shutdown,
626         .id_table       = s5m_rtc_id,
627 };
628
629 module_platform_driver(s5m_rtc_driver);
630
631 /* Module information */
632 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
633 MODULE_DESCRIPTION("Samsung S5M RTC driver");
634 MODULE_LICENSE("GPL");
635 MODULE_ALIAS("platform:s5m-rtc");