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
;
75 static irqreturn_t
rtc_update_handler(int irq
, void *data
)
77 struct max8925_rtc_info
*info
= (struct max8925_rtc_info
*)data
;
79 /* disable ALARM0 except for 1SEC alarm */
80 max8925_set_bits(info
->rtc
, MAX8925_ALARM0_CNTL
, 0x7f, 0);
81 rtc_update_irq(info
->rtc_dev
, 1, RTC_IRQF
| RTC_AF
);
85 static int tm_calc(struct rtc_time
*tm
, unsigned char *buf
, int len
)
89 tm
->tm_year
= (buf
[RTC_YEAR2
] >> 4) * 1000
90 + (buf
[RTC_YEAR2
] & 0xf) * 100
91 + (buf
[RTC_YEAR1
] >> 4) * 10
92 + (buf
[RTC_YEAR1
] & 0xf);
94 tm
->tm_mon
= ((buf
[RTC_MONTH
] >> 4) & 0x01) * 10
95 + (buf
[RTC_MONTH
] & 0x0f);
96 tm
->tm_mday
= ((buf
[RTC_DATE
] >> 4) & 0x03) * 10
97 + (buf
[RTC_DATE
] & 0x0f);
98 tm
->tm_wday
= buf
[RTC_WEEKDAY
] & 0x07;
99 if (buf
[RTC_HOUR
] & HOUR_12
) {
100 tm
->tm_hour
= ((buf
[RTC_HOUR
] >> 4) & 0x1) * 10
101 + (buf
[RTC_HOUR
] & 0x0f);
102 if (buf
[RTC_HOUR
] & HOUR_AM_PM
)
105 tm
->tm_hour
= ((buf
[RTC_HOUR
] >> 4) & 0x03) * 10
106 + (buf
[RTC_HOUR
] & 0x0f);
107 tm
->tm_min
= ((buf
[RTC_MIN
] >> 4) & 0x7) * 10
108 + (buf
[RTC_MIN
] & 0x0f);
109 tm
->tm_sec
= ((buf
[RTC_SEC
] >> 4) & 0x7) * 10
110 + (buf
[RTC_SEC
] & 0x0f);
114 static int data_calc(unsigned char *buf
, struct rtc_time
*tm
, int len
)
116 unsigned char high
, low
;
121 high
= (tm
->tm_year
+ 1900) / 1000;
122 low
= (tm
->tm_year
+ 1900) / 100;
123 low
= low
- high
* 10;
124 buf
[RTC_YEAR2
] = (high
<< 4) + low
;
125 high
= (tm
->tm_year
+ 1900) / 10;
126 low
= tm
->tm_year
+ 1900;
127 low
= low
- high
* 10;
128 high
= high
- (high
/ 10) * 10;
129 buf
[RTC_YEAR1
] = (high
<< 4) + low
;
130 high
= tm
->tm_mon
/ 10;
132 low
= low
- high
* 10;
133 buf
[RTC_MONTH
] = (high
<< 4) + low
;
134 high
= tm
->tm_mday
/ 10;
136 low
= low
- high
* 10;
137 buf
[RTC_DATE
] = (high
<< 4) + low
;
138 buf
[RTC_WEEKDAY
] = tm
->tm_wday
;
139 high
= tm
->tm_hour
/ 10;
141 low
= low
- high
* 10;
142 buf
[RTC_HOUR
] = (high
<< 4) + low
;
143 high
= tm
->tm_min
/ 10;
145 low
= low
- high
* 10;
146 buf
[RTC_MIN
] = (high
<< 4) + low
;
147 high
= tm
->tm_sec
/ 10;
149 low
= low
- high
* 10;
150 buf
[RTC_SEC
] = (high
<< 4) + low
;
154 static int max8925_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
156 struct max8925_rtc_info
*info
= dev_get_drvdata(dev
);
157 unsigned char buf
[TIME_NUM
];
160 ret
= max8925_bulk_read(info
->rtc
, MAX8925_RTC_SEC
, TIME_NUM
, buf
);
163 ret
= tm_calc(tm
, buf
, TIME_NUM
);
168 static int max8925_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
170 struct max8925_rtc_info
*info
= dev_get_drvdata(dev
);
171 unsigned char buf
[TIME_NUM
];
174 ret
= data_calc(buf
, tm
, TIME_NUM
);
177 ret
= max8925_bulk_write(info
->rtc
, MAX8925_RTC_SEC
, TIME_NUM
, buf
);
182 static int max8925_rtc_read_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
184 struct max8925_rtc_info
*info
= dev_get_drvdata(dev
);
185 unsigned char buf
[TIME_NUM
];
188 ret
= max8925_bulk_read(info
->rtc
, MAX8925_ALARM0_SEC
, TIME_NUM
, buf
);
191 ret
= tm_calc(&alrm
->time
, buf
, TIME_NUM
);
194 ret
= max8925_reg_read(info
->rtc
, MAX8925_RTC_IRQ_MASK
);
197 if (ret
& ALARM0_IRQ
) {
200 ret
= max8925_reg_read(info
->rtc
, MAX8925_ALARM0_CNTL
);
208 ret
= max8925_reg_read(info
->rtc
, MAX8925_RTC_STATUS
);
211 if (ret
& ALARM0_STATUS
)
220 static int max8925_rtc_set_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
222 struct max8925_rtc_info
*info
= dev_get_drvdata(dev
);
223 unsigned char buf
[TIME_NUM
];
226 ret
= data_calc(buf
, &alrm
->time
, TIME_NUM
);
229 ret
= max8925_bulk_write(info
->rtc
, MAX8925_ALARM0_SEC
, TIME_NUM
, buf
);
233 /* only enable alarm on year/month/day/hour/min/sec */
234 ret
= max8925_reg_write(info
->rtc
, MAX8925_ALARM0_CNTL
, 0x77);
236 ret
= max8925_reg_write(info
->rtc
, MAX8925_ALARM0_CNTL
, 0x0);
243 static const struct rtc_class_ops max8925_rtc_ops
= {
244 .read_time
= max8925_rtc_read_time
,
245 .set_time
= max8925_rtc_set_time
,
246 .read_alarm
= max8925_rtc_read_alarm
,
247 .set_alarm
= max8925_rtc_set_alarm
,
250 static int max8925_rtc_probe(struct platform_device
*pdev
)
252 struct max8925_chip
*chip
= dev_get_drvdata(pdev
->dev
.parent
);
253 struct max8925_rtc_info
*info
;
256 info
= devm_kzalloc(&pdev
->dev
, sizeof(struct max8925_rtc_info
),
261 info
->rtc
= chip
->rtc
;
262 info
->dev
= &pdev
->dev
;
263 info
->irq
= platform_get_irq(pdev
, 0);
265 ret
= devm_request_threaded_irq(&pdev
->dev
, info
->irq
, NULL
,
266 rtc_update_handler
, IRQF_ONESHOT
,
269 dev_err(chip
->dev
, "Failed to request IRQ: #%d: %d\n",
274 dev_set_drvdata(&pdev
->dev
, info
);
275 /* XXX - isn't this redundant? */
276 platform_set_drvdata(pdev
, info
);
278 device_init_wakeup(&pdev
->dev
, 1);
280 info
->rtc_dev
= devm_rtc_device_register(&pdev
->dev
, "max8925-rtc",
281 &max8925_rtc_ops
, THIS_MODULE
);
282 ret
= PTR_ERR(info
->rtc_dev
);
283 if (IS_ERR(info
->rtc_dev
)) {
284 dev_err(&pdev
->dev
, "Failed to register RTC device: %d\n", ret
);
291 #ifdef CONFIG_PM_SLEEP
292 static int max8925_rtc_suspend(struct device
*dev
)
294 struct platform_device
*pdev
= to_platform_device(dev
);
295 struct max8925_chip
*chip
= dev_get_drvdata(pdev
->dev
.parent
);
297 if (device_may_wakeup(dev
))
298 chip
->wakeup_flag
|= 1 << MAX8925_IRQ_RTC_ALARM0
;
301 static int max8925_rtc_resume(struct device
*dev
)
303 struct platform_device
*pdev
= to_platform_device(dev
);
304 struct max8925_chip
*chip
= dev_get_drvdata(pdev
->dev
.parent
);
306 if (device_may_wakeup(dev
))
307 chip
->wakeup_flag
&= ~(1 << MAX8925_IRQ_RTC_ALARM0
);
312 static SIMPLE_DEV_PM_OPS(max8925_rtc_pm_ops
, max8925_rtc_suspend
, max8925_rtc_resume
);
314 static struct platform_driver max8925_rtc_driver
= {
316 .name
= "max8925-rtc",
317 .owner
= THIS_MODULE
,
318 .pm
= &max8925_rtc_pm_ops
,
320 .probe
= max8925_rtc_probe
,
323 module_platform_driver(max8925_rtc_driver
);
325 MODULE_DESCRIPTION("Maxim MAX8925 RTC driver");
326 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
327 MODULE_LICENSE("GPL");