2 * Copyright (c) 2013 Samsung Electronics Co., Ltd
3 * http://www.samsung.com
5 * Copyright (C) 2013 Google, Inc
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.
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.
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>
32 * Maximum number of retries for checking changes in UDR field
33 * of SEC_RTC_UDR_CON register (to limit possible endless loop).
35 * After writing to RTC registers (setting time or alarm) read the UDR field
36 * in SEC_RTC_UDR_CON register. UDR is auto-cleared when data have
39 #define UDR_READ_RETRY_CNT 5
43 struct sec_pmic_dev
*s5m87xx
;
44 struct regmap
*regmap
;
45 struct rtc_device
*rtc_dev
;
52 static void s5m8767_data_to_tm(u8
*data
, struct rtc_time
*tm
,
55 tm
->tm_sec
= data
[RTC_SEC
] & 0x7f;
56 tm
->tm_min
= data
[RTC_MIN
] & 0x7f;
58 tm
->tm_hour
= data
[RTC_HOUR
] & 0x1f;
60 tm
->tm_hour
= data
[RTC_HOUR
] & 0x0f;
61 if (data
[RTC_HOUR
] & HOUR_PM_MASK
)
65 tm
->tm_wday
= ffs(data
[RTC_WEEKDAY
] & 0x7f);
66 tm
->tm_mday
= data
[RTC_DATE
] & 0x1f;
67 tm
->tm_mon
= (data
[RTC_MONTH
] & 0x0f) - 1;
68 tm
->tm_year
= (data
[RTC_YEAR1
] & 0x7f) + 100;
73 static int s5m8767_tm_to_data(struct rtc_time
*tm
, u8
*data
)
75 data
[RTC_SEC
] = tm
->tm_sec
;
76 data
[RTC_MIN
] = tm
->tm_min
;
78 if (tm
->tm_hour
>= 12)
79 data
[RTC_HOUR
] = tm
->tm_hour
| HOUR_PM_MASK
;
81 data
[RTC_HOUR
] = tm
->tm_hour
& ~HOUR_PM_MASK
;
83 data
[RTC_WEEKDAY
] = 1 << tm
->tm_wday
;
84 data
[RTC_DATE
] = tm
->tm_mday
;
85 data
[RTC_MONTH
] = tm
->tm_mon
+ 1;
86 data
[RTC_YEAR1
] = tm
->tm_year
> 100 ? (tm
->tm_year
- 100) : 0;
88 if (tm
->tm_year
< 100) {
89 pr_err("s5m8767 RTC cannot handle the year %d.\n",
98 * Read RTC_UDR_CON register and wait till UDR field is cleared.
99 * This indicates that time/alarm update ended.
101 static inline int s5m8767_wait_for_udr_update(struct s5m_rtc_info
*info
)
103 int ret
, retry
= UDR_READ_RETRY_CNT
;
107 ret
= regmap_read(info
->regmap
, SEC_RTC_UDR_CON
, &data
);
108 } while (--retry
&& (data
& RTC_UDR_MASK
) && !ret
);
111 dev_err(info
->dev
, "waiting for UDR update, reached max number of retries\n");
116 static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info
*info
)
121 ret
= regmap_read(info
->regmap
, SEC_RTC_UDR_CON
, &data
);
123 dev_err(info
->dev
, "failed to read update reg(%d)\n", ret
);
127 data
|= RTC_TIME_EN_MASK
;
128 data
|= RTC_UDR_MASK
;
130 ret
= regmap_write(info
->regmap
, SEC_RTC_UDR_CON
, data
);
132 dev_err(info
->dev
, "failed to write update reg(%d)\n", ret
);
136 ret
= s5m8767_wait_for_udr_update(info
);
141 static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info
*info
)
146 ret
= regmap_read(info
->regmap
, SEC_RTC_UDR_CON
, &data
);
148 dev_err(info
->dev
, "%s: fail to read update reg(%d)\n",
153 data
&= ~RTC_TIME_EN_MASK
;
154 data
|= RTC_UDR_MASK
;
156 ret
= regmap_write(info
->regmap
, SEC_RTC_UDR_CON
, data
);
158 dev_err(info
->dev
, "%s: fail to write update reg(%d)\n",
163 ret
= s5m8767_wait_for_udr_update(info
);
168 static void s5m8763_data_to_tm(u8
*data
, struct rtc_time
*tm
)
170 tm
->tm_sec
= bcd2bin(data
[RTC_SEC
]);
171 tm
->tm_min
= bcd2bin(data
[RTC_MIN
]);
173 if (data
[RTC_HOUR
] & HOUR_12
) {
174 tm
->tm_hour
= bcd2bin(data
[RTC_HOUR
] & 0x1f);
175 if (data
[RTC_HOUR
] & HOUR_PM
)
178 tm
->tm_hour
= bcd2bin(data
[RTC_HOUR
] & 0x3f);
181 tm
->tm_wday
= data
[RTC_WEEKDAY
] & 0x07;
182 tm
->tm_mday
= bcd2bin(data
[RTC_DATE
]);
183 tm
->tm_mon
= bcd2bin(data
[RTC_MONTH
]);
184 tm
->tm_year
= bcd2bin(data
[RTC_YEAR1
]) + bcd2bin(data
[RTC_YEAR2
]) * 100;
188 static void s5m8763_tm_to_data(struct rtc_time
*tm
, u8
*data
)
190 data
[RTC_SEC
] = bin2bcd(tm
->tm_sec
);
191 data
[RTC_MIN
] = bin2bcd(tm
->tm_min
);
192 data
[RTC_HOUR
] = bin2bcd(tm
->tm_hour
);
193 data
[RTC_WEEKDAY
] = tm
->tm_wday
;
194 data
[RTC_DATE
] = bin2bcd(tm
->tm_mday
);
195 data
[RTC_MONTH
] = bin2bcd(tm
->tm_mon
);
196 data
[RTC_YEAR1
] = bin2bcd(tm
->tm_year
% 100);
197 data
[RTC_YEAR2
] = bin2bcd((tm
->tm_year
+ 1900) / 100);
200 static int s5m_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
202 struct s5m_rtc_info
*info
= dev_get_drvdata(dev
);
206 ret
= regmap_bulk_read(info
->regmap
, SEC_RTC_SEC
, data
, 8);
210 switch (info
->device_type
) {
212 s5m8763_data_to_tm(data
, tm
);
216 s5m8767_data_to_tm(data
, tm
, info
->rtc_24hr_mode
);
223 dev_dbg(dev
, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__
,
224 1900 + tm
->tm_year
, 1 + tm
->tm_mon
, tm
->tm_mday
,
225 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
, tm
->tm_wday
);
227 return rtc_valid_tm(tm
);
230 static int s5m_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
232 struct s5m_rtc_info
*info
= dev_get_drvdata(dev
);
236 switch (info
->device_type
) {
238 s5m8763_tm_to_data(tm
, data
);
241 ret
= s5m8767_tm_to_data(tm
, data
);
250 dev_dbg(dev
, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__
,
251 1900 + tm
->tm_year
, 1 + tm
->tm_mon
, tm
->tm_mday
,
252 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
, tm
->tm_wday
);
254 ret
= regmap_raw_write(info
->regmap
, SEC_RTC_SEC
, data
, 8);
258 ret
= s5m8767_rtc_set_time_reg(info
);
263 static int s5m_rtc_read_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
265 struct s5m_rtc_info
*info
= dev_get_drvdata(dev
);
270 ret
= regmap_bulk_read(info
->regmap
, SEC_ALARM0_SEC
, data
, 8);
274 switch (info
->device_type
) {
276 s5m8763_data_to_tm(data
, &alrm
->time
);
277 ret
= regmap_read(info
->regmap
, SEC_ALARM0_CONF
, &val
);
281 alrm
->enabled
= !!val
;
283 ret
= regmap_read(info
->regmap
, SEC_RTC_STATUS
, &val
);
290 s5m8767_data_to_tm(data
, &alrm
->time
, info
->rtc_24hr_mode
);
291 dev_dbg(dev
, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__
,
292 1900 + alrm
->time
.tm_year
, 1 + alrm
->time
.tm_mon
,
293 alrm
->time
.tm_mday
, alrm
->time
.tm_hour
,
294 alrm
->time
.tm_min
, alrm
->time
.tm_sec
,
298 for (i
= 0; i
< 7; i
++) {
299 if (data
[i
] & ALARM_ENABLE_MASK
) {
306 ret
= regmap_read(info
->regmap
, SEC_RTC_STATUS
, &val
);
315 if (val
& ALARM0_STATUS
)
323 static int s5m_rtc_stop_alarm(struct s5m_rtc_info
*info
)
329 ret
= regmap_bulk_read(info
->regmap
, SEC_ALARM0_SEC
, data
, 8);
333 s5m8767_data_to_tm(data
, &tm
, info
->rtc_24hr_mode
);
334 dev_dbg(info
->dev
, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__
,
335 1900 + tm
.tm_year
, 1 + tm
.tm_mon
, tm
.tm_mday
,
336 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
, tm
.tm_wday
);
338 switch (info
->device_type
) {
340 ret
= regmap_write(info
->regmap
, SEC_ALARM0_CONF
, 0);
344 for (i
= 0; i
< 7; i
++)
345 data
[i
] &= ~ALARM_ENABLE_MASK
;
347 ret
= regmap_raw_write(info
->regmap
, SEC_ALARM0_SEC
, data
, 8);
351 ret
= s5m8767_rtc_set_alarm_reg(info
);
362 static int s5m_rtc_start_alarm(struct s5m_rtc_info
*info
)
369 ret
= regmap_bulk_read(info
->regmap
, SEC_ALARM0_SEC
, data
, 8);
373 s5m8767_data_to_tm(data
, &tm
, info
->rtc_24hr_mode
);
374 dev_dbg(info
->dev
, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__
,
375 1900 + tm
.tm_year
, 1 + tm
.tm_mon
, tm
.tm_mday
,
376 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
, tm
.tm_wday
);
378 switch (info
->device_type
) {
381 ret
= regmap_write(info
->regmap
, SEC_ALARM0_CONF
, alarm0_conf
);
385 data
[RTC_SEC
] |= ALARM_ENABLE_MASK
;
386 data
[RTC_MIN
] |= ALARM_ENABLE_MASK
;
387 data
[RTC_HOUR
] |= ALARM_ENABLE_MASK
;
388 data
[RTC_WEEKDAY
] &= ~ALARM_ENABLE_MASK
;
389 if (data
[RTC_DATE
] & 0x1f)
390 data
[RTC_DATE
] |= ALARM_ENABLE_MASK
;
391 if (data
[RTC_MONTH
] & 0xf)
392 data
[RTC_MONTH
] |= ALARM_ENABLE_MASK
;
393 if (data
[RTC_YEAR1
] & 0x7f)
394 data
[RTC_YEAR1
] |= ALARM_ENABLE_MASK
;
396 ret
= regmap_raw_write(info
->regmap
, SEC_ALARM0_SEC
, data
, 8);
399 ret
= s5m8767_rtc_set_alarm_reg(info
);
410 static int s5m_rtc_set_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
412 struct s5m_rtc_info
*info
= dev_get_drvdata(dev
);
416 switch (info
->device_type
) {
418 s5m8763_tm_to_data(&alrm
->time
, data
);
422 s5m8767_tm_to_data(&alrm
->time
, data
);
429 dev_dbg(dev
, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__
,
430 1900 + alrm
->time
.tm_year
, 1 + alrm
->time
.tm_mon
,
431 alrm
->time
.tm_mday
, alrm
->time
.tm_hour
, alrm
->time
.tm_min
,
432 alrm
->time
.tm_sec
, alrm
->time
.tm_wday
);
434 ret
= s5m_rtc_stop_alarm(info
);
438 ret
= regmap_raw_write(info
->regmap
, SEC_ALARM0_SEC
, data
, 8);
442 ret
= s5m8767_rtc_set_alarm_reg(info
);
447 ret
= s5m_rtc_start_alarm(info
);
452 static int s5m_rtc_alarm_irq_enable(struct device
*dev
,
453 unsigned int enabled
)
455 struct s5m_rtc_info
*info
= dev_get_drvdata(dev
);
458 return s5m_rtc_start_alarm(info
);
460 return s5m_rtc_stop_alarm(info
);
463 static irqreturn_t
s5m_rtc_alarm_irq(int irq
, void *data
)
465 struct s5m_rtc_info
*info
= data
;
467 rtc_update_irq(info
->rtc_dev
, 1, RTC_IRQF
| RTC_AF
);
472 static const struct rtc_class_ops s5m_rtc_ops
= {
473 .read_time
= s5m_rtc_read_time
,
474 .set_time
= s5m_rtc_set_time
,
475 .read_alarm
= s5m_rtc_read_alarm
,
476 .set_alarm
= s5m_rtc_set_alarm
,
477 .alarm_irq_enable
= s5m_rtc_alarm_irq_enable
,
480 static void s5m_rtc_enable_wtsr(struct s5m_rtc_info
*info
, bool enable
)
483 ret
= regmap_update_bits(info
->regmap
, SEC_WTSR_SMPL_CNTL
,
485 enable
? WTSR_ENABLE_MASK
: 0);
487 dev_err(info
->dev
, "%s: fail to update WTSR reg(%d)\n",
491 static void s5m_rtc_enable_smpl(struct s5m_rtc_info
*info
, bool enable
)
494 ret
= regmap_update_bits(info
->regmap
, SEC_WTSR_SMPL_CNTL
,
496 enable
? SMPL_ENABLE_MASK
: 0);
498 dev_err(info
->dev
, "%s: fail to update SMPL reg(%d)\n",
502 static int s5m8767_rtc_init_reg(struct s5m_rtc_info
*info
)
505 unsigned int tp_read
;
509 ret
= regmap_read(info
->regmap
, SEC_RTC_UDR_CON
, &tp_read
);
511 dev_err(info
->dev
, "%s: fail to read control reg(%d)\n",
516 /* Set RTC control register : Binary mode, 24hour mode */
517 data
[0] = (1 << BCD_EN_SHIFT
) | (1 << MODEL24_SHIFT
);
518 data
[1] = (0 << BCD_EN_SHIFT
) | (1 << MODEL24_SHIFT
);
520 info
->rtc_24hr_mode
= 1;
521 ret
= regmap_raw_write(info
->regmap
, SEC_ALARM0_CONF
, data
, 2);
523 dev_err(info
->dev
, "%s: fail to write controlm reg(%d)\n",
528 /* In first boot time, Set rtc time to 1/1/2012 00:00:00(SUN) */
529 if ((tp_read
& RTC_TCON_MASK
) == 0) {
530 dev_dbg(info
->dev
, "rtc init\n");
540 ret
= s5m_rtc_set_time(info
->dev
, &tm
);
543 ret
= regmap_update_bits(info
->regmap
, SEC_RTC_UDR_CON
,
544 RTC_TCON_MASK
, tp_read
| RTC_TCON_MASK
);
546 dev_err(info
->dev
, "%s: fail to update TCON reg(%d)\n",
552 static int s5m_rtc_probe(struct platform_device
*pdev
)
554 struct sec_pmic_dev
*s5m87xx
= dev_get_drvdata(pdev
->dev
.parent
);
555 struct sec_platform_data
*pdata
= s5m87xx
->pdata
;
556 struct s5m_rtc_info
*info
;
560 dev_err(pdev
->dev
.parent
, "Platform data not supplied\n");
564 info
= devm_kzalloc(&pdev
->dev
, sizeof(*info
), GFP_KERNEL
);
568 info
->dev
= &pdev
->dev
;
569 info
->s5m87xx
= s5m87xx
;
570 info
->regmap
= s5m87xx
->regmap_rtc
;
571 info
->device_type
= s5m87xx
->device_type
;
572 info
->wtsr_smpl
= s5m87xx
->wtsr_smpl
;
574 switch (pdata
->device_type
) {
576 info
->irq
= regmap_irq_get_virq(s5m87xx
->irq_data
,
581 info
->irq
= regmap_irq_get_virq(s5m87xx
->irq_data
,
587 dev_err(&pdev
->dev
, "Unsupported device type: %d\n", ret
);
591 platform_set_drvdata(pdev
, info
);
593 ret
= s5m8767_rtc_init_reg(info
);
595 if (info
->wtsr_smpl
) {
596 s5m_rtc_enable_wtsr(info
, true);
597 s5m_rtc_enable_smpl(info
, true);
600 device_init_wakeup(&pdev
->dev
, 1);
602 info
->rtc_dev
= devm_rtc_device_register(&pdev
->dev
, "s5m-rtc",
603 &s5m_rtc_ops
, THIS_MODULE
);
605 if (IS_ERR(info
->rtc_dev
))
606 return PTR_ERR(info
->rtc_dev
);
608 ret
= devm_request_threaded_irq(&pdev
->dev
, info
->irq
, NULL
,
609 s5m_rtc_alarm_irq
, 0, "rtc-alarm0",
612 dev_err(&pdev
->dev
, "Failed to request alarm IRQ: %d: %d\n",
618 static void s5m_rtc_shutdown(struct platform_device
*pdev
)
620 struct s5m_rtc_info
*info
= platform_get_drvdata(pdev
);
622 unsigned int val
= 0;
623 if (info
->wtsr_smpl
) {
624 for (i
= 0; i
< 3; i
++) {
625 s5m_rtc_enable_wtsr(info
, false);
626 regmap_read(info
->regmap
, SEC_WTSR_SMPL_CNTL
, &val
);
627 pr_debug("%s: WTSR_SMPL reg(0x%02x)\n", __func__
, val
);
628 if (val
& WTSR_ENABLE_MASK
)
629 pr_emerg("%s: fail to disable WTSR\n",
632 pr_info("%s: success to disable WTSR\n",
638 /* Disable SMPL when power off */
639 s5m_rtc_enable_smpl(info
, false);
642 #ifdef CONFIG_PM_SLEEP
643 static int s5m_rtc_resume(struct device
*dev
)
645 struct s5m_rtc_info
*info
= dev_get_drvdata(dev
);
648 if (device_may_wakeup(dev
))
649 ret
= disable_irq_wake(info
->irq
);
654 static int s5m_rtc_suspend(struct device
*dev
)
656 struct s5m_rtc_info
*info
= dev_get_drvdata(dev
);
659 if (device_may_wakeup(dev
))
660 ret
= enable_irq_wake(info
->irq
);
664 #endif /* CONFIG_PM_SLEEP */
666 static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops
, s5m_rtc_suspend
, s5m_rtc_resume
);
668 static const struct platform_device_id s5m_rtc_id
[] = {
672 static struct platform_driver s5m_rtc_driver
= {
675 .owner
= THIS_MODULE
,
676 .pm
= &s5m_rtc_pm_ops
,
678 .probe
= s5m_rtc_probe
,
679 .shutdown
= s5m_rtc_shutdown
,
680 .id_table
= s5m_rtc_id
,
683 module_platform_driver(s5m_rtc_driver
);
685 /* Module information */
686 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
687 MODULE_DESCRIPTION("Samsung S5M RTC driver");
688 MODULE_LICENSE("GPL");
689 MODULE_ALIAS("platform:s5m-rtc");