Merge branches 'msm-fixes' and 'msm-video' of git://codeaurora.org/quic/kernel/dwalke...
[pandora-kernel.git] / drivers / rtc / rtc-ds3232.c
1 /*
2  * RTC client/driver for the Maxim/Dallas DS3232 Real-Time Clock over I2C
3  *
4  * Copyright (C) 2009-2010 Freescale Semiconductor.
5  * Author: Jack Lan <jack.lan@freescale.com>
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  */
12 /*
13  * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
14  * recommened in .../Documentation/i2c/writing-clients section
15  * "Sending and receiving", using SMBus level communication is preferred.
16  */
17
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/interrupt.h>
21 #include <linux/i2c.h>
22 #include <linux/rtc.h>
23 #include <linux/bcd.h>
24 #include <linux/workqueue.h>
25 #include <linux/slab.h>
26
27 #define DS3232_REG_SECONDS      0x00
28 #define DS3232_REG_MINUTES      0x01
29 #define DS3232_REG_HOURS        0x02
30 #define DS3232_REG_AMPM         0x02
31 #define DS3232_REG_DAY          0x03
32 #define DS3232_REG_DATE         0x04
33 #define DS3232_REG_MONTH        0x05
34 #define DS3232_REG_CENTURY      0x05
35 #define DS3232_REG_YEAR         0x06
36 #define DS3232_REG_ALARM1         0x07  /* Alarm 1 BASE */
37 #define DS3232_REG_ALARM2         0x0B  /* Alarm 2 BASE */
38 #define DS3232_REG_CR           0x0E    /* Control register */
39 #       define DS3232_REG_CR_nEOSC        0x80
40 #       define DS3232_REG_CR_INTCN        0x04
41 #       define DS3232_REG_CR_A2IE        0x02
42 #       define DS3232_REG_CR_A1IE        0x01
43
44 #define DS3232_REG_SR   0x0F    /* control/status register */
45 #       define DS3232_REG_SR_OSF   0x80
46 #       define DS3232_REG_SR_BSY   0x04
47 #       define DS3232_REG_SR_A2F   0x02
48 #       define DS3232_REG_SR_A1F   0x01
49
50 struct ds3232 {
51         struct i2c_client *client;
52         struct rtc_device *rtc;
53         struct work_struct work;
54
55         /* The mutex protects alarm operations, and prevents a race
56          * between the enable_irq() in the workqueue and the free_irq()
57          * in the remove function.
58          */
59         struct mutex mutex;
60         int exiting;
61 };
62
63 static struct i2c_driver ds3232_driver;
64
65 static int ds3232_check_rtc_status(struct i2c_client *client)
66 {
67         int ret = 0;
68         int control, stat;
69
70         stat = i2c_smbus_read_byte_data(client, DS3232_REG_SR);
71         if (stat < 0)
72                 return stat;
73
74         if (stat & DS3232_REG_SR_OSF)
75                 dev_warn(&client->dev,
76                                 "oscillator discontinuity flagged, "
77                                 "time unreliable\n");
78
79         stat &= ~(DS3232_REG_SR_OSF | DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
80
81         ret = i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat);
82         if (ret < 0)
83                 return ret;
84
85         /* If the alarm is pending, clear it before requesting
86          * the interrupt, so an interrupt event isn't reported
87          * before everything is initialized.
88          */
89
90         control = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
91         if (control < 0)
92                 return control;
93
94         control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
95         control |= DS3232_REG_CR_INTCN;
96
97         return i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
98 }
99
100 static int ds3232_read_time(struct device *dev, struct rtc_time *time)
101 {
102         struct i2c_client *client = to_i2c_client(dev);
103         int ret;
104         u8 buf[7];
105         unsigned int year, month, day, hour, minute, second;
106         unsigned int week, twelve_hr, am_pm;
107         unsigned int century, add_century = 0;
108
109         ret = i2c_smbus_read_i2c_block_data(client, DS3232_REG_SECONDS, 7, buf);
110
111         if (ret < 0)
112                 return ret;
113         if (ret < 7)
114                 return -EIO;
115
116         second = buf[0];
117         minute = buf[1];
118         hour = buf[2];
119         week = buf[3];
120         day = buf[4];
121         month = buf[5];
122         year = buf[6];
123
124         /* Extract additional information for AM/PM and century */
125
126         twelve_hr = hour & 0x40;
127         am_pm = hour & 0x20;
128         century = month & 0x80;
129
130         /* Write to rtc_time structure */
131
132         time->tm_sec = bcd2bin(second);
133         time->tm_min = bcd2bin(minute);
134         if (twelve_hr) {
135                 /* Convert to 24 hr */
136                 if (am_pm)
137                         time->tm_hour = bcd2bin(hour & 0x1F) + 12;
138                 else
139                         time->tm_hour = bcd2bin(hour & 0x1F);
140         } else {
141                 time->tm_hour = bcd2bin(hour);
142         }
143
144         time->tm_wday = bcd2bin(week);
145         time->tm_mday = bcd2bin(day);
146         time->tm_mon = bcd2bin(month & 0x7F);
147         if (century)
148                 add_century = 100;
149
150         time->tm_year = bcd2bin(year) + add_century;
151
152         return rtc_valid_tm(time);
153 }
154
155 static int ds3232_set_time(struct device *dev, struct rtc_time *time)
156 {
157         struct i2c_client *client = to_i2c_client(dev);
158         u8 buf[7];
159
160         /* Extract time from rtc_time and load into ds3232*/
161
162         buf[0] = bin2bcd(time->tm_sec);
163         buf[1] = bin2bcd(time->tm_min);
164         buf[2] = bin2bcd(time->tm_hour);
165         buf[3] = bin2bcd(time->tm_wday); /* Day of the week */
166         buf[4] = bin2bcd(time->tm_mday); /* Date */
167         buf[5] = bin2bcd(time->tm_mon);
168         if (time->tm_year >= 100) {
169                 buf[5] |= 0x80;
170                 buf[6] = bin2bcd(time->tm_year - 100);
171         } else {
172                 buf[6] = bin2bcd(time->tm_year);
173         }
174
175         return i2c_smbus_write_i2c_block_data(client,
176                                               DS3232_REG_SECONDS, 7, buf);
177 }
178
179 /*
180  * DS3232 has two alarm, we only use alarm1
181  * According to linux specification, only support one-shot alarm
182  * no periodic alarm mode
183  */
184 static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
185 {
186         struct i2c_client *client = to_i2c_client(dev);
187         struct ds3232 *ds3232 = i2c_get_clientdata(client);
188         int control, stat;
189         int ret;
190         u8 buf[4];
191
192         mutex_lock(&ds3232->mutex);
193
194         ret = i2c_smbus_read_byte_data(client, DS3232_REG_SR);
195         if (ret < 0)
196                 goto out;
197         stat = ret;
198         ret = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
199         if (ret < 0)
200                 goto out;
201         control = ret;
202         ret = i2c_smbus_read_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf);
203         if (ret < 0)
204                 goto out;
205
206         alarm->time.tm_sec = bcd2bin(buf[0] & 0x7F);
207         alarm->time.tm_min = bcd2bin(buf[1] & 0x7F);
208         alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F);
209         alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F);
210
211         alarm->time.tm_mon = -1;
212         alarm->time.tm_year = -1;
213         alarm->time.tm_wday = -1;
214         alarm->time.tm_yday = -1;
215         alarm->time.tm_isdst = -1;
216
217         alarm->enabled = !!(control & DS3232_REG_CR_A1IE);
218         alarm->pending = !!(stat & DS3232_REG_SR_A1F);
219
220         ret = 0;
221 out:
222         mutex_unlock(&ds3232->mutex);
223         return ret;
224 }
225
226 /*
227  * linux rtc-module does not support wday alarm
228  * and only 24h time mode supported indeed
229  */
230 static int ds3232_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
231 {
232         struct i2c_client *client = to_i2c_client(dev);
233         struct ds3232 *ds3232 = i2c_get_clientdata(client);
234         int control, stat;
235         int ret;
236         u8 buf[4];
237
238         if (client->irq <= 0)
239                 return -EINVAL;
240
241         mutex_lock(&ds3232->mutex);
242
243         buf[0] = bin2bcd(alarm->time.tm_sec);
244         buf[1] = bin2bcd(alarm->time.tm_min);
245         buf[2] = bin2bcd(alarm->time.tm_hour);
246         buf[3] = bin2bcd(alarm->time.tm_mday);
247
248         /* clear alarm interrupt enable bit */
249         ret = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
250         if (ret < 0)
251                 goto out;
252         control = ret;
253         control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
254         ret = i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
255         if (ret < 0)
256                 goto out;
257
258         /* clear any pending alarm flag */
259         ret = i2c_smbus_read_byte_data(client, DS3232_REG_SR);
260         if (ret < 0)
261                 goto out;
262         stat = ret;
263         stat &= ~(DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
264         ret = i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat);
265         if (ret < 0)
266                 goto out;
267
268         ret = i2c_smbus_write_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf);
269
270         if (alarm->enabled) {
271                 control |= DS3232_REG_CR_A1IE;
272                 ret = i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
273         }
274 out:
275         mutex_unlock(&ds3232->mutex);
276         return ret;
277 }
278
279 static void ds3232_update_alarm(struct i2c_client *client)
280 {
281         struct ds3232 *ds3232 = i2c_get_clientdata(client);
282         int control;
283         int ret;
284         u8 buf[4];
285
286         mutex_lock(&ds3232->mutex);
287
288         ret = i2c_smbus_read_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf);
289         if (ret < 0)
290                 goto unlock;
291
292         buf[0] = bcd2bin(buf[0]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ?
293                                                                 0x80 : buf[0];
294         buf[1] = bcd2bin(buf[1]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ?
295                                                                 0x80 : buf[1];
296         buf[2] = bcd2bin(buf[2]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ?
297                                                                 0x80 : buf[2];
298         buf[3] = bcd2bin(buf[3]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ?
299                                                                 0x80 : buf[3];
300
301         ret = i2c_smbus_write_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf);
302         if (ret < 0)
303                 goto unlock;
304
305         control = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
306         if (control < 0)
307                 goto unlock;
308
309         if (ds3232->rtc->irq_data & (RTC_AF | RTC_UF))
310                 /* enable alarm1 interrupt */
311                 control |= DS3232_REG_CR_A1IE;
312         else
313                 /* disable alarm1 interrupt */
314                 control &= ~(DS3232_REG_CR_A1IE);
315         i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
316
317 unlock:
318         mutex_unlock(&ds3232->mutex);
319 }
320
321 static int ds3232_alarm_irq_enable(struct device *dev, unsigned int enabled)
322 {
323         struct i2c_client *client = to_i2c_client(dev);
324         struct ds3232 *ds3232 = i2c_get_clientdata(client);
325
326         if (client->irq <= 0)
327                 return -EINVAL;
328
329         if (enabled)
330                 ds3232->rtc->irq_data |= RTC_AF;
331         else
332                 ds3232->rtc->irq_data &= ~RTC_AF;
333
334         ds3232_update_alarm(client);
335         return 0;
336 }
337
338 static int ds3232_update_irq_enable(struct device *dev, unsigned int enabled)
339 {
340         struct i2c_client *client = to_i2c_client(dev);
341         struct ds3232 *ds3232 = i2c_get_clientdata(client);
342
343         if (client->irq <= 0)
344                 return -EINVAL;
345
346         if (enabled)
347                 ds3232->rtc->irq_data |= RTC_UF;
348         else
349                 ds3232->rtc->irq_data &= ~RTC_UF;
350
351         ds3232_update_alarm(client);
352         return 0;
353 }
354
355 static irqreturn_t ds3232_irq(int irq, void *dev_id)
356 {
357         struct i2c_client *client = dev_id;
358         struct ds3232 *ds3232 = i2c_get_clientdata(client);
359
360         disable_irq_nosync(irq);
361         schedule_work(&ds3232->work);
362         return IRQ_HANDLED;
363 }
364
365 static void ds3232_work(struct work_struct *work)
366 {
367         struct ds3232 *ds3232 = container_of(work, struct ds3232, work);
368         struct i2c_client *client = ds3232->client;
369         int stat, control;
370
371         mutex_lock(&ds3232->mutex);
372
373         stat = i2c_smbus_read_byte_data(client, DS3232_REG_SR);
374         if (stat < 0)
375                 goto unlock;
376
377         if (stat & DS3232_REG_SR_A1F) {
378                 control = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
379                 if (control < 0)
380                         goto out;
381                 /* disable alarm1 interrupt */
382                 control &= ~(DS3232_REG_CR_A1IE);
383                 i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
384
385                 /* clear the alarm pend flag */
386                 stat &= ~DS3232_REG_SR_A1F;
387                 i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat);
388
389                 rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF);
390         }
391
392 out:
393         if (!ds3232->exiting)
394                 enable_irq(client->irq);
395 unlock:
396         mutex_unlock(&ds3232->mutex);
397 }
398
399 static const struct rtc_class_ops ds3232_rtc_ops = {
400         .read_time = ds3232_read_time,
401         .set_time = ds3232_set_time,
402         .read_alarm = ds3232_read_alarm,
403         .set_alarm = ds3232_set_alarm,
404         .alarm_irq_enable = ds3232_alarm_irq_enable,
405         .update_irq_enable = ds3232_update_irq_enable,
406 };
407
408 static int __devinit ds3232_probe(struct i2c_client *client,
409                 const struct i2c_device_id *id)
410 {
411         struct ds3232 *ds3232;
412         int ret;
413
414         ds3232 = kzalloc(sizeof(struct ds3232), GFP_KERNEL);
415         if (!ds3232)
416                 return -ENOMEM;
417
418         ds3232->client = client;
419         i2c_set_clientdata(client, ds3232);
420
421         INIT_WORK(&ds3232->work, ds3232_work);
422         mutex_init(&ds3232->mutex);
423
424         ret = ds3232_check_rtc_status(client);
425         if (ret)
426                 goto out_free;
427
428         ds3232->rtc = rtc_device_register(client->name, &client->dev,
429                                           &ds3232_rtc_ops, THIS_MODULE);
430         if (IS_ERR(ds3232->rtc)) {
431                 ret = PTR_ERR(ds3232->rtc);
432                 dev_err(&client->dev, "unable to register the class device\n");
433                 goto out_irq;
434         }
435
436         if (client->irq >= 0) {
437                 ret = request_irq(client->irq, ds3232_irq, 0,
438                                  "ds3232", client);
439                 if (ret) {
440                         dev_err(&client->dev, "unable to request IRQ\n");
441                         goto out_free;
442                 }
443         }
444
445         return 0;
446
447 out_irq:
448         if (client->irq >= 0)
449                 free_irq(client->irq, client);
450
451 out_free:
452         kfree(ds3232);
453         return ret;
454 }
455
456 static int __devexit ds3232_remove(struct i2c_client *client)
457 {
458         struct ds3232 *ds3232 = i2c_get_clientdata(client);
459
460         if (client->irq >= 0) {
461                 mutex_lock(&ds3232->mutex);
462                 ds3232->exiting = 1;
463                 mutex_unlock(&ds3232->mutex);
464
465                 free_irq(client->irq, client);
466                 flush_scheduled_work();
467         }
468
469         rtc_device_unregister(ds3232->rtc);
470         kfree(ds3232);
471         return 0;
472 }
473
474 static const struct i2c_device_id ds3232_id[] = {
475         { "ds3232", 0 },
476         { }
477 };
478 MODULE_DEVICE_TABLE(i2c, ds3232_id);
479
480 static struct i2c_driver ds3232_driver = {
481         .driver = {
482                 .name = "rtc-ds3232",
483                 .owner = THIS_MODULE,
484         },
485         .probe = ds3232_probe,
486         .remove = __devexit_p(ds3232_remove),
487         .id_table = ds3232_id,
488 };
489
490 static int __init ds3232_init(void)
491 {
492         return i2c_add_driver(&ds3232_driver);
493 }
494
495 static void __exit ds3232_exit(void)
496 {
497         i2c_del_driver(&ds3232_driver);
498 }
499
500 module_init(ds3232_init);
501 module_exit(ds3232_exit);
502
503 MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
504 MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver");
505 MODULE_LICENSE("GPL");