temp revert rk change
[firefly-linux-kernel-4.4.55.git] / drivers / rtc / rtc-cpcap.c
1 /*
2  * Copyright (C) 2009 Motorola, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16  * 02111-1307, USA
17  */
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/device.h>
22 #include <linux/platform_device.h>
23 #include <linux/rtc.h>
24 #include <linux/err.h>
25 #include <linux/slab.h>
26 #include <linux/spi/cpcap.h>
27 #ifdef RTC_INTF_CPCAP_SECCLKD
28 #include <linux/miscdevice.h>
29
30 #define CNT_MASK  0xFFFF
31 #endif
32 #define SECS_PER_DAY 86400
33 #define DAY_MASK  0x7FFF
34 #define TOD1_MASK 0x00FF
35 #define TOD2_MASK 0x01FF
36
37 #ifdef RTC_INTF_CPCAP_SECCLKD
38 static int cpcap_rtc_open(struct inode *inode, struct file *file);
39 static int cpcap_rtc_ioctl(struct inode *inode, struct file *file,
40                             unsigned int cmd, unsigned long arg);
41 static unsigned int cpcap_rtc_poll(struct file *file, poll_table *wait);
42 static int cpcap_rtc_read_time(struct device *dev, struct rtc_time *tm);
43 #endif
44
45 struct cpcap_time {
46         unsigned short day;
47         unsigned short tod1;
48         unsigned short tod2;
49 };
50
51 struct cpcap_rtc {
52         struct cpcap_device *cpcap;
53         struct rtc_device *rtc_dev;
54         int alarm_enabled;
55         int second_enabled;
56 #ifdef RTC_INTF_CPCAP_SECCLKD
57         struct device *dev;
58         struct mutex lock;      /* protect access to flags */
59         wait_queue_head_t wait;
60         bool data_pending;
61         bool reset_flag;
62 #endif
63 };
64
65 #ifdef RTC_INTF_CPCAP_SECCLKD
66 static const struct file_operations cpcap_rtc_fops = {
67         .owner = THIS_MODULE,
68         .open = cpcap_rtc_open,
69         .ioctl = cpcap_rtc_ioctl,
70         .poll = cpcap_rtc_poll,
71 };
72
73 static struct cpcap_rtc *rtc_ptr;
74
75 static struct miscdevice cpcap_rtc_dev = {
76         .minor  = MISC_DYNAMIC_MINOR,
77         .name   = "cpcap_mot_rtc",
78         .fops   = &cpcap_rtc_fops,
79 };
80
81 static int cpcap_rtc_open(struct inode *inode, struct file *file)
82 {
83         file->private_data = rtc_ptr;
84         return 0;
85 }
86
87 static int cpcap_rtc_ioctl(struct inode *inode,
88                             struct file *file,
89                             unsigned int cmd,
90                             unsigned long arg)
91 {
92         struct cpcap_rtc *rtc = file->private_data;
93         struct cpcap_rtc_time_cnt local_val;
94         int ret = 0;
95
96         mutex_lock(&rtc->lock);
97         switch (cmd) {
98         case CPCAP_IOCTL_GET_RTC_TIME_COUNTER:
99                 ret = cpcap_rtc_read_time(rtc->dev, &local_val.time);
100                 ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_VAL2,
101                                 &local_val.count);
102
103                 if (ret)
104                         break;
105
106                 if (rtc->reset_flag) {
107                         rtc->reset_flag = 0;
108                         local_val.count = 0;
109                 }
110
111                 /* Copy the result back to the user. */
112                 if (copy_to_user((struct cpcap_rtc_time_cnt *)arg, &local_val,
113                         sizeof(struct cpcap_rtc_time_cnt)) == 0) {
114                         if (local_val.count == 0) {
115                                 ret = cpcap_regacc_write(rtc->cpcap,
116                                                 CPCAP_REG_VAL2, 0x0001,
117                                                 CNT_MASK);
118                                 if (ret)
119                                         break;
120                         }
121                         rtc->data_pending = 0;
122                 } else
123                         ret = -EFAULT;
124                 break;
125
126         default:
127                 ret = -ENOTTY;
128
129         }
130
131         mutex_unlock(&rtc->lock);
132         return ret;
133 }
134
135 static unsigned int cpcap_rtc_poll(struct file *file, poll_table *wait)
136 {
137         struct cpcap_rtc *rtc = file->private_data;
138         unsigned int ret = 0;
139
140         poll_wait(file, &rtc->wait, wait);
141
142         if (rtc->data_pending)
143                 ret = (POLLIN | POLLRDNORM);
144
145         return ret;
146 }
147 #endif
148
149 static void cpcap2rtc_time(struct rtc_time *rtc, struct cpcap_time *cpcap)
150 {
151         unsigned long int tod;
152         unsigned long int time;
153
154         tod = (cpcap->tod1 & TOD1_MASK) | ((cpcap->tod2 & TOD2_MASK) << 8);
155         time = tod + ((cpcap->day & DAY_MASK) * SECS_PER_DAY);
156
157         rtc_time_to_tm(time, rtc);
158 }
159
160 static void rtc2cpcap_time(struct cpcap_time *cpcap, struct rtc_time *rtc)
161 {
162         unsigned long time;
163
164         rtc_tm_to_time(rtc, &time);
165
166         cpcap->day = time / SECS_PER_DAY;
167         time %= SECS_PER_DAY;
168         cpcap->tod2 = (time >> 8) & TOD2_MASK;
169         cpcap->tod1 = time & TOD1_MASK;
170 }
171
172 static int
173 cpcap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
174 {
175         struct cpcap_rtc *rtc = dev_get_drvdata(dev);
176         int err;
177
178         if (enabled)
179                 err = cpcap_irq_unmask(rtc->cpcap, CPCAP_IRQ_TODA);
180         else
181                 err = cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_TODA);
182
183         if (err < 0)
184                 return err;
185
186         rtc->alarm_enabled = enabled;
187
188         return 0;
189 }
190
191 static int
192 cpcap_rtc_update_irq_enable(struct device *dev, unsigned int enabled)
193 {
194         struct cpcap_rtc *rtc = dev_get_drvdata(dev);
195         int err;
196
197         if (enabled)
198                 err = cpcap_irq_unmask(rtc->cpcap, CPCAP_IRQ_1HZ);
199         else
200                 err = cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_1HZ);
201
202         if (err < 0)
203                 return err;
204
205         rtc->second_enabled = enabled;
206
207         return 0;
208 }
209
210 static int cpcap_rtc_read_time(struct device *dev, struct rtc_time *tm)
211 {
212         struct cpcap_rtc *rtc;
213         struct cpcap_time cpcap_tm;
214         unsigned short temp_tod2;
215         int ret;
216
217         rtc = dev_get_drvdata(dev);
218
219         ret = cpcap_regacc_read(rtc->cpcap, CPCAP_REG_TOD2, &temp_tod2);
220         ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_DAY, &cpcap_tm.day);
221         ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_TOD1, &cpcap_tm.tod1);
222         ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_TOD2, &cpcap_tm.tod2);
223         if (temp_tod2 > cpcap_tm.tod2)
224                 ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_DAY,
225                                          &cpcap_tm.day);
226
227         if (ret) {
228                 dev_err(dev, "Failed to read time\n");
229                 return -EIO;
230         }
231
232         cpcap2rtc_time(tm, &cpcap_tm);
233
234         dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
235                 tm->tm_mday, tm->tm_mon, tm->tm_year,
236                 tm->tm_hour, tm->tm_min, tm->tm_sec);
237
238         return rtc_valid_tm(tm);
239 }
240
241 static int cpcap_rtc_set_time(struct device *dev, struct rtc_time *tm)
242 {
243         struct cpcap_rtc *rtc;
244         struct cpcap_time cpcap_tm;
245         int second_masked;
246         int alarm_masked;
247         int ret = 0;
248 #ifdef RTC_INTF_CPCAP_SECCLKD
249         unsigned short local_cnt;
250 #endif
251
252         rtc = dev_get_drvdata(dev);
253
254         dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
255                 tm->tm_mday, tm->tm_mon, tm->tm_year,
256                 tm->tm_hour, tm->tm_min, tm->tm_sec);
257
258         rtc2cpcap_time(&cpcap_tm, tm);
259
260         second_masked = cpcap_irq_mask_get(rtc->cpcap, CPCAP_IRQ_1HZ);
261         alarm_masked = cpcap_irq_mask_get(rtc->cpcap, CPCAP_IRQ_TODA);
262
263         if (!second_masked)
264                 cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_1HZ);
265         if (!alarm_masked)
266                 cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_TODA);
267
268 #ifdef RTC_INTF_CPCAP_SECCLKD
269         /* Increment the counter and update validity 2 register */
270         ret = cpcap_regacc_read(rtc->cpcap, CPCAP_REG_VAL2, &local_cnt);
271
272         if (local_cnt == 0)
273                 rtc->reset_flag = 1;
274
275         if (local_cnt == CNT_MASK)
276                 local_cnt = 0x0001;
277         else
278                 local_cnt++;
279
280         ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_VAL2, local_cnt,
281                                          CNT_MASK);
282 #endif
283
284         if (rtc->cpcap->vendor == CPCAP_VENDOR_ST) {
285                 /* The TOD1 and TOD2 registers MUST be written in this order
286                  * for the change to properly set. */
287                 ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TOD1,
288                                           cpcap_tm.tod1, TOD1_MASK);
289                 ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TOD2,
290                                           cpcap_tm.tod2, TOD2_MASK);
291                 ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_DAY,
292                                           cpcap_tm.day, DAY_MASK);
293         } else {
294                 /* Clearing the upper lower 8 bits of the TOD guarantees that
295                  * the upper half of TOD (TOD2) will not increment for 0xFF RTC
296                  * ticks (255 seconds).  During this time we can safely write
297                  * to DAY, TOD2, then TOD1 (in that order) and expect RTC to be
298                  * synchronized to the exact time requested upon the final write
299                  * to TOD1. */
300                 ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TOD1,
301                                           0, TOD1_MASK);
302                 ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_DAY,
303                                           cpcap_tm.day, DAY_MASK);
304                 ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TOD2,
305                                           cpcap_tm.tod2, TOD2_MASK);
306                 ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TOD1,
307                                           cpcap_tm.tod1, TOD1_MASK);
308         }
309
310         if (!second_masked)
311                 cpcap_irq_unmask(rtc->cpcap, CPCAP_IRQ_1HZ);
312         if (!alarm_masked)
313                 cpcap_irq_unmask(rtc->cpcap, CPCAP_IRQ_TODA);
314
315 #ifdef RTC_INTF_CPCAP_SECCLKD
316         mutex_lock(&rtc->lock);
317         rtc->data_pending = 1;
318         mutex_unlock(&rtc->lock);
319         wake_up_interruptible(&rtc->wait);
320 #endif
321
322         return ret;
323 }
324
325 static int cpcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
326 {
327         struct cpcap_rtc *rtc;
328         struct cpcap_time cpcap_tm;
329         int ret;
330
331         rtc = dev_get_drvdata(dev);
332
333         alrm->enabled = rtc->alarm_enabled;
334
335         ret = cpcap_regacc_read(rtc->cpcap, CPCAP_REG_DAYA, &cpcap_tm.day);
336         ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_TODA2, &cpcap_tm.tod2);
337         ret |= cpcap_regacc_read(rtc->cpcap, CPCAP_REG_TODA1, &cpcap_tm.tod1);
338
339         if (ret) {
340                 dev_err(dev, "Failed to read time\n");
341                 return -EIO;
342         }
343
344         cpcap2rtc_time(&alrm->time, &cpcap_tm);
345         return rtc_valid_tm(&alrm->time);
346 }
347
348 static int cpcap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
349 {
350         struct cpcap_rtc *rtc;
351         struct cpcap_time cpcap_tm;
352         int ret;
353
354         rtc = dev_get_drvdata(dev);
355
356         rtc2cpcap_time(&cpcap_tm, &alrm->time);
357
358         if (rtc->alarm_enabled)
359                 cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_TODA);
360
361         ret = cpcap_regacc_write(rtc->cpcap, CPCAP_REG_DAYA, cpcap_tm.day,
362                                  DAY_MASK);
363         ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TODA2, cpcap_tm.tod2,
364                                   TOD2_MASK);
365         ret |= cpcap_regacc_write(rtc->cpcap, CPCAP_REG_TODA1, cpcap_tm.tod1,
366                                   TOD1_MASK);
367
368         ret |= cpcap_rtc_alarm_irq_enable(dev, alrm->enabled);
369
370         return ret;
371 }
372
373 static struct rtc_class_ops cpcap_rtc_ops = {
374         .read_time              = cpcap_rtc_read_time,
375         .set_time               = cpcap_rtc_set_time,
376         .read_alarm             = cpcap_rtc_read_alarm,
377         .set_alarm              = cpcap_rtc_set_alarm,
378         .alarm_irq_enable       = cpcap_rtc_alarm_irq_enable,
379         .update_irq_enable      = cpcap_rtc_update_irq_enable,
380 };
381
382 static void cpcap_rtc_irq(enum cpcap_irqs irq, void *data)
383 {
384         struct cpcap_rtc *rtc = data;
385
386         switch (irq) {
387         case CPCAP_IRQ_TODA:
388                 rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
389                 break;
390         case CPCAP_IRQ_1HZ:
391                 rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
392                 break;
393         default:
394                 break;
395         }
396 }
397
398 static int __devinit cpcap_rtc_probe(struct platform_device *pdev)
399 {
400         struct cpcap_rtc *rtc;
401 #ifdef RTC_INTF_CPCAP_SECCLKD
402         int ret = 0;
403 #endif
404
405         rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
406         if (!rtc)
407                 return -ENOMEM;
408
409         rtc->cpcap = pdev->dev.platform_data;
410         platform_set_drvdata(pdev, rtc);
411         rtc->rtc_dev = rtc_device_register("cpcap_rtc", &pdev->dev,
412                                            &cpcap_rtc_ops, THIS_MODULE);
413
414         if (IS_ERR(rtc->rtc_dev)) {
415                 kfree(rtc);
416                 return PTR_ERR(rtc->rtc_dev);
417         }
418
419 #ifdef RTC_INTF_CPCAP_SECCLKD
420         rtc->dev = &pdev->dev;
421         ret = misc_register(&cpcap_rtc_dev);
422         if (ret != 0) {
423                 rtc_device_unregister(rtc->rtc_dev);
424                 kfree(rtc);
425                 return ret;
426         }
427
428         mutex_init(&rtc->lock);
429         init_waitqueue_head(&rtc->wait);
430         rtc_ptr = rtc;
431 #endif
432         cpcap_irq_register(rtc->cpcap, CPCAP_IRQ_TODA, cpcap_rtc_irq, rtc);
433         cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_TODA);
434
435         cpcap_irq_clear(rtc->cpcap, CPCAP_IRQ_1HZ);
436         cpcap_irq_register(rtc->cpcap, CPCAP_IRQ_1HZ, cpcap_rtc_irq, rtc);
437         cpcap_irq_mask(rtc->cpcap, CPCAP_IRQ_1HZ);
438
439         return 0;
440 }
441
442 static int __devexit cpcap_rtc_remove(struct platform_device *pdev)
443 {
444         struct cpcap_rtc *rtc;
445
446         rtc = platform_get_drvdata(pdev);
447
448         cpcap_irq_free(rtc->cpcap, CPCAP_IRQ_TODA);
449         cpcap_irq_free(rtc->cpcap, CPCAP_IRQ_1HZ);
450
451 #ifdef RTC_INTF_CPCAP_SECCLKD
452         misc_deregister(&cpcap_rtc_dev);
453 #endif
454         rtc_device_unregister(rtc->rtc_dev);
455         kfree(rtc);
456
457         return 0;
458 }
459
460 static struct platform_driver cpcap_rtc_driver = {
461         .driver = {
462                 .name = "cpcap_rtc",
463         },
464         .probe = cpcap_rtc_probe,
465         .remove = __devexit_p(cpcap_rtc_remove),
466 };
467
468 static int __init cpcap_rtc_init(void)
469 {
470         return platform_driver_register(&cpcap_rtc_driver);
471 }
472 module_init(cpcap_rtc_init);
473
474 static void __exit cpcap_rtc_exit(void)
475 {
476         platform_driver_unregister(&cpcap_rtc_driver);
477 }
478 module_exit(cpcap_rtc_exit);
479
480 MODULE_ALIAS("platform:cpcap_rtc");
481 MODULE_DESCRIPTION("CPCAP RTC driver");
482 MODULE_AUTHOR("Motorola");
483 MODULE_LICENSE("GPL");