2 * RTC driver for Maxim MAX8925
4 * Copyright (C) 2009-2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
12 #include <linux/module.h>
13 #include <linux/i2c.h>
14 #include <linux/slab.h>
15 #include <linux/rtc.h>
16 #include <linux/platform_device.h>
17 #include <linux/mfd/max8925.h>
30 #define MAX8925_RTC_SEC 0x00
31 #define MAX8925_RTC_MIN 0x01
32 #define MAX8925_RTC_HOUR 0x02
33 #define MAX8925_RTC_WEEKDAY 0x03
34 #define MAX8925_RTC_DATE 0x04
35 #define MAX8925_RTC_MONTH 0x05
36 #define MAX8925_RTC_YEAR1 0x06
37 #define MAX8925_RTC_YEAR2 0x07
38 #define MAX8925_ALARM0_SEC 0x08
39 #define MAX8925_ALARM0_MIN 0x09
40 #define MAX8925_ALARM0_HOUR 0x0a
41 #define MAX8925_ALARM0_WEEKDAY 0x0b
42 #define MAX8925_ALARM0_DATE 0x0c
43 #define MAX8925_ALARM0_MON 0x0d
44 #define MAX8925_ALARM0_YEAR1 0x0e
45 #define MAX8925_ALARM0_YEAR2 0x0f
46 #define MAX8925_ALARM1_SEC 0x10
47 #define MAX8925_ALARM1_MIN 0x11
48 #define MAX8925_ALARM1_HOUR 0x12
49 #define MAX8925_ALARM1_WEEKDAY 0x13
50 #define MAX8925_ALARM1_DATE 0x14
51 #define MAX8925_ALARM1_MON 0x15
52 #define MAX8925_ALARM1_YEAR1 0x16
53 #define MAX8925_ALARM1_YEAR2 0x17
54 #define MAX8925_RTC_CNTL 0x1b
55 #define MAX8925_RTC_STATUS 0x20
58 #define ALARM_1SEC (1 << 7)
59 #define HOUR_12 (1 << 7)
60 #define HOUR_AM_PM (1 << 5)
61 #define ALARM0_IRQ (1 << 3)
62 #define ALARM1_IRQ (1 << 2)
63 #define ALARM0_STATUS (1 << 2)
64 #define ALARM1_STATUS (1 << 1)
67 struct max8925_rtc_info
{
68 struct rtc_device
*rtc_dev
;
69 struct max8925_chip
*chip
;
70 struct i2c_client
*rtc
;
74 static irqreturn_t
rtc_update_handler(int irq
, void *data
)
76 struct max8925_rtc_info
*info
= (struct max8925_rtc_info
*)data
;
78 /* disable ALARM0 except for 1SEC alarm */
79 max8925_set_bits(info
->rtc
, MAX8925_ALARM0_CNTL
, 0x7f, 0);
80 rtc_update_irq(info
->rtc_dev
, 1, RTC_IRQF
| RTC_AF
);
84 static int tm_calc(struct rtc_time
*tm
, unsigned char *buf
, int len
)
88 tm
->tm_year
= (buf
[RTC_YEAR2
] >> 4) * 1000
89 + (buf
[RTC_YEAR2
] & 0xf) * 100
90 + (buf
[RTC_YEAR1
] >> 4) * 10
91 + (buf
[RTC_YEAR1
] & 0xf);
93 tm
->tm_mon
= ((buf
[RTC_MONTH
] >> 4) & 0x01) * 10
94 + (buf
[RTC_MONTH
] & 0x0f);
95 tm
->tm_mday
= ((buf
[RTC_DATE
] >> 4) & 0x03) * 10
96 + (buf
[RTC_DATE
] & 0x0f);
97 tm
->tm_wday
= buf
[RTC_WEEKDAY
] & 0x07;
98 if (buf
[RTC_HOUR
] & HOUR_12
) {
99 tm
->tm_hour
= ((buf
[RTC_HOUR
] >> 4) & 0x1) * 10
100 + (buf
[RTC_HOUR
] & 0x0f);
101 if (buf
[RTC_HOUR
] & HOUR_AM_PM
)
104 tm
->tm_hour
= ((buf
[RTC_HOUR
] >> 4) & 0x03) * 10
105 + (buf
[RTC_HOUR
] & 0x0f);
106 tm
->tm_min
= ((buf
[RTC_MIN
] >> 4) & 0x7) * 10
107 + (buf
[RTC_MIN
] & 0x0f);
108 tm
->tm_sec
= ((buf
[RTC_SEC
] >> 4) & 0x7) * 10
109 + (buf
[RTC_SEC
] & 0x0f);
113 static int data_calc(unsigned char *buf
, struct rtc_time
*tm
, int len
)
115 unsigned char high
, low
;
120 high
= (tm
->tm_year
+ 1900) / 1000;
121 low
= (tm
->tm_year
+ 1900) / 100;
122 low
= low
- high
* 10;
123 buf
[RTC_YEAR2
] = (high
<< 4) + low
;
124 high
= (tm
->tm_year
+ 1900) / 10;
125 low
= tm
->tm_year
+ 1900;
126 low
= low
- high
* 10;
127 high
= high
- (high
/ 10) * 10;
128 buf
[RTC_YEAR1
] = (high
<< 4) + low
;
129 high
= tm
->tm_mon
/ 10;
131 low
= low
- high
* 10;
132 buf
[RTC_MONTH
] = (high
<< 4) + low
;
133 high
= tm
->tm_mday
/ 10;
135 low
= low
- high
* 10;
136 buf
[RTC_DATE
] = (high
<< 4) + low
;
137 buf
[RTC_WEEKDAY
] = tm
->tm_wday
;
138 high
= tm
->tm_hour
/ 10;
140 low
= low
- high
* 10;
141 buf
[RTC_HOUR
] = (high
<< 4) + low
;
142 high
= tm
->tm_min
/ 10;
144 low
= low
- high
* 10;
145 buf
[RTC_MIN
] = (high
<< 4) + low
;
146 high
= tm
->tm_sec
/ 10;
148 low
= low
- high
* 10;
149 buf
[RTC_SEC
] = (high
<< 4) + low
;
153 static int max8925_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
155 struct max8925_rtc_info
*info
= dev_get_drvdata(dev
);
156 unsigned char buf
[TIME_NUM
];
159 ret
= max8925_bulk_read(info
->rtc
, MAX8925_RTC_SEC
, TIME_NUM
, buf
);
162 ret
= tm_calc(tm
, buf
, TIME_NUM
);
167 static int max8925_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
169 struct max8925_rtc_info
*info
= dev_get_drvdata(dev
);
170 unsigned char buf
[TIME_NUM
];
173 ret
= data_calc(buf
, tm
, TIME_NUM
);
176 ret
= max8925_bulk_write(info
->rtc
, MAX8925_RTC_SEC
, TIME_NUM
, buf
);
181 static int max8925_rtc_read_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
183 struct max8925_rtc_info
*info
= dev_get_drvdata(dev
);
184 unsigned char buf
[TIME_NUM
];
187 ret
= max8925_bulk_read(info
->rtc
, MAX8925_ALARM0_SEC
, TIME_NUM
, buf
);
190 ret
= tm_calc(&alrm
->time
, buf
, TIME_NUM
);
193 ret
= max8925_reg_read(info
->rtc
, MAX8925_RTC_IRQ_MASK
);
196 if (ret
& ALARM0_IRQ
) {
199 ret
= max8925_reg_read(info
->rtc
, MAX8925_ALARM0_CNTL
);
207 ret
= max8925_reg_read(info
->rtc
, MAX8925_RTC_STATUS
);
210 if (ret
& ALARM0_STATUS
)
219 static int max8925_rtc_set_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
221 struct max8925_rtc_info
*info
= dev_get_drvdata(dev
);
222 unsigned char buf
[TIME_NUM
];
225 ret
= data_calc(buf
, &alrm
->time
, TIME_NUM
);
228 ret
= max8925_bulk_write(info
->rtc
, MAX8925_ALARM0_SEC
, TIME_NUM
, buf
);
232 /* only enable alarm on year/month/day/hour/min/sec */
233 ret
= max8925_reg_write(info
->rtc
, MAX8925_ALARM0_CNTL
, 0x77);
235 ret
= max8925_reg_write(info
->rtc
, MAX8925_ALARM0_CNTL
, 0x0);
242 static const struct rtc_class_ops max8925_rtc_ops
= {
243 .read_time
= max8925_rtc_read_time
,
244 .set_time
= max8925_rtc_set_time
,
245 .read_alarm
= max8925_rtc_read_alarm
,
246 .set_alarm
= max8925_rtc_set_alarm
,
249 static int __devinit
max8925_rtc_probe(struct platform_device
*pdev
)
251 struct max8925_chip
*chip
= dev_get_drvdata(pdev
->dev
.parent
);
252 struct max8925_rtc_info
*info
;
255 info
= kzalloc(sizeof(struct max8925_rtc_info
), GFP_KERNEL
);
259 info
->rtc
= chip
->rtc
;
260 info
->dev
= &pdev
->dev
;
261 irq
= chip
->irq_base
+ MAX8925_IRQ_RTC_ALARM0
;
263 ret
= request_threaded_irq(irq
, NULL
, rtc_update_handler
,
264 IRQF_ONESHOT
, "rtc-alarm0", info
);
266 dev_err(chip
->dev
, "Failed to request IRQ: #%d: %d\n",
271 dev_set_drvdata(&pdev
->dev
, info
);
272 /* XXX - isn't this redundant? */
273 platform_set_drvdata(pdev
, info
);
275 device_init_wakeup(&pdev
->dev
, 1);
277 info
->rtc_dev
= rtc_device_register("max8925-rtc", &pdev
->dev
,
278 &max8925_rtc_ops
, THIS_MODULE
);
279 ret
= PTR_ERR(info
->rtc_dev
);
280 if (IS_ERR(info
->rtc_dev
)) {
281 dev_err(&pdev
->dev
, "Failed to register RTC device: %d\n", ret
);
287 platform_set_drvdata(pdev
, NULL
);
288 free_irq(chip
->irq_base
+ MAX8925_IRQ_RTC_ALARM0
, info
);
294 static int __devexit
max8925_rtc_remove(struct platform_device
*pdev
)
296 struct max8925_rtc_info
*info
= platform_get_drvdata(pdev
);
299 free_irq(info
->chip
->irq_base
+ MAX8925_IRQ_RTC_ALARM0
, info
);
300 rtc_device_unregister(info
->rtc_dev
);
306 #ifdef CONFIG_PM_SLEEP
307 static int max8925_rtc_suspend(struct device
*dev
)
309 struct platform_device
*pdev
= to_platform_device(dev
);
310 struct max8925_chip
*chip
= dev_get_drvdata(pdev
->dev
.parent
);
312 if (device_may_wakeup(dev
))
313 chip
->wakeup_flag
|= 1 << MAX8925_IRQ_RTC_ALARM0
;
316 static int max8925_rtc_resume(struct device
*dev
)
318 struct platform_device
*pdev
= to_platform_device(dev
);
319 struct max8925_chip
*chip
= dev_get_drvdata(pdev
->dev
.parent
);
321 if (device_may_wakeup(dev
))
322 chip
->wakeup_flag
&= ~(1 << MAX8925_IRQ_RTC_ALARM0
);
327 static SIMPLE_DEV_PM_OPS(max8925_rtc_pm_ops
, max8925_rtc_suspend
, max8925_rtc_resume
);
329 static struct platform_driver max8925_rtc_driver
= {
331 .name
= "max8925-rtc",
332 .owner
= THIS_MODULE
,
333 .pm
= &max8925_rtc_pm_ops
,
335 .probe
= max8925_rtc_probe
,
336 .remove
= __devexit_p(max8925_rtc_remove
),
339 module_platform_driver(max8925_rtc_driver
);
341 MODULE_DESCRIPTION("Maxim MAX8925 RTC driver");
342 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
343 MODULE_LICENSE("GPL");