2 * Real time clock driver for DA9055
4 * Copyright(c) 2012 Dialog Semiconductor Ltd.
6 * Author: Dajun Dajun Chen <dajun.chen@diasemi.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/rtc.h>
19 #include <linux/mfd/da9055/core.h>
20 #include <linux/mfd/da9055/reg.h>
21 #include <linux/mfd/da9055/pdata.h>
24 struct rtc_device
*rtc
;
25 struct da9055
*da9055
;
29 static int da9055_rtc_enable_alarm(struct da9055_rtc
*rtc
, bool enable
)
33 ret
= da9055_reg_update(rtc
->da9055
, DA9055_REG_ALARM_Y
,
37 dev_err(rtc
->da9055
->dev
, "Failed to enable ALM: %d\n",
39 rtc
->alarm_enable
= 1;
41 ret
= da9055_reg_update(rtc
->da9055
, DA9055_REG_ALARM_Y
,
42 DA9055_RTC_ALM_EN
, 0);
44 dev_err(rtc
->da9055
->dev
,
45 "Failed to disable ALM: %d\n", ret
);
46 rtc
->alarm_enable
= 0;
51 static irqreturn_t
da9055_rtc_alm_irq(int irq
, void *data
)
53 struct da9055_rtc
*rtc
= data
;
55 da9055_rtc_enable_alarm(rtc
, 0);
56 rtc_update_irq(rtc
->rtc
, 1, RTC_IRQF
| RTC_AF
);
61 static int da9055_read_alarm(struct da9055
*da9055
, struct rtc_time
*rtc_tm
)
66 ret
= da9055_group_read(da9055
, DA9055_REG_ALARM_MI
, 5, v
);
68 dev_err(da9055
->dev
, "Failed to group read ALM: %d\n", ret
);
72 rtc_tm
->tm_year
= (v
[4] & DA9055_RTC_ALM_YEAR
) + 100;
73 rtc_tm
->tm_mon
= (v
[3] & DA9055_RTC_ALM_MONTH
) - 1;
74 rtc_tm
->tm_mday
= v
[2] & DA9055_RTC_ALM_DAY
;
75 rtc_tm
->tm_hour
= v
[1] & DA9055_RTC_ALM_HOUR
;
76 rtc_tm
->tm_min
= v
[0] & DA9055_RTC_ALM_MIN
;
79 return rtc_valid_tm(rtc_tm
);
82 static int da9055_set_alarm(struct da9055
*da9055
, struct rtc_time
*rtc_tm
)
87 rtc_tm
->tm_year
-= 100;
90 ret
= da9055_reg_update(da9055
, DA9055_REG_ALARM_MI
,
91 DA9055_RTC_ALM_MIN
, rtc_tm
->tm_min
);
93 dev_err(da9055
->dev
, "Failed to write ALRM MIN: %d\n", ret
);
97 v
[0] = rtc_tm
->tm_hour
;
98 v
[1] = rtc_tm
->tm_mday
;
100 ret
= da9055_group_write(da9055
, DA9055_REG_ALARM_H
, 2, v
);
104 ret
= da9055_reg_update(da9055
, DA9055_REG_ALARM_MO
,
105 DA9055_RTC_ALM_MONTH
, rtc_tm
->tm_mon
);
107 dev_err(da9055
->dev
, "Failed to write ALM Month:%d\n", ret
);
109 ret
= da9055_reg_update(da9055
, DA9055_REG_ALARM_Y
,
110 DA9055_RTC_ALM_YEAR
, rtc_tm
->tm_year
);
112 dev_err(da9055
->dev
, "Failed to write ALM Year:%d\n", ret
);
117 static int da9055_rtc_get_alarm_status(struct da9055
*da9055
)
121 ret
= da9055_reg_read(da9055
, DA9055_REG_ALARM_Y
);
123 dev_err(da9055
->dev
, "Failed to read ALM: %d\n", ret
);
126 ret
&= DA9055_RTC_ALM_EN
;
127 return (ret
> 0) ? 1 : 0;
130 static int da9055_rtc_read_time(struct device
*dev
, struct rtc_time
*rtc_tm
)
132 struct da9055_rtc
*rtc
= dev_get_drvdata(dev
);
136 ret
= da9055_reg_read(rtc
->da9055
, DA9055_REG_COUNT_S
);
141 * Registers are only valid when RTC_READ
142 * status bit is asserted
144 if (!(ret
& DA9055_RTC_READ
))
147 ret
= da9055_group_read(rtc
->da9055
, DA9055_REG_COUNT_S
, 6, v
);
149 dev_err(rtc
->da9055
->dev
, "Failed to read RTC time : %d\n",
154 rtc_tm
->tm_year
= (v
[5] & DA9055_RTC_YEAR
) + 100;
155 rtc_tm
->tm_mon
= (v
[4] & DA9055_RTC_MONTH
) - 1;
156 rtc_tm
->tm_mday
= v
[3] & DA9055_RTC_DAY
;
157 rtc_tm
->tm_hour
= v
[2] & DA9055_RTC_HOUR
;
158 rtc_tm
->tm_min
= v
[1] & DA9055_RTC_MIN
;
159 rtc_tm
->tm_sec
= v
[0] & DA9055_RTC_SEC
;
164 static int da9055_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
166 struct da9055_rtc
*rtc
;
169 rtc
= dev_get_drvdata(dev
);
175 v
[4] = tm
->tm_mon
+ 1;
176 v
[5] = tm
->tm_year
- 100;
178 return da9055_group_write(rtc
->da9055
, DA9055_REG_COUNT_S
, 6, v
);
181 static int da9055_rtc_read_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
184 struct rtc_time
*tm
= &alrm
->time
;
185 struct da9055_rtc
*rtc
= dev_get_drvdata(dev
);
187 ret
= da9055_read_alarm(rtc
->da9055
, tm
);
192 alrm
->enabled
= da9055_rtc_get_alarm_status(rtc
->da9055
);
197 static int da9055_rtc_set_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
200 struct rtc_time
*tm
= &alrm
->time
;
201 struct da9055_rtc
*rtc
= dev_get_drvdata(dev
);
203 ret
= da9055_rtc_enable_alarm(rtc
, 0);
207 ret
= da9055_set_alarm(rtc
->da9055
, tm
);
211 ret
= da9055_rtc_enable_alarm(rtc
, 1);
216 static int da9055_rtc_alarm_irq_enable(struct device
*dev
, unsigned int enabled
)
218 struct da9055_rtc
*rtc
= dev_get_drvdata(dev
);
220 return da9055_rtc_enable_alarm(rtc
, enabled
);
223 static const struct rtc_class_ops da9055_rtc_ops
= {
224 .read_time
= da9055_rtc_read_time
,
225 .set_time
= da9055_rtc_set_time
,
226 .read_alarm
= da9055_rtc_read_alarm
,
227 .set_alarm
= da9055_rtc_set_alarm
,
228 .alarm_irq_enable
= da9055_rtc_alarm_irq_enable
,
231 static int da9055_rtc_device_init(struct da9055
*da9055
,
232 struct da9055_pdata
*pdata
)
236 /* Enable RTC and the internal Crystal */
237 ret
= da9055_reg_update(da9055
, DA9055_REG_CONTROL_B
,
238 DA9055_RTC_EN
, DA9055_RTC_EN
);
241 ret
= da9055_reg_update(da9055
, DA9055_REG_EN_32K
,
242 DA9055_CRYSTAL_EN
, DA9055_CRYSTAL_EN
);
246 /* Enable RTC in Power Down mode */
247 ret
= da9055_reg_update(da9055
, DA9055_REG_CONTROL_B
,
248 DA9055_RTC_MODE_PD
, DA9055_RTC_MODE_PD
);
252 /* Enable RTC in Reset mode */
253 if (pdata
&& pdata
->reset_enable
) {
254 ret
= da9055_reg_update(da9055
, DA9055_REG_CONTROL_B
,
256 DA9055_RTC_MODE_SD
<<
257 DA9055_RTC_MODE_SD_SHIFT
);
262 /* Disable the RTC TICK ALM */
263 ret
= da9055_reg_update(da9055
, DA9055_REG_ALARM_MO
,
264 DA9055_RTC_TICK_WAKE_MASK
, 0);
271 static int da9055_rtc_probe(struct platform_device
*pdev
)
273 struct da9055_rtc
*rtc
;
274 struct da9055_pdata
*pdata
= NULL
;
277 rtc
= devm_kzalloc(&pdev
->dev
, sizeof(struct da9055_rtc
), GFP_KERNEL
);
281 rtc
->da9055
= dev_get_drvdata(pdev
->dev
.parent
);
282 pdata
= dev_get_platdata(rtc
->da9055
->dev
);
283 platform_set_drvdata(pdev
, rtc
);
285 ret
= da9055_rtc_device_init(rtc
->da9055
, pdata
);
289 ret
= da9055_reg_read(rtc
->da9055
, DA9055_REG_ALARM_Y
);
293 if (ret
& DA9055_RTC_ALM_EN
)
294 rtc
->alarm_enable
= 1;
296 device_init_wakeup(&pdev
->dev
, 1);
298 rtc
->rtc
= devm_rtc_device_register(&pdev
->dev
, pdev
->name
,
299 &da9055_rtc_ops
, THIS_MODULE
);
300 if (IS_ERR(rtc
->rtc
)) {
301 ret
= PTR_ERR(rtc
->rtc
);
305 alm_irq
= platform_get_irq_byname(pdev
, "ALM");
309 ret
= devm_request_threaded_irq(&pdev
->dev
, alm_irq
, NULL
,
311 IRQF_TRIGGER_HIGH
| IRQF_ONESHOT
,
314 dev_err(rtc
->da9055
->dev
, "irq registration failed: %d\n", ret
);
322 /* Turn off the alarm if it should not be a wake source. */
323 static int da9055_rtc_suspend(struct device
*dev
)
325 struct platform_device
*pdev
= to_platform_device(dev
);
326 struct da9055_rtc
*rtc
= dev_get_drvdata(&pdev
->dev
);
329 if (!device_may_wakeup(&pdev
->dev
)) {
330 /* Disable the ALM IRQ */
331 ret
= da9055_rtc_enable_alarm(rtc
, 0);
333 dev_err(&pdev
->dev
, "Failed to disable RTC ALM\n");
339 /* Enable the alarm if it should be enabled (in case it was disabled to
340 * prevent use as a wake source).
342 static int da9055_rtc_resume(struct device
*dev
)
344 struct platform_device
*pdev
= to_platform_device(dev
);
345 struct da9055_rtc
*rtc
= dev_get_drvdata(&pdev
->dev
);
348 if (!device_may_wakeup(&pdev
->dev
)) {
349 if (rtc
->alarm_enable
) {
350 ret
= da9055_rtc_enable_alarm(rtc
, 1);
353 "Failed to restart RTC ALM\n");
360 /* Unconditionally disable the alarm */
361 static int da9055_rtc_freeze(struct device
*dev
)
363 struct platform_device
*pdev
= to_platform_device(dev
);
364 struct da9055_rtc
*rtc
= dev_get_drvdata(&pdev
->dev
);
367 ret
= da9055_rtc_enable_alarm(rtc
, 0);
369 dev_err(&pdev
->dev
, "Failed to freeze RTC ALMs\n");
375 #define da9055_rtc_suspend NULL
376 #define da9055_rtc_resume NULL
377 #define da9055_rtc_freeze NULL
380 static const struct dev_pm_ops da9055_rtc_pm_ops
= {
381 .suspend
= da9055_rtc_suspend
,
382 .resume
= da9055_rtc_resume
,
384 .freeze
= da9055_rtc_freeze
,
385 .thaw
= da9055_rtc_resume
,
386 .restore
= da9055_rtc_resume
,
388 .poweroff
= da9055_rtc_suspend
,
391 static struct platform_driver da9055_rtc_driver
= {
392 .probe
= da9055_rtc_probe
,
394 .name
= "da9055-rtc",
395 .pm
= &da9055_rtc_pm_ops
,
399 module_platform_driver(da9055_rtc_driver
);
401 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
402 MODULE_DESCRIPTION("RTC driver for Dialog DA9055 PMIC");
403 MODULE_LICENSE("GPL");
404 MODULE_ALIAS("platform:da9055-rtc");