rtc: as3722: add shutdown support
[linux-3.10.git] / drivers / rtc / rtc-as3722.c
1 /*
2  * rtc-as3722.c - Real Time Clock driver for ams AS3722 PMICs
3  *
4  * Copyright (C) 2013 ams AG
5  * Copyright (c) 2013-2015, NVIDIA Corporation. All rights reserved.
6  *
7  * Author: Florian Lobmaier <florian.lobmaier@ams.com>
8  * Author: Laxman Dewangan <ldewangan@nvidia.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  *
24  */
25
26 #include <linux/bcd.h>
27 #include <linux/completion.h>
28 #include <linux/delay.h>
29 #include <linux/interrupt.h>
30 #include <linux/ioctl.h>
31 #include <linux/kernel.h>
32 #include <linux/module.h>
33 #include <linux/mfd/as3722.h>
34 #include <linux/platform_device.h>
35 #include <linux/rtc.h>
36 #include <linux/time.h>
37
38 #define AS3722_RTC_START_YEAR     2000
39 struct as3722_rtc {
40         struct rtc_device       *rtc;
41         struct device           *dev;
42         struct as3722           *as3722;
43         int                     alarm_irq;
44         bool                    irq_enable;
45 };
46
47 static void as3722_time_to_reg(u8 *rbuff, struct rtc_time *tm)
48 {
49         rbuff[0] = bin2bcd(tm->tm_sec);
50         rbuff[1] = bin2bcd(tm->tm_min);
51         rbuff[2] = bin2bcd(tm->tm_hour);
52         rbuff[3] = bin2bcd(tm->tm_mday);
53         rbuff[4] = bin2bcd(tm->tm_mon + 1);
54         rbuff[5] = bin2bcd(tm->tm_year - (AS3722_RTC_START_YEAR - 1900));
55 }
56
57 static void as3722_reg_to_time(u8 *rbuff, struct rtc_time *tm)
58 {
59         tm->tm_sec = bcd2bin(rbuff[0] & 0x7F);
60         tm->tm_min = bcd2bin(rbuff[1] & 0x7F);
61         tm->tm_hour = bcd2bin(rbuff[2] & 0x3F);
62         tm->tm_mday = bcd2bin(rbuff[3] & 0x3F);
63         tm->tm_mon = bcd2bin(rbuff[4] & 0x1F) - 1;
64         tm->tm_year = (AS3722_RTC_START_YEAR - 1900) + bcd2bin(rbuff[5] & 0x7F);
65         return;
66 }
67
68 static int as3722_rtc_read_time(struct device *dev, struct rtc_time *tm)
69 {
70         struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
71         struct as3722 *as3722 = as3722_rtc->as3722;
72         u8 as_time_array[6];
73         int ret;
74
75         ret = as3722_block_read(as3722, AS3722_RTC_SECOND_REG,
76                         6, as_time_array);
77         if (ret < 0) {
78                 dev_err(dev, "RTC_SECOND reg block read failed %d\n", ret);
79                 return ret;
80         }
81         as3722_reg_to_time(as_time_array, tm);
82         return 0;
83 }
84
85 static int as3722_rtc_set_time(struct device *dev, struct rtc_time *tm)
86 {
87         struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
88         struct as3722 *as3722 = as3722_rtc->as3722;
89         u8 as_time_array[6];
90         int ret;
91
92         if (tm->tm_year < (AS3722_RTC_START_YEAR - 1900))
93                 return -EINVAL;
94
95         as3722_time_to_reg(as_time_array, tm);
96         ret = as3722_block_write(as3722, AS3722_RTC_SECOND_REG, 6,
97                         as_time_array);
98         if (ret < 0)
99                 dev_err(dev, "RTC_SECOND reg block write failed %d\n", ret);
100         return ret;
101 }
102
103 static int as3722_rtc_alarm_irq_enable(struct device *dev,
104                 unsigned int enabled)
105 {
106         struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
107
108         if (enabled && !as3722_rtc->irq_enable) {
109                 enable_irq(as3722_rtc->alarm_irq);
110                 as3722_rtc->irq_enable = true;
111         } else if (!enabled && as3722_rtc->irq_enable)  {
112                 disable_irq(as3722_rtc->alarm_irq);
113                 as3722_rtc->irq_enable = false;
114         }
115         return 0;
116 }
117
118 static int as3722_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
119 {
120         struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
121         struct as3722 *as3722 = as3722_rtc->as3722;
122         u8 as_time_array[6];
123         int ret;
124
125         ret = as3722_block_read(as3722, AS3722_RTC_ALARM_SECOND_REG, 6,
126                         as_time_array);
127         if (ret < 0) {
128                 dev_err(dev, "RTC_ALARM_SECOND block read failed %d\n", ret);
129                 return ret;
130         }
131
132         as3722_reg_to_time(as_time_array, &alrm->time);
133         alrm->enabled = (as3722_rtc->irq_enable) ? 1 : 0;
134         return 0;
135 }
136
137 static int as3722_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
138 {
139         struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
140         struct as3722 *as3722 = as3722_rtc->as3722;
141         u8 as_time_array[6];
142         int ret;
143
144         if (alrm->time.tm_year < (AS3722_RTC_START_YEAR - 1900))
145                 return -EINVAL;
146
147         ret = as3722_rtc_alarm_irq_enable(dev, 0);
148         if (ret < 0) {
149                 dev_err(dev, "Disable RTC alarm failed\n");
150                 return ret;
151         }
152
153         as3722_time_to_reg(as_time_array, &alrm->time);
154         ret = as3722_block_write(as3722, AS3722_RTC_ALARM_SECOND_REG, 6,
155                         as_time_array);
156         if (ret < 0) {
157                 dev_err(dev, "RTC_ALARM_SECOND block write failed %d\n", ret);
158                 return ret;
159         }
160
161         if (alrm->enabled)
162                 ret = as3722_rtc_alarm_irq_enable(dev, alrm->enabled);
163         return ret;
164 }
165
166 static irqreturn_t as3722_alarm_irq(int irq, void *data)
167 {
168         struct as3722_rtc *as3722_rtc = data;
169
170         rtc_update_irq(as3722_rtc->rtc, 1, RTC_IRQF | RTC_AF);
171         return IRQ_HANDLED;
172 }
173
174 static const struct rtc_class_ops as3722_rtc_ops = {
175         .read_time = as3722_rtc_read_time,
176         .set_time = as3722_rtc_set_time,
177         .read_alarm = as3722_rtc_read_alarm,
178         .set_alarm = as3722_rtc_set_alarm,
179         .alarm_irq_enable = as3722_rtc_alarm_irq_enable,
180 };
181
182 static int as3722_rtc_probe(struct platform_device *pdev)
183 {
184         struct as3722 *as3722 = dev_get_drvdata(pdev->dev.parent);
185         struct as3722_rtc *as3722_rtc;
186         int ret;
187
188         as3722_rtc = devm_kzalloc(&pdev->dev, sizeof(*as3722_rtc), GFP_KERNEL);
189         if (!as3722_rtc)
190                 return -ENOMEM;
191
192         as3722_rtc->as3722 = as3722;
193         as3722_rtc->dev = &pdev->dev;
194         platform_set_drvdata(pdev, as3722_rtc);
195
196         /* Enable the RTC to make sure it is running. */
197         ret = as3722_update_bits(as3722, AS3722_RTC_CONTROL_REG,
198                         AS3722_RTC_ON | AS3722_RTC_ALARM_WAKEUP_EN,
199                         AS3722_RTC_ON | AS3722_RTC_ALARM_WAKEUP_EN);
200         if (ret < 0) {
201                 dev_err(&pdev->dev, "RTC_CONTROL reg write failed: %d\n", ret);
202                 return ret;
203         }
204
205         device_init_wakeup(&pdev->dev, 1);
206
207         as3722_rtc->rtc = rtc_device_register("as3722", &pdev->dev,
208                                 &as3722_rtc_ops, THIS_MODULE);
209         if (IS_ERR(as3722_rtc->rtc)) {
210                 ret = PTR_ERR(as3722_rtc->rtc);
211                 dev_err(&pdev->dev, "RTC register failed: %d\n", ret);
212                 return ret;
213         }
214
215         as3722_rtc->alarm_irq = platform_get_irq(pdev, 0);
216         dev_info(&pdev->dev, "RTC interrupt %d\n", as3722_rtc->alarm_irq);
217
218         ret = request_threaded_irq(as3722_rtc->alarm_irq, NULL,
219                         as3722_alarm_irq, IRQF_ONESHOT | IRQF_EARLY_RESUME,
220                         "rtc-alarm", as3722_rtc);
221         if (ret < 0) {
222                 dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
223                                 as3722_rtc->alarm_irq, ret);
224                 goto scrub;
225         }
226         disable_irq(as3722_rtc->alarm_irq);
227         return 0;
228 scrub:
229         rtc_device_unregister(as3722_rtc->rtc);
230         return ret;
231 }
232
233 static int as3722_rtc_remove(struct platform_device *pdev)
234 {
235         struct as3722_rtc *as3722_rtc = platform_get_drvdata(pdev);
236
237         free_irq(as3722_rtc->alarm_irq, as3722_rtc);
238         rtc_device_unregister(as3722_rtc->rtc);
239         return 0;
240 }
241
242 void as3722_rtc_shutdown(struct platform_device *pdev)
243 {
244         struct as3722_rtc *as3722_rtc = platform_get_drvdata(pdev);
245
246         as3722_rtc_alarm_irq_enable(as3722_rtc->dev, 0);
247         rtc_device_shutdown(as3722_rtc->rtc);
248 }
249
250 #ifdef CONFIG_PM_SLEEP
251 static int as3722_rtc_suspend(struct device *dev)
252 {
253         struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
254
255         if (device_may_wakeup(dev)) {
256                 int ret;
257                 struct rtc_wkalrm alm;
258
259                 enable_irq_wake(as3722_rtc->alarm_irq);
260                 ret = as3722_rtc_read_alarm(dev, &alm);
261                 if (!ret)
262                         dev_info(dev, "%s() alrm %d time %d %d %d %d %d %d\n",
263                                 __func__, alm.enabled,
264                                 alm.time.tm_year, alm.time.tm_mon,
265                                 alm.time.tm_mday, alm.time.tm_hour,
266                                 alm.time.tm_min, alm.time.tm_sec);
267         }
268         return 0;
269 }
270
271 static int as3722_rtc_resume(struct device *dev)
272 {
273         struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev);
274
275         if (device_may_wakeup(dev)) {
276                 int ret;
277                 struct rtc_time tm;
278
279                 disable_irq_wake(as3722_rtc->alarm_irq);
280                 ret = as3722_rtc_read_time(dev, &tm);
281                 if (!ret)
282                         dev_info(dev, "%s() %d %d %d %d %d %d\n",
283                                 __func__, tm.tm_year, tm.tm_mon, tm.tm_mday,
284                                 tm.tm_hour, tm.tm_min, tm.tm_sec);
285         }
286         return 0;
287 }
288 #endif
289
290 static const struct dev_pm_ops as3722_rtc_pm_ops = {
291         SET_SYSTEM_SLEEP_PM_OPS(as3722_rtc_suspend, as3722_rtc_resume)
292 };
293
294 static struct platform_driver as3722_rtc_driver = {
295         .probe = as3722_rtc_probe,
296         .remove = as3722_rtc_remove,
297         .shutdown = as3722_rtc_shutdown,
298         .driver = {
299                 .name = "as3722-rtc",
300                 .pm = &as3722_rtc_pm_ops,
301         },
302 };
303 module_platform_driver(as3722_rtc_driver);
304
305 MODULE_DESCRIPTION("RTC driver for AS3722 PMICs");
306 MODULE_ALIAS("platform:as3722-rtc");
307 MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>");
308 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
309 MODULE_LICENSE("GPL");