ricoh619:update the 619 drivers
[firefly-linux-kernel-4.4.55.git] / drivers / rtc / rtc-ricoh619.c
1 /*
2  * drivers/rtc/rtc-ricoh619.c
3  *
4  * Real time clock driver for RICOH RC5T619 power management chip.
5  *
6  * Copyright (C) 2012-2013 RICOH COMPANY,LTD
7  *
8  * Based on code
9  *  Copyright (C) 2011 NVIDIA Corporation  
10  *
11  * this program is free software; you can redistribute it and/or modify
12  * it under the terms of the gnu general public license as published by
13  * the free software foundation; either version 2 of the license, or
14  * (at your option) any later version.
15  *
16  * this program is distributed in the hope that it will be useful, but without
17  * any warranty; without even the implied warranty of merchantability or
18  * fitness for a particular purpose.  see the gnu general public license for
19  * more details.
20  *
21  * you should have received a copy of the gnu general public license
22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.  
23  *
24  */
25
26 /* #define debug                1 */
27 /* #define verbose_debug        1 */
28
29 #include <linux/device.h>
30 #include <linux/err.h>
31 #include <linux/init.h>
32 #include <linux/kernel.h>
33 #include <linux/mfd/ricoh619.h>
34 #include <linux/rtc/rtc-ricoh619.h>
35 #include <linux/platform_device.h>
36 #include <linux/rtc.h>
37 #include <linux/slab.h>
38
39 struct ricoh619_rtc {
40         unsigned long           epoch_start;
41         int                     irq;
42         struct rtc_device       *rtc;
43         bool                    irq_en;
44 };
45
46 static int ricoh619_read_regs(struct device *dev, int reg, int len,
47         uint8_t *val)
48 {
49         int ret;
50
51         ret = ricoh619_bulk_reads(dev->parent, reg, len, val);
52         if (ret < 0) {
53                 dev_err(dev->parent, "\n %s failed reading from 0x%02x\n",
54                         __func__, reg);
55                 WARN_ON(1);
56         }
57         return ret;
58 }
59
60 static int ricoh619_write_regs(struct device *dev, int reg, int len,
61         uint8_t *val)
62 {
63         int ret;
64         ret = ricoh619_bulk_writes(dev->parent, reg, len, val);
65         if (ret < 0) {
66                 dev_err(dev->parent, "\n %s failed writing\n", __func__);
67                 WARN_ON(1);
68         }
69
70         return ret;
71 }
72
73 static int ricoh619_rtc_valid_tm(struct device *dev, struct rtc_time *tm)
74 {
75         if (tm->tm_year >= (rtc_year_offset + 99)
76                 || tm->tm_mon > 12
77                 || tm->tm_mday < 1
78                 || tm->tm_mday > rtc_month_days(tm->tm_mon,
79                         tm->tm_year + os_ref_year)
80                 || tm->tm_hour >= 24
81                 || tm->tm_min >= 60
82                 || tm->tm_sec >= 60) {
83                 dev_err(dev->parent, "\n returning error due to time"
84                 "%d/%d/%d %d:%d:%d", tm->tm_mon, tm->tm_mday,
85                 tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec);
86                 return -EINVAL;
87         }
88         return 0;
89 }
90
91 static u8 dec2bcd(u8 dec)
92 {
93         return ((dec/10)<<4)+(dec%10);
94 }
95
96 static u8 bcd2dec(u8 bcd)
97 {
98         return (bcd >> 4)*10+(bcd & 0xf);
99 }
100
101 static void convert_bcd_to_decimal(u8 *buf, u8 len)
102 {
103         int i = 0;
104         for (i = 0; i < len; i++)
105                 buf[i] = bcd2dec(buf[i]);
106 }
107
108 static void convert_decimal_to_bcd(u8 *buf, u8 len)
109 {
110         int i = 0;
111         for (i = 0; i < len; i++)
112                 buf[i] = dec2bcd(buf[i]);
113 }
114
115 static void print_time(struct device *dev, struct rtc_time *tm)
116 {
117         dev_info(dev, "rtc-time : %d/%d/%d %d:%d\n",
118                 (tm->tm_mon + 1), tm->tm_mday, (tm->tm_year + os_ref_year),
119                 tm->tm_hour, tm->tm_min);
120 }
121
122 static int ricoh619_rtc_read_time(struct device *dev, struct rtc_time *tm)
123 {
124         u8 buff[7];
125         int err;
126         err = ricoh619_read_regs(dev, rtc_seconds_reg, sizeof(buff), buff);
127         if (err < 0) {
128                 dev_err(dev, "\n %s :: failed to read time\n", __FILE__);
129                 return err;
130         }
131         convert_bcd_to_decimal(buff, sizeof(buff));
132         tm->tm_sec  = buff[0];
133         tm->tm_min  = buff[1];
134         tm->tm_hour = buff[2];
135         tm->tm_wday = buff[3];
136         tm->tm_mday = buff[4];
137         tm->tm_mon  = buff[5] - 1;
138         tm->tm_year = buff[6] + rtc_year_offset;
139 //      print_time(dev, tm);
140         return ricoh619_rtc_valid_tm(dev, tm);
141 }
142
143 static int ricoh619_rtc_set_time(struct device *dev, struct rtc_time *tm)
144 {
145         u8 buff[7];
146         int err;
147
148 //      print_time(dev, tm);
149         buff[0] = tm->tm_sec;
150         buff[1] = tm->tm_min;
151         buff[2] = tm->tm_hour;
152         buff[3] = tm->tm_wday;
153         buff[4] = tm->tm_mday;
154         buff[5] = tm->tm_mon + 1;
155         buff[6] = tm->tm_year - rtc_year_offset;
156
157         convert_decimal_to_bcd(buff, sizeof(buff));
158         err = ricoh619_write_regs(dev, rtc_seconds_reg, sizeof(buff), buff);
159         if (err < 0) {
160                 dev_err(dev->parent, "\n failed to program new time\n");
161                 return err;
162         }
163
164         return 0;
165 }
166 static int ricoh619_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm);
167
168 static int ricoh619_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
169 {
170         struct ricoh619_rtc *rtc = dev_get_drvdata(dev);
171         unsigned long seconds;
172         u8 buff[6];
173         int err;
174         struct rtc_time tm;
175
176         if (rtc->irq == -1)
177                 return -EIO;
178
179         rtc_tm_to_time(&alrm->time, &seconds);
180         err = ricoh619_rtc_read_time(dev, &tm);
181         if (err) {
182                 dev_err(dev, "\n failed to read time\n");
183                 return err;
184         }
185         rtc_tm_to_time(&tm, &rtc->epoch_start);
186
187         dev_info(dev->parent, "\n setting alarm to requested time::\n");
188 //      print_time(dev->parent, &alrm->time);
189
190         if (WARN_ON(alrm->enabled && (seconds < rtc->epoch_start))) {
191                 dev_err(dev->parent, "\n can't set alarm to requested time\n");
192                 return -EINVAL;
193         }
194
195         if (alrm->enabled && !rtc->irq_en)
196                 rtc->irq_en = true;
197         else if (!alrm->enabled && rtc->irq_en)
198                 rtc->irq_en = false;
199
200         buff[0] = alrm->time.tm_sec;
201         buff[1] = alrm->time.tm_min;
202         buff[2] = alrm->time.tm_hour;
203         buff[3] = alrm->time.tm_mday;
204         buff[4] = alrm->time.tm_mon + 1;
205         buff[5] = alrm->time.tm_year - rtc_year_offset;
206         convert_decimal_to_bcd(buff, sizeof(buff));
207         buff[3] |= 0x80;        /* set DAL_EXT */
208         err = ricoh619_write_regs(dev, rtc_alarm_y_sec, sizeof(buff), buff);
209         if (err) {
210                 dev_err(dev->parent, "\n unable to set alarm\n");
211                 return -EBUSY;
212         }
213
214         err = ricoh619_read_regs(dev, rtc_ctrl2, 1, buff);
215         if (err) {
216                 dev_err(dev->parent, "unable to read rtc_ctrl2 reg\n");
217                 return -EBUSY;
218         }
219
220         buff[1] = buff[0] & ~0x81; /* to clear alarm-D flag, and set adjustment parameter */
221         buff[0] = 0x60; /* to enable alarm_d and 24-hour format */
222         err = ricoh619_write_regs(dev, rtc_ctrl1, 2, buff);
223         if (err) {
224                 dev_err(dev, "failed programming rtc ctrl regs\n");
225                 return -EBUSY;
226         }
227 return err;
228 }
229
230 static int ricoh619_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
231 {
232         u8 buff[6];
233         int err;
234
235         err = ricoh619_read_regs(dev, rtc_alarm_y_sec, sizeof(buff), buff);
236         if (err)
237                 return err;
238         buff[3] &= ~0x80;       /* clear DAL_EXT */
239         convert_bcd_to_decimal(buff, sizeof(buff));
240
241         alrm->time.tm_sec  = buff[0];
242         alrm->time.tm_min  = buff[1];
243         alrm->time.tm_hour = buff[2];
244         alrm->time.tm_mday = buff[3];
245         alrm->time.tm_mon  = buff[4] - 1;
246         alrm->time.tm_year = buff[5] + rtc_year_offset;
247
248 //      dev_info(dev->parent, "\n getting alarm time::\n");
249 //      print_time(dev, &alrm->time);
250
251         return 0;
252 }
253
254 static const struct rtc_class_ops ricoh619_rtc_ops = {
255         .read_time      = ricoh619_rtc_read_time,
256         .set_time       = ricoh619_rtc_set_time,
257         .set_alarm      = ricoh619_rtc_set_alarm,
258         .read_alarm     = ricoh619_rtc_read_alarm,
259 };
260
261 static irqreturn_t ricoh619_rtc_irq(int irq, void *data)
262 {
263         struct device *dev = data;
264         struct ricoh619_rtc *rtc = dev_get_drvdata(dev);
265         u8 reg;
266         int err;
267
268         /* clear alarm-D status bits.*/
269         err = ricoh619_read_regs(dev, rtc_ctrl2, 1, &reg);
270         if (err)
271                 dev_err(dev->parent, "unable to read rtc_ctrl2 reg\n");
272
273         /* to clear alarm-D flag, and set adjustment parameter */
274         reg &= ~0x81;
275         err = ricoh619_write_regs(dev, rtc_ctrl2, 1, &reg);
276         if (err)
277                 dev_err(dev->parent, "unable to program rtc_status reg\n");
278
279         rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
280         return IRQ_HANDLED;
281 }
282
283 static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
284 {
285         struct ricoh619_rtc_platform_data *pdata = pdev->dev.platform_data;
286         struct ricoh619_rtc *rtc;
287         struct rtc_time tm;
288         int err;
289         u8 reg;
290         rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
291 //      printk("%s,line=%d\n", __func__,__LINE__);      
292
293         if (!rtc)
294                 return -ENOMEM;
295
296         rtc->irq = -1;
297
298         if (!pdata) {
299                 dev_err(&pdev->dev, "no platform_data specified\n");
300                 return -EINVAL;
301         }
302
303         if (pdata->irq < 0)
304                 dev_err(&pdev->dev, "\n no irq specified, wakeup is disabled\n");
305
306         dev_set_drvdata(&pdev->dev, rtc);
307         device_init_wakeup(&pdev->dev, 1);
308         rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
309                                        &ricoh619_rtc_ops, THIS_MODULE);
310
311         if (IS_ERR(rtc->rtc)) {
312                 err = PTR_ERR(rtc->rtc);
313                 goto fail;
314         }
315
316         reg = 0x60; /* to enable alarm_d and 24-hour format */
317         err = ricoh619_write_regs(&pdev->dev, rtc_ctrl1, 1, &reg);
318         if (err) {
319                 dev_err(&pdev->dev, "failed rtc setup\n");
320                 return -EBUSY;
321         }
322
323         reg =  0; /* clearing RTC Adjust register */
324         err = ricoh619_write_regs(&pdev->dev, rtc_adjust, 1, &reg);
325         if (err) {
326                 dev_err(&pdev->dev, "unable to program rtc_adjust reg\n");
327                 return -EBUSY;
328         }
329         /* Set default time-1970.1.1-0h:0m:0s if PON is on */
330         err = ricoh619_read_regs(&pdev->dev, rtc_ctrl2, 1, &reg);
331         if (err) {
332                 dev_err(&pdev->dev, "\n failed to read rtc ctl2 reg\n");
333                 return -EBUSY;
334         }
335         if (reg&0x10) {
336                 printk("%s,PON=1 -- CTRL2=%x\n", __func__, reg);
337                 tm.tm_sec  = 0;
338                 tm.tm_min  = 0;
339                 tm.tm_hour = 0;
340                 tm.tm_wday = 4;
341                 tm.tm_mday = 1;
342                 tm.tm_mon  = 0;
343                 tm.tm_year = 0x70;
344                 /* VDET & PON = 0, others are not changed */
345                 reg &= ~0x50;
346                 err = ricoh619_write_regs(&pdev->dev, rtc_ctrl2, 1, &reg);
347                 if (err) {
348                         dev_err(&pdev->dev, "\n failed to write rtc ctl2 reg\n");
349                         return -EBUSY;
350                 }
351                 
352         } else {
353                 err = ricoh619_rtc_read_time(&pdev->dev, &tm);
354                 if (err) {
355                         dev_err(&pdev->dev, "\n failed to read time\n");
356                         return err;
357                 }
358         }
359         if (ricoh619_rtc_valid_tm(&pdev->dev, &tm)) {
360                 if (pdata->time.tm_year < 2000 || pdata->time.tm_year > 2100) {
361                         memset(&pdata->time, 0, sizeof(pdata->time));
362                         pdata->time.tm_year = rtc_year_offset;
363                         pdata->time.tm_mday = 1;
364                 } else
365                 pdata->time.tm_year -= os_ref_year;
366                 err = ricoh619_rtc_set_time(&pdev->dev, &pdata->time);
367                 if (err) {
368                         dev_err(&pdev->dev, "\n failed to set time\n");
369                         return err;
370                 }
371         }
372         if (pdata && (pdata->irq >= 0)) {
373                 rtc->irq = pdata->irq + RICOH619_IRQ_DALE;
374                 err = request_threaded_irq(rtc->irq, NULL, ricoh619_rtc_irq,
375                                         IRQF_ONESHOT, "rtc_ricoh619",
376                                         &pdev->dev);
377                 if (err) {
378                         dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq);
379                         rtc->irq = -1;
380                 } else {
381                         device_init_wakeup(&pdev->dev, 1);
382                         enable_irq_wake(rtc->irq);
383                 }
384         }
385         return 0;
386
387 fail:
388         if (!IS_ERR_OR_NULL(rtc->rtc))
389                 rtc_device_unregister(rtc->rtc);
390         kfree(rtc);
391         return err;
392 }
393
394 static int __devexit ricoh619_rtc_remove(struct platform_device *pdev)
395 {
396         struct ricoh619_rtc *rtc = dev_get_drvdata(&pdev->dev);
397
398         if (rtc->irq != -1)
399                 free_irq(rtc->irq, rtc);
400         rtc_device_unregister(rtc->rtc);
401         kfree(rtc);
402         return 0;
403 }
404
405 static struct platform_driver ricoh619_rtc_driver = {
406         .driver = {
407                 .name   = "rtc_ricoh619",
408                 .owner  = THIS_MODULE,
409         },
410         .probe  = ricoh619_rtc_probe,
411         .remove = __devexit_p(ricoh619_rtc_remove),
412 };
413
414 static int __init ricoh619_rtc_init(void)
415 {
416         return platform_driver_register(&ricoh619_rtc_driver);
417 }
418 subsys_initcall_sync(ricoh619_rtc_init);
419
420 static void __exit ricoh619_rtc_exit(void)
421 {
422         platform_driver_unregister(&ricoh619_rtc_driver);
423 }
424 module_exit(ricoh619_rtc_exit);
425
426 MODULE_DESCRIPTION("RICOH RICOH619 RTC driver");
427 MODULE_ALIAS("platform:rtc_ricoh619");
428 MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
429 MODULE_LICENSE("GPL");
430