]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/rtc/rtc-s5m.c
rtc: s5m: support different register layout
[karo-tx-linux.git] / drivers / rtc / rtc-s5m.c
1 /*
2  * Copyright (c) 2013-2014 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 /*
32  * Maximum number of retries for checking changes in UDR field
33  * of S5M_RTC_UDR_CON register (to limit possible endless loop).
34  *
35  * After writing to RTC registers (setting time or alarm) read the UDR field
36  * in S5M_RTC_UDR_CON register. UDR is auto-cleared when data have
37  * been transferred.
38  */
39 #define UDR_READ_RETRY_CNT      5
40
41 /* Registers used by the driver which are different between chipsets. */
42 struct s5m_rtc_reg_config {
43         /* Number of registers used for setting time/alarm0/alarm1 */
44         unsigned int regs_count;
45         /* First register for time, seconds */
46         unsigned int time;
47         /* RTC control register */
48         unsigned int ctrl;
49         /* First register for alarm 0, seconds */
50         unsigned int alarm0;
51         /* First register for alarm 1, seconds */
52         unsigned int alarm1;
53         /* SMPL/WTSR register */
54         unsigned int smpl_wtsr;
55         /*
56          * Register for update flag (UDR). Typically setting UDR field to 1
57          * will enable update of time or alarm register. Then it will be
58          * auto-cleared after successful update.
59          */
60         unsigned int rtc_udr_update;
61         /* Mask for UDR field in 'rtc_udr_update' register */
62         unsigned int rtc_udr_mask;
63 };
64
65 /* Register map for S5M8763 and S5M8767 */
66 static const struct s5m_rtc_reg_config s5m_rtc_regs = {
67         .regs_count             = 8,
68         .time                   = S5M_RTC_SEC,
69         .ctrl                   = S5M_ALARM1_CONF,
70         .alarm0                 = S5M_ALARM0_SEC,
71         .alarm1                 = S5M_ALARM1_SEC,
72         .smpl_wtsr              = S5M_WTSR_SMPL_CNTL,
73         .rtc_udr_update         = S5M_RTC_UDR_CON,
74         .rtc_udr_mask           = S5M_RTC_UDR_MASK,
75 };
76
77 struct s5m_rtc_info {
78         struct device *dev;
79         struct i2c_client *i2c;
80         struct sec_pmic_dev *s5m87xx;
81         struct regmap *regmap;
82         struct rtc_device *rtc_dev;
83         int irq;
84         int device_type;
85         int rtc_24hr_mode;
86         bool wtsr_smpl;
87         const struct s5m_rtc_reg_config *regs;
88 };
89
90 static const struct regmap_config s5m_rtc_regmap_config = {
91         .reg_bits = 8,
92         .val_bits = 8,
93
94         .max_register = S5M_RTC_REG_MAX,
95 };
96
97 static const struct regmap_config s2mps14_rtc_regmap_config = {
98         .reg_bits = 8,
99         .val_bits = 8,
100
101         .max_register = S2MPS_RTC_REG_MAX,
102 };
103
104 static void s5m8767_data_to_tm(u8 *data, struct rtc_time *tm,
105                                int rtc_24hr_mode)
106 {
107         tm->tm_sec = data[RTC_SEC] & 0x7f;
108         tm->tm_min = data[RTC_MIN] & 0x7f;
109         if (rtc_24hr_mode) {
110                 tm->tm_hour = data[RTC_HOUR] & 0x1f;
111         } else {
112                 tm->tm_hour = data[RTC_HOUR] & 0x0f;
113                 if (data[RTC_HOUR] & HOUR_PM_MASK)
114                         tm->tm_hour += 12;
115         }
116
117         tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f);
118         tm->tm_mday = data[RTC_DATE] & 0x1f;
119         tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
120         tm->tm_year = (data[RTC_YEAR1] & 0x7f) + 100;
121         tm->tm_yday = 0;
122         tm->tm_isdst = 0;
123 }
124
125 static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data)
126 {
127         data[RTC_SEC] = tm->tm_sec;
128         data[RTC_MIN] = tm->tm_min;
129
130         if (tm->tm_hour >= 12)
131                 data[RTC_HOUR] = tm->tm_hour | HOUR_PM_MASK;
132         else
133                 data[RTC_HOUR] = tm->tm_hour & ~HOUR_PM_MASK;
134
135         data[RTC_WEEKDAY] = 1 << tm->tm_wday;
136         data[RTC_DATE] = tm->tm_mday;
137         data[RTC_MONTH] = tm->tm_mon + 1;
138         data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
139
140         if (tm->tm_year < 100) {
141                 pr_err("s5m8767 RTC cannot handle the year %d.\n",
142                        1900 + tm->tm_year);
143                 return -EINVAL;
144         } else {
145                 return 0;
146         }
147 }
148
149 /*
150  * Read RTC_UDR_CON register and wait till UDR field is cleared.
151  * This indicates that time/alarm update ended.
152  */
153 static inline int s5m8767_wait_for_udr_update(struct s5m_rtc_info *info)
154 {
155         int ret, retry = UDR_READ_RETRY_CNT;
156         unsigned int data;
157
158         do {
159                 ret = regmap_read(info->regmap, info->regs->rtc_udr_update,
160                                 &data);
161         } while (--retry && (data & info->regs->rtc_udr_mask) && !ret);
162
163         if (!retry)
164                 dev_err(info->dev, "waiting for UDR update, reached max number of retries\n");
165
166         return ret;
167 }
168
169 static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info,
170                 struct rtc_wkalrm *alarm)
171 {
172         int ret;
173         unsigned int val;
174
175         switch (info->device_type) {
176         case S5M8767X:
177         case S5M8763X:
178                 ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val);
179                 val &= S5M_ALARM0_STATUS;
180                 break;
181         default:
182                 return -EINVAL;
183         }
184         if (ret < 0)
185                 return ret;
186
187         if (val)
188                 alarm->pending = 1;
189         else
190                 alarm->pending = 0;
191
192         return 0;
193 }
194
195 static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
196 {
197         int ret;
198         unsigned int data;
199
200         ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data);
201         if (ret < 0) {
202                 dev_err(info->dev, "failed to read update reg(%d)\n", ret);
203                 return ret;
204         }
205
206         data |= S5M_RTC_TIME_EN_MASK;
207         data |= info->regs->rtc_udr_mask;
208
209         ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data);
210         if (ret < 0) {
211                 dev_err(info->dev, "failed to write update reg(%d)\n", ret);
212                 return ret;
213         }
214
215         ret = s5m8767_wait_for_udr_update(info);
216
217         return ret;
218 }
219
220 static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
221 {
222         int ret;
223         unsigned int data;
224
225         ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data);
226         if (ret < 0) {
227                 dev_err(info->dev, "%s: fail to read update reg(%d)\n",
228                         __func__, ret);
229                 return ret;
230         }
231
232         data &= ~S5M_RTC_TIME_EN_MASK;
233         data |= info->regs->rtc_udr_mask;
234
235         ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data);
236         if (ret < 0) {
237                 dev_err(info->dev, "%s: fail to write update reg(%d)\n",
238                         __func__, ret);
239                 return ret;
240         }
241
242         ret = s5m8767_wait_for_udr_update(info);
243
244         return ret;
245 }
246
247 static void s5m8763_data_to_tm(u8 *data, struct rtc_time *tm)
248 {
249         tm->tm_sec = bcd2bin(data[RTC_SEC]);
250         tm->tm_min = bcd2bin(data[RTC_MIN]);
251
252         if (data[RTC_HOUR] & HOUR_12) {
253                 tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f);
254                 if (data[RTC_HOUR] & HOUR_PM)
255                         tm->tm_hour += 12;
256         } else {
257                 tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);
258         }
259
260         tm->tm_wday = data[RTC_WEEKDAY] & 0x07;
261         tm->tm_mday = bcd2bin(data[RTC_DATE]);
262         tm->tm_mon = bcd2bin(data[RTC_MONTH]);
263         tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100;
264         tm->tm_year -= 1900;
265 }
266
267 static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data)
268 {
269         data[RTC_SEC] = bin2bcd(tm->tm_sec);
270         data[RTC_MIN] = bin2bcd(tm->tm_min);
271         data[RTC_HOUR] = bin2bcd(tm->tm_hour);
272         data[RTC_WEEKDAY] = tm->tm_wday;
273         data[RTC_DATE] = bin2bcd(tm->tm_mday);
274         data[RTC_MONTH] = bin2bcd(tm->tm_mon);
275         data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100);
276         data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100);
277 }
278
279 static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
280 {
281         struct s5m_rtc_info *info = dev_get_drvdata(dev);
282         u8 data[info->regs->regs_count];
283         int ret;
284
285         ret = regmap_bulk_read(info->regmap, info->regs->time, data,
286                         info->regs->regs_count);
287         if (ret < 0)
288                 return ret;
289
290         switch (info->device_type) {
291         case S5M8763X:
292                 s5m8763_data_to_tm(data, tm);
293                 break;
294
295         case S5M8767X:
296                 s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode);
297                 break;
298
299         default:
300                 return -EINVAL;
301         }
302
303         dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
304                 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
305                 tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
306
307         return rtc_valid_tm(tm);
308 }
309
310 static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
311 {
312         struct s5m_rtc_info *info = dev_get_drvdata(dev);
313         u8 data[info->regs->regs_count];
314         int ret = 0;
315
316         switch (info->device_type) {
317         case S5M8763X:
318                 s5m8763_tm_to_data(tm, data);
319                 break;
320         case S5M8767X:
321                 ret = s5m8767_tm_to_data(tm, data);
322                 break;
323         default:
324                 return -EINVAL;
325         }
326
327         if (ret < 0)
328                 return ret;
329
330         dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
331                 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
332                 tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
333
334         ret = regmap_raw_write(info->regmap, info->regs->time, data,
335                         info->regs->regs_count);
336         if (ret < 0)
337                 return ret;
338
339         ret = s5m8767_rtc_set_time_reg(info);
340
341         return ret;
342 }
343
344 static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
345 {
346         struct s5m_rtc_info *info = dev_get_drvdata(dev);
347         u8 data[info->regs->regs_count];
348         unsigned int val;
349         int ret, i;
350
351         ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
352                         info->regs->regs_count);
353         if (ret < 0)
354                 return ret;
355
356         switch (info->device_type) {
357         case S5M8763X:
358                 s5m8763_data_to_tm(data, &alrm->time);
359                 ret = regmap_read(info->regmap, S5M_ALARM0_CONF, &val);
360                 if (ret < 0)
361                         return ret;
362
363                 alrm->enabled = !!val;
364                 break;
365
366         case S5M8767X:
367                 s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
368                 alrm->enabled = 0;
369                 for (i = 0; i < info->regs->regs_count; i++) {
370                         if (data[i] & ALARM_ENABLE_MASK) {
371                                 alrm->enabled = 1;
372                                 break;
373                         }
374                 }
375                 break;
376
377         default:
378                 return -EINVAL;
379         }
380
381         dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
382                 1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
383                 alrm->time.tm_mday, alrm->time.tm_hour,
384                 alrm->time.tm_min, alrm->time.tm_sec,
385                 alrm->time.tm_wday);
386
387         ret = s5m_check_peding_alarm_interrupt(info, alrm);
388
389         return 0;
390 }
391
392 static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
393 {
394         u8 data[info->regs->regs_count];
395         int ret, i;
396         struct rtc_time tm;
397
398         ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
399                         info->regs->regs_count);
400         if (ret < 0)
401                 return ret;
402
403         s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
404         dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
405                 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
406                 tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
407
408         switch (info->device_type) {
409         case S5M8763X:
410                 ret = regmap_write(info->regmap, S5M_ALARM0_CONF, 0);
411                 break;
412
413         case S5M8767X:
414                 for (i = 0; i < info->regs->regs_count; i++)
415                         data[i] &= ~ALARM_ENABLE_MASK;
416
417                 ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
418                                 info->regs->regs_count);
419                 if (ret < 0)
420                         return ret;
421
422                 ret = s5m8767_rtc_set_alarm_reg(info);
423
424                 break;
425
426         default:
427                 return -EINVAL;
428         }
429
430         return ret;
431 }
432
433 static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
434 {
435         int ret;
436         u8 data[info->regs->regs_count];
437         u8 alarm0_conf;
438         struct rtc_time tm;
439
440         ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
441                         info->regs->regs_count);
442         if (ret < 0)
443                 return ret;
444
445         s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
446         dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
447                 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
448                 tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
449
450         switch (info->device_type) {
451         case S5M8763X:
452                 alarm0_conf = 0x77;
453                 ret = regmap_write(info->regmap, S5M_ALARM0_CONF, alarm0_conf);
454                 break;
455
456         case S5M8767X:
457                 data[RTC_SEC] |= ALARM_ENABLE_MASK;
458                 data[RTC_MIN] |= ALARM_ENABLE_MASK;
459                 data[RTC_HOUR] |= ALARM_ENABLE_MASK;
460                 data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK;
461                 if (data[RTC_DATE] & 0x1f)
462                         data[RTC_DATE] |= ALARM_ENABLE_MASK;
463                 if (data[RTC_MONTH] & 0xf)
464                         data[RTC_MONTH] |= ALARM_ENABLE_MASK;
465                 if (data[RTC_YEAR1] & 0x7f)
466                         data[RTC_YEAR1] |= ALARM_ENABLE_MASK;
467
468                 ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
469                                 info->regs->regs_count);
470                 if (ret < 0)
471                         return ret;
472                 ret = s5m8767_rtc_set_alarm_reg(info);
473
474                 break;
475
476         default:
477                 return -EINVAL;
478         }
479
480         return ret;
481 }
482
483 static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
484 {
485         struct s5m_rtc_info *info = dev_get_drvdata(dev);
486         u8 data[info->regs->regs_count];
487         int ret;
488
489         switch (info->device_type) {
490         case S5M8763X:
491                 s5m8763_tm_to_data(&alrm->time, data);
492                 break;
493
494         case S5M8767X:
495                 s5m8767_tm_to_data(&alrm->time, data);
496                 break;
497
498         default:
499                 return -EINVAL;
500         }
501
502         dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
503                 1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
504                 alrm->time.tm_mday, alrm->time.tm_hour, alrm->time.tm_min,
505                 alrm->time.tm_sec, alrm->time.tm_wday);
506
507         ret = s5m_rtc_stop_alarm(info);
508         if (ret < 0)
509                 return ret;
510
511         ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
512                         info->regs->regs_count);
513         if (ret < 0)
514                 return ret;
515
516         ret = s5m8767_rtc_set_alarm_reg(info);
517         if (ret < 0)
518                 return ret;
519
520         if (alrm->enabled)
521                 ret = s5m_rtc_start_alarm(info);
522
523         return ret;
524 }
525
526 static int s5m_rtc_alarm_irq_enable(struct device *dev,
527                                     unsigned int enabled)
528 {
529         struct s5m_rtc_info *info = dev_get_drvdata(dev);
530
531         if (enabled)
532                 return s5m_rtc_start_alarm(info);
533         else
534                 return s5m_rtc_stop_alarm(info);
535 }
536
537 static irqreturn_t s5m_rtc_alarm_irq(int irq, void *data)
538 {
539         struct s5m_rtc_info *info = data;
540
541         rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
542
543         return IRQ_HANDLED;
544 }
545
546 static const struct rtc_class_ops s5m_rtc_ops = {
547         .read_time = s5m_rtc_read_time,
548         .set_time = s5m_rtc_set_time,
549         .read_alarm = s5m_rtc_read_alarm,
550         .set_alarm = s5m_rtc_set_alarm,
551         .alarm_irq_enable = s5m_rtc_alarm_irq_enable,
552 };
553
554 static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable)
555 {
556         int ret;
557         ret = regmap_update_bits(info->regmap, info->regs->smpl_wtsr,
558                                  WTSR_ENABLE_MASK,
559                                  enable ? WTSR_ENABLE_MASK : 0);
560         if (ret < 0)
561                 dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n",
562                         __func__, ret);
563 }
564
565 static void s5m_rtc_enable_smpl(struct s5m_rtc_info *info, bool enable)
566 {
567         int ret;
568         ret = regmap_update_bits(info->regmap, info->regs->smpl_wtsr,
569                                  SMPL_ENABLE_MASK,
570                                  enable ? SMPL_ENABLE_MASK : 0);
571         if (ret < 0)
572                 dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n",
573                         __func__, ret);
574 }
575
576 static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
577 {
578         u8 data[2];
579         int ret;
580
581         /* UDR update time. Default of 7.32 ms is too long. */
582         ret = regmap_update_bits(info->regmap, S5M_RTC_UDR_CON,
583                         S5M_RTC_UDR_T_MASK, S5M_RTC_UDR_T_450_US);
584         if (ret < 0)
585                 dev_err(info->dev, "%s: fail to change UDR time: %d\n",
586                                 __func__, ret);
587
588         /* Set RTC control register : Binary mode, 24hour mode */
589         data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
590         data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
591
592         info->rtc_24hr_mode = 1;
593         ret = regmap_raw_write(info->regmap, S5M_ALARM0_CONF, data, 2);
594         if (ret < 0) {
595                 dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
596                         __func__, ret);
597                 return ret;
598         }
599
600         return ret;
601 }
602
603 static int s5m_rtc_probe(struct platform_device *pdev)
604 {
605         struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent);
606         struct sec_platform_data *pdata = s5m87xx->pdata;
607         struct s5m_rtc_info *info;
608         const struct regmap_config *regmap_cfg;
609         int ret;
610
611         if (!pdata) {
612                 dev_err(pdev->dev.parent, "Platform data not supplied\n");
613                 return -ENODEV;
614         }
615
616         info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
617         if (!info)
618                 return -ENOMEM;
619
620         switch (pdata->device_type) {
621         case S2MPS14X:
622                 regmap_cfg = &s2mps14_rtc_regmap_config;
623                 break;
624         case S5M8763X:
625                 regmap_cfg = &s5m_rtc_regmap_config;
626                 info->regs = &s5m_rtc_regs;
627                 break;
628         case S5M8767X:
629                 regmap_cfg = &s5m_rtc_regmap_config;
630                 info->regs = &s5m_rtc_regs;
631                 break;
632         default:
633                 dev_err(&pdev->dev, "Device type is not supported by RTC driver\n");
634                 return -ENODEV;
635         }
636
637         info->i2c = i2c_new_dummy(s5m87xx->i2c->adapter, RTC_I2C_ADDR);
638         if (!info->i2c) {
639                 dev_err(&pdev->dev, "Failed to allocate I2C for RTC\n");
640                 return -ENODEV;
641         }
642
643         info->regmap = devm_regmap_init_i2c(info->i2c, regmap_cfg);
644         if (IS_ERR(info->regmap)) {
645                 ret = PTR_ERR(info->regmap);
646                 dev_err(&pdev->dev, "Failed to allocate RTC register map: %d\n",
647                                 ret);
648                 goto err;
649         }
650
651         info->dev = &pdev->dev;
652         info->s5m87xx = s5m87xx;
653         info->device_type = s5m87xx->device_type;
654         info->wtsr_smpl = s5m87xx->wtsr_smpl;
655
656         switch (pdata->device_type) {
657         case S5M8763X:
658                 info->irq = regmap_irq_get_virq(s5m87xx->irq_data,
659                                 S5M8763_IRQ_ALARM0);
660                 break;
661
662         case S5M8767X:
663                 info->irq = regmap_irq_get_virq(s5m87xx->irq_data,
664                                 S5M8767_IRQ_RTCA1);
665                 break;
666
667         default:
668                 ret = -EINVAL;
669                 dev_err(&pdev->dev, "Unsupported device type: %d\n", ret);
670                 goto err;
671         }
672
673         platform_set_drvdata(pdev, info);
674
675         ret = s5m8767_rtc_init_reg(info);
676
677         if (info->wtsr_smpl) {
678                 s5m_rtc_enable_wtsr(info, true);
679                 s5m_rtc_enable_smpl(info, true);
680         }
681
682         device_init_wakeup(&pdev->dev, 1);
683
684         info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc",
685                                                  &s5m_rtc_ops, THIS_MODULE);
686
687         if (IS_ERR(info->rtc_dev)) {
688                 ret = PTR_ERR(info->rtc_dev);
689                 goto err;
690         }
691
692         ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
693                                         s5m_rtc_alarm_irq, 0, "rtc-alarm0",
694                                         info);
695         if (ret < 0) {
696                 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
697                         info->irq, ret);
698                 goto err;
699         }
700
701         return 0;
702
703 err:
704         i2c_unregister_device(info->i2c);
705
706         return ret;
707 }
708
709 static void s5m_rtc_shutdown(struct platform_device *pdev)
710 {
711         struct s5m_rtc_info *info = platform_get_drvdata(pdev);
712         int i;
713         unsigned int val = 0;
714         if (info->wtsr_smpl) {
715                 for (i = 0; i < 3; i++) {
716                         s5m_rtc_enable_wtsr(info, false);
717                         regmap_read(info->regmap, info->regs->smpl_wtsr, &val);
718                         pr_debug("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val);
719                         if (val & WTSR_ENABLE_MASK)
720                                 pr_emerg("%s: fail to disable WTSR\n",
721                                          __func__);
722                         else {
723                                 pr_info("%s: success to disable WTSR\n",
724                                         __func__);
725                                 break;
726                         }
727                 }
728         }
729         /* Disable SMPL when power off */
730         s5m_rtc_enable_smpl(info, false);
731 }
732
733 static int s5m_rtc_remove(struct platform_device *pdev)
734 {
735         struct s5m_rtc_info *info = platform_get_drvdata(pdev);
736
737         /* Perform also all shutdown steps when removing */
738         s5m_rtc_shutdown(pdev);
739         i2c_unregister_device(info->i2c);
740
741         return 0;
742 }
743
744 #ifdef CONFIG_PM_SLEEP
745 static int s5m_rtc_resume(struct device *dev)
746 {
747         struct s5m_rtc_info *info = dev_get_drvdata(dev);
748         int ret = 0;
749
750         if (device_may_wakeup(dev))
751                 ret = disable_irq_wake(info->irq);
752
753         return ret;
754 }
755
756 static int s5m_rtc_suspend(struct device *dev)
757 {
758         struct s5m_rtc_info *info = dev_get_drvdata(dev);
759         int ret = 0;
760
761         if (device_may_wakeup(dev))
762                 ret = enable_irq_wake(info->irq);
763
764         return ret;
765 }
766 #endif /* CONFIG_PM_SLEEP */
767
768 static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume);
769
770 static const struct platform_device_id s5m_rtc_id[] = {
771         { "s5m-rtc", 0 },
772 };
773
774 static struct platform_driver s5m_rtc_driver = {
775         .driver         = {
776                 .name   = "s5m-rtc",
777                 .owner  = THIS_MODULE,
778                 .pm     = &s5m_rtc_pm_ops,
779         },
780         .probe          = s5m_rtc_probe,
781         .remove         = s5m_rtc_remove,
782         .shutdown       = s5m_rtc_shutdown,
783         .id_table       = s5m_rtc_id,
784 };
785
786 module_platform_driver(s5m_rtc_driver);
787
788 /* Module information */
789 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
790 MODULE_DESCRIPTION("Samsung S5M RTC driver");
791 MODULE_LICENSE("GPL");
792 MODULE_ALIAS("platform:s5m-rtc");