xref: /linux/drivers/rtc/rtc-twl.c (revision 8dcebaa9a0ae8a0487f4342f3d56d2cb1c980860)
1b07682b6SSantosh Shilimkar /*
2ef3b7d0dSBalaji T K  * rtc-twl.c -- TWL Real Time Clock interface
3b07682b6SSantosh Shilimkar  *
4b07682b6SSantosh Shilimkar  * Copyright (C) 2007 MontaVista Software, Inc
5b07682b6SSantosh Shilimkar  * Author: Alexandre Rusev <source@mvista.com>
6b07682b6SSantosh Shilimkar  *
7b07682b6SSantosh Shilimkar  * Based on original TI driver twl4030-rtc.c
8b07682b6SSantosh Shilimkar  *   Copyright (C) 2006 Texas Instruments, Inc.
9b07682b6SSantosh Shilimkar  *
10b07682b6SSantosh Shilimkar  * Based on rtc-omap.c
11b07682b6SSantosh Shilimkar  *   Copyright (C) 2003 MontaVista Software, Inc.
12b07682b6SSantosh Shilimkar  *   Author: George G. Davis <gdavis@mvista.com> or <source@mvista.com>
13b07682b6SSantosh Shilimkar  *   Copyright (C) 2006 David Brownell
14b07682b6SSantosh Shilimkar  *
15b07682b6SSantosh Shilimkar  * This program is free software; you can redistribute it and/or
16b07682b6SSantosh Shilimkar  * modify it under the terms of the GNU General Public License
17b07682b6SSantosh Shilimkar  * as published by the Free Software Foundation; either version
18b07682b6SSantosh Shilimkar  * 2 of the License, or (at your option) any later version.
19b07682b6SSantosh Shilimkar  */
20b07682b6SSantosh Shilimkar 
21b07682b6SSantosh Shilimkar #include <linux/kernel.h>
22b07682b6SSantosh Shilimkar #include <linux/errno.h>
23b07682b6SSantosh Shilimkar #include <linux/init.h>
24b07682b6SSantosh Shilimkar #include <linux/module.h>
25b07682b6SSantosh Shilimkar #include <linux/types.h>
26b07682b6SSantosh Shilimkar #include <linux/rtc.h>
27b07682b6SSantosh Shilimkar #include <linux/bcd.h>
28b07682b6SSantosh Shilimkar #include <linux/platform_device.h>
29b07682b6SSantosh Shilimkar #include <linux/interrupt.h>
30b07682b6SSantosh Shilimkar 
31b07682b6SSantosh Shilimkar #include <linux/i2c/twl.h>
32b07682b6SSantosh Shilimkar 
33b07682b6SSantosh Shilimkar 
34b07682b6SSantosh Shilimkar /*
35b07682b6SSantosh Shilimkar  * RTC block register offsets (use TWL_MODULE_RTC)
36b07682b6SSantosh Shilimkar  */
37a6b49ffdSBalaji T K enum {
38a6b49ffdSBalaji T K 	REG_SECONDS_REG = 0,
39a6b49ffdSBalaji T K 	REG_MINUTES_REG,
40a6b49ffdSBalaji T K 	REG_HOURS_REG,
41a6b49ffdSBalaji T K 	REG_DAYS_REG,
42a6b49ffdSBalaji T K 	REG_MONTHS_REG,
43a6b49ffdSBalaji T K 	REG_YEARS_REG,
44a6b49ffdSBalaji T K 	REG_WEEKS_REG,
45b07682b6SSantosh Shilimkar 
46a6b49ffdSBalaji T K 	REG_ALARM_SECONDS_REG,
47a6b49ffdSBalaji T K 	REG_ALARM_MINUTES_REG,
48a6b49ffdSBalaji T K 	REG_ALARM_HOURS_REG,
49a6b49ffdSBalaji T K 	REG_ALARM_DAYS_REG,
50a6b49ffdSBalaji T K 	REG_ALARM_MONTHS_REG,
51a6b49ffdSBalaji T K 	REG_ALARM_YEARS_REG,
52b07682b6SSantosh Shilimkar 
53a6b49ffdSBalaji T K 	REG_RTC_CTRL_REG,
54a6b49ffdSBalaji T K 	REG_RTC_STATUS_REG,
55a6b49ffdSBalaji T K 	REG_RTC_INTERRUPTS_REG,
56b07682b6SSantosh Shilimkar 
57a6b49ffdSBalaji T K 	REG_RTC_COMP_LSB_REG,
58a6b49ffdSBalaji T K 	REG_RTC_COMP_MSB_REG,
59a6b49ffdSBalaji T K };
602e84067bSTobias Klauser static const u8 twl4030_rtc_reg_map[] = {
61a6b49ffdSBalaji T K 	[REG_SECONDS_REG] = 0x00,
62a6b49ffdSBalaji T K 	[REG_MINUTES_REG] = 0x01,
63a6b49ffdSBalaji T K 	[REG_HOURS_REG] = 0x02,
64a6b49ffdSBalaji T K 	[REG_DAYS_REG] = 0x03,
65a6b49ffdSBalaji T K 	[REG_MONTHS_REG] = 0x04,
66a6b49ffdSBalaji T K 	[REG_YEARS_REG] = 0x05,
67a6b49ffdSBalaji T K 	[REG_WEEKS_REG] = 0x06,
68a6b49ffdSBalaji T K 
69a6b49ffdSBalaji T K 	[REG_ALARM_SECONDS_REG] = 0x07,
70a6b49ffdSBalaji T K 	[REG_ALARM_MINUTES_REG] = 0x08,
71a6b49ffdSBalaji T K 	[REG_ALARM_HOURS_REG] = 0x09,
72a6b49ffdSBalaji T K 	[REG_ALARM_DAYS_REG] = 0x0A,
73a6b49ffdSBalaji T K 	[REG_ALARM_MONTHS_REG] = 0x0B,
74a6b49ffdSBalaji T K 	[REG_ALARM_YEARS_REG] = 0x0C,
75a6b49ffdSBalaji T K 
76a6b49ffdSBalaji T K 	[REG_RTC_CTRL_REG] = 0x0D,
77a6b49ffdSBalaji T K 	[REG_RTC_STATUS_REG] = 0x0E,
78a6b49ffdSBalaji T K 	[REG_RTC_INTERRUPTS_REG] = 0x0F,
79a6b49ffdSBalaji T K 
80a6b49ffdSBalaji T K 	[REG_RTC_COMP_LSB_REG] = 0x10,
81a6b49ffdSBalaji T K 	[REG_RTC_COMP_MSB_REG] = 0x11,
82a6b49ffdSBalaji T K };
832e84067bSTobias Klauser static const u8 twl6030_rtc_reg_map[] = {
84a6b49ffdSBalaji T K 	[REG_SECONDS_REG] = 0x00,
85a6b49ffdSBalaji T K 	[REG_MINUTES_REG] = 0x01,
86a6b49ffdSBalaji T K 	[REG_HOURS_REG] = 0x02,
87a6b49ffdSBalaji T K 	[REG_DAYS_REG] = 0x03,
88a6b49ffdSBalaji T K 	[REG_MONTHS_REG] = 0x04,
89a6b49ffdSBalaji T K 	[REG_YEARS_REG] = 0x05,
90a6b49ffdSBalaji T K 	[REG_WEEKS_REG] = 0x06,
91a6b49ffdSBalaji T K 
92a6b49ffdSBalaji T K 	[REG_ALARM_SECONDS_REG] = 0x08,
93a6b49ffdSBalaji T K 	[REG_ALARM_MINUTES_REG] = 0x09,
94a6b49ffdSBalaji T K 	[REG_ALARM_HOURS_REG] = 0x0A,
95a6b49ffdSBalaji T K 	[REG_ALARM_DAYS_REG] = 0x0B,
96a6b49ffdSBalaji T K 	[REG_ALARM_MONTHS_REG] = 0x0C,
97a6b49ffdSBalaji T K 	[REG_ALARM_YEARS_REG] = 0x0D,
98a6b49ffdSBalaji T K 
99a6b49ffdSBalaji T K 	[REG_RTC_CTRL_REG] = 0x10,
100a6b49ffdSBalaji T K 	[REG_RTC_STATUS_REG] = 0x11,
101a6b49ffdSBalaji T K 	[REG_RTC_INTERRUPTS_REG] = 0x12,
102a6b49ffdSBalaji T K 
103a6b49ffdSBalaji T K 	[REG_RTC_COMP_LSB_REG] = 0x13,
104a6b49ffdSBalaji T K 	[REG_RTC_COMP_MSB_REG] = 0x14,
105a6b49ffdSBalaji T K };
106b07682b6SSantosh Shilimkar 
107b07682b6SSantosh Shilimkar /* RTC_CTRL_REG bitfields */
108b07682b6SSantosh Shilimkar #define BIT_RTC_CTRL_REG_STOP_RTC_M              0x01
109b07682b6SSantosh Shilimkar #define BIT_RTC_CTRL_REG_ROUND_30S_M             0x02
110b07682b6SSantosh Shilimkar #define BIT_RTC_CTRL_REG_AUTO_COMP_M             0x04
111b07682b6SSantosh Shilimkar #define BIT_RTC_CTRL_REG_MODE_12_24_M            0x08
112b07682b6SSantosh Shilimkar #define BIT_RTC_CTRL_REG_TEST_MODE_M             0x10
113b07682b6SSantosh Shilimkar #define BIT_RTC_CTRL_REG_SET_32_COUNTER_M        0x20
114b07682b6SSantosh Shilimkar #define BIT_RTC_CTRL_REG_GET_TIME_M              0x40
115f3ec434cSKonstantin Shlyakhovoy #define BIT_RTC_CTRL_REG_RTC_V_OPT               0x80
116b07682b6SSantosh Shilimkar 
117b07682b6SSantosh Shilimkar /* RTC_STATUS_REG bitfields */
118b07682b6SSantosh Shilimkar #define BIT_RTC_STATUS_REG_RUN_M                 0x02
119b07682b6SSantosh Shilimkar #define BIT_RTC_STATUS_REG_1S_EVENT_M            0x04
120b07682b6SSantosh Shilimkar #define BIT_RTC_STATUS_REG_1M_EVENT_M            0x08
121b07682b6SSantosh Shilimkar #define BIT_RTC_STATUS_REG_1H_EVENT_M            0x10
122b07682b6SSantosh Shilimkar #define BIT_RTC_STATUS_REG_1D_EVENT_M            0x20
123b07682b6SSantosh Shilimkar #define BIT_RTC_STATUS_REG_ALARM_M               0x40
124b07682b6SSantosh Shilimkar #define BIT_RTC_STATUS_REG_POWER_UP_M            0x80
125b07682b6SSantosh Shilimkar 
126b07682b6SSantosh Shilimkar /* RTC_INTERRUPTS_REG bitfields */
127b07682b6SSantosh Shilimkar #define BIT_RTC_INTERRUPTS_REG_EVERY_M           0x03
128b07682b6SSantosh Shilimkar #define BIT_RTC_INTERRUPTS_REG_IT_TIMER_M        0x04
129b07682b6SSantosh Shilimkar #define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M        0x08
130b07682b6SSantosh Shilimkar 
131b07682b6SSantosh Shilimkar 
132b07682b6SSantosh Shilimkar /* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
133b07682b6SSantosh Shilimkar #define ALL_TIME_REGS		6
134b07682b6SSantosh Shilimkar 
135b07682b6SSantosh Shilimkar /*----------------------------------------------------------------------*/
136a6b49ffdSBalaji T K static u8  *rtc_reg_map;
137b07682b6SSantosh Shilimkar 
138b07682b6SSantosh Shilimkar /*
139ef3b7d0dSBalaji T K  * Supports 1 byte read from TWL RTC register.
140b07682b6SSantosh Shilimkar  */
141ef3b7d0dSBalaji T K static int twl_rtc_read_u8(u8 *data, u8 reg)
142b07682b6SSantosh Shilimkar {
143b07682b6SSantosh Shilimkar 	int ret;
144b07682b6SSantosh Shilimkar 
145a6b49ffdSBalaji T K 	ret = twl_i2c_read_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg]));
146b07682b6SSantosh Shilimkar 	if (ret < 0)
147ef3b7d0dSBalaji T K 		pr_err("twl_rtc: Could not read TWL"
148b07682b6SSantosh Shilimkar 		       "register %X - error %d\n", reg, ret);
149b07682b6SSantosh Shilimkar 	return ret;
150b07682b6SSantosh Shilimkar }
151b07682b6SSantosh Shilimkar 
152b07682b6SSantosh Shilimkar /*
153ef3b7d0dSBalaji T K  * Supports 1 byte write to TWL RTC registers.
154b07682b6SSantosh Shilimkar  */
155ef3b7d0dSBalaji T K static int twl_rtc_write_u8(u8 data, u8 reg)
156b07682b6SSantosh Shilimkar {
157b07682b6SSantosh Shilimkar 	int ret;
158b07682b6SSantosh Shilimkar 
159a6b49ffdSBalaji T K 	ret = twl_i2c_write_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg]));
160b07682b6SSantosh Shilimkar 	if (ret < 0)
161ef3b7d0dSBalaji T K 		pr_err("twl_rtc: Could not write TWL"
162b07682b6SSantosh Shilimkar 		       "register %X - error %d\n", reg, ret);
163b07682b6SSantosh Shilimkar 	return ret;
164b07682b6SSantosh Shilimkar }
165b07682b6SSantosh Shilimkar 
166b07682b6SSantosh Shilimkar /*
167b07682b6SSantosh Shilimkar  * Cache the value for timer/alarm interrupts register; this is
168b07682b6SSantosh Shilimkar  * only changed by callers holding rtc ops lock (or resume).
169b07682b6SSantosh Shilimkar  */
170b07682b6SSantosh Shilimkar static unsigned char rtc_irq_bits;
171b07682b6SSantosh Shilimkar 
172b07682b6SSantosh Shilimkar /*
173b07682b6SSantosh Shilimkar  * Enable 1/second update and/or alarm interrupts.
174b07682b6SSantosh Shilimkar  */
175b07682b6SSantosh Shilimkar static int set_rtc_irq_bit(unsigned char bit)
176b07682b6SSantosh Shilimkar {
177b07682b6SSantosh Shilimkar 	unsigned char val;
178b07682b6SSantosh Shilimkar 	int ret;
179b07682b6SSantosh Shilimkar 
180ce9f6506SVenu Byravarasu 	/* if the bit is set, return from here */
181ce9f6506SVenu Byravarasu 	if (rtc_irq_bits & bit)
182ce9f6506SVenu Byravarasu 		return 0;
183ce9f6506SVenu Byravarasu 
184b07682b6SSantosh Shilimkar 	val = rtc_irq_bits | bit;
185b07682b6SSantosh Shilimkar 	val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M;
186ef3b7d0dSBalaji T K 	ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
187b07682b6SSantosh Shilimkar 	if (ret == 0)
188b07682b6SSantosh Shilimkar 		rtc_irq_bits = val;
189b07682b6SSantosh Shilimkar 
190b07682b6SSantosh Shilimkar 	return ret;
191b07682b6SSantosh Shilimkar }
192b07682b6SSantosh Shilimkar 
193b07682b6SSantosh Shilimkar /*
194b07682b6SSantosh Shilimkar  * Disable update and/or alarm interrupts.
195b07682b6SSantosh Shilimkar  */
196b07682b6SSantosh Shilimkar static int mask_rtc_irq_bit(unsigned char bit)
197b07682b6SSantosh Shilimkar {
198b07682b6SSantosh Shilimkar 	unsigned char val;
199b07682b6SSantosh Shilimkar 	int ret;
200b07682b6SSantosh Shilimkar 
201ce9f6506SVenu Byravarasu 	/* if the bit is clear, return from here */
202ce9f6506SVenu Byravarasu 	if (!(rtc_irq_bits & bit))
203ce9f6506SVenu Byravarasu 		return 0;
204ce9f6506SVenu Byravarasu 
205b07682b6SSantosh Shilimkar 	val = rtc_irq_bits & ~bit;
206ef3b7d0dSBalaji T K 	ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
207b07682b6SSantosh Shilimkar 	if (ret == 0)
208b07682b6SSantosh Shilimkar 		rtc_irq_bits = val;
209b07682b6SSantosh Shilimkar 
210b07682b6SSantosh Shilimkar 	return ret;
211b07682b6SSantosh Shilimkar }
212b07682b6SSantosh Shilimkar 
213ef3b7d0dSBalaji T K static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
214b07682b6SSantosh Shilimkar {
215b07682b6SSantosh Shilimkar 	int ret;
216b07682b6SSantosh Shilimkar 
217b07682b6SSantosh Shilimkar 	if (enabled)
218b07682b6SSantosh Shilimkar 		ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
219b07682b6SSantosh Shilimkar 	else
220b07682b6SSantosh Shilimkar 		ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
221b07682b6SSantosh Shilimkar 
222b07682b6SSantosh Shilimkar 	return ret;
223b07682b6SSantosh Shilimkar }
224b07682b6SSantosh Shilimkar 
225b07682b6SSantosh Shilimkar /*
226ef3b7d0dSBalaji T K  * Gets current TWL RTC time and date parameters.
227b07682b6SSantosh Shilimkar  *
228b07682b6SSantosh Shilimkar  * The RTC's time/alarm representation is not what gmtime(3) requires
229b07682b6SSantosh Shilimkar  * Linux to use:
230b07682b6SSantosh Shilimkar  *
231b07682b6SSantosh Shilimkar  *  - Months are 1..12 vs Linux 0-11
232b07682b6SSantosh Shilimkar  *  - Years are 0..99 vs Linux 1900..N (we assume 21st century)
233b07682b6SSantosh Shilimkar  */
234ef3b7d0dSBalaji T K static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm)
235b07682b6SSantosh Shilimkar {
236b07682b6SSantosh Shilimkar 	unsigned char rtc_data[ALL_TIME_REGS + 1];
237b07682b6SSantosh Shilimkar 	int ret;
238b07682b6SSantosh Shilimkar 	u8 save_control;
239f3ec434cSKonstantin Shlyakhovoy 	u8 rtc_control;
240b07682b6SSantosh Shilimkar 
241ef3b7d0dSBalaji T K 	ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
242f3ec434cSKonstantin Shlyakhovoy 	if (ret < 0) {
243f3ec434cSKonstantin Shlyakhovoy 		dev_err(dev, "%s: reading CTRL_REG, error %d\n", __func__, ret);
244b07682b6SSantosh Shilimkar 		return ret;
245f3ec434cSKonstantin Shlyakhovoy 	}
246f3ec434cSKonstantin Shlyakhovoy 	/* for twl6030/32 make sure BIT_RTC_CTRL_REG_GET_TIME_M is clear */
247f3ec434cSKonstantin Shlyakhovoy 	if (twl_class_is_6030()) {
248f3ec434cSKonstantin Shlyakhovoy 		if (save_control & BIT_RTC_CTRL_REG_GET_TIME_M) {
249f3ec434cSKonstantin Shlyakhovoy 			save_control &= ~BIT_RTC_CTRL_REG_GET_TIME_M;
250ef3b7d0dSBalaji T K 			ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
251f3ec434cSKonstantin Shlyakhovoy 			if (ret < 0) {
252f3ec434cSKonstantin Shlyakhovoy 				dev_err(dev, "%s clr GET_TIME, error %d\n",
253f3ec434cSKonstantin Shlyakhovoy 					__func__, ret);
254b07682b6SSantosh Shilimkar 				return ret;
255f3ec434cSKonstantin Shlyakhovoy 			}
256f3ec434cSKonstantin Shlyakhovoy 		}
257f3ec434cSKonstantin Shlyakhovoy 	}
258f3ec434cSKonstantin Shlyakhovoy 
259f3ec434cSKonstantin Shlyakhovoy 	/* Copy RTC counting registers to static registers or latches */
260f3ec434cSKonstantin Shlyakhovoy 	rtc_control = save_control | BIT_RTC_CTRL_REG_GET_TIME_M;
261f3ec434cSKonstantin Shlyakhovoy 
262f3ec434cSKonstantin Shlyakhovoy 	/* for twl6030/32 enable read access to static shadowed registers */
263f3ec434cSKonstantin Shlyakhovoy 	if (twl_class_is_6030())
264f3ec434cSKonstantin Shlyakhovoy 		rtc_control |= BIT_RTC_CTRL_REG_RTC_V_OPT;
265f3ec434cSKonstantin Shlyakhovoy 
266f3ec434cSKonstantin Shlyakhovoy 	ret = twl_rtc_write_u8(rtc_control, REG_RTC_CTRL_REG);
267f3ec434cSKonstantin Shlyakhovoy 	if (ret < 0) {
268f3ec434cSKonstantin Shlyakhovoy 		dev_err(dev, "%s: writing CTRL_REG, error %d\n", __func__, ret);
269f3ec434cSKonstantin Shlyakhovoy 		return ret;
270f3ec434cSKonstantin Shlyakhovoy 	}
271b07682b6SSantosh Shilimkar 
272ef3b7d0dSBalaji T K 	ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data,
273a6b49ffdSBalaji T K 			(rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS);
274b07682b6SSantosh Shilimkar 
275b07682b6SSantosh Shilimkar 	if (ret < 0) {
276f3ec434cSKonstantin Shlyakhovoy 		dev_err(dev, "%s: reading data, error %d\n", __func__, ret);
277b07682b6SSantosh Shilimkar 		return ret;
278b07682b6SSantosh Shilimkar 	}
279b07682b6SSantosh Shilimkar 
280f3ec434cSKonstantin Shlyakhovoy 	/* for twl6030 restore original state of rtc control register */
281f3ec434cSKonstantin Shlyakhovoy 	if (twl_class_is_6030()) {
282f3ec434cSKonstantin Shlyakhovoy 		ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
283f3ec434cSKonstantin Shlyakhovoy 		if (ret < 0) {
284f3ec434cSKonstantin Shlyakhovoy 			dev_err(dev, "%s: restore CTRL_REG, error %d\n",
285f3ec434cSKonstantin Shlyakhovoy 				__func__, ret);
286f3ec434cSKonstantin Shlyakhovoy 			return ret;
287f3ec434cSKonstantin Shlyakhovoy 		}
288f3ec434cSKonstantin Shlyakhovoy 	}
289f3ec434cSKonstantin Shlyakhovoy 
290b07682b6SSantosh Shilimkar 	tm->tm_sec = bcd2bin(rtc_data[0]);
291b07682b6SSantosh Shilimkar 	tm->tm_min = bcd2bin(rtc_data[1]);
292b07682b6SSantosh Shilimkar 	tm->tm_hour = bcd2bin(rtc_data[2]);
293b07682b6SSantosh Shilimkar 	tm->tm_mday = bcd2bin(rtc_data[3]);
294b07682b6SSantosh Shilimkar 	tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
295b07682b6SSantosh Shilimkar 	tm->tm_year = bcd2bin(rtc_data[5]) + 100;
296b07682b6SSantosh Shilimkar 
297b07682b6SSantosh Shilimkar 	return ret;
298b07682b6SSantosh Shilimkar }
299b07682b6SSantosh Shilimkar 
300ef3b7d0dSBalaji T K static int twl_rtc_set_time(struct device *dev, struct rtc_time *tm)
301b07682b6SSantosh Shilimkar {
302b07682b6SSantosh Shilimkar 	unsigned char save_control;
303b07682b6SSantosh Shilimkar 	unsigned char rtc_data[ALL_TIME_REGS + 1];
304b07682b6SSantosh Shilimkar 	int ret;
305b07682b6SSantosh Shilimkar 
306b07682b6SSantosh Shilimkar 	rtc_data[1] = bin2bcd(tm->tm_sec);
307b07682b6SSantosh Shilimkar 	rtc_data[2] = bin2bcd(tm->tm_min);
308b07682b6SSantosh Shilimkar 	rtc_data[3] = bin2bcd(tm->tm_hour);
309b07682b6SSantosh Shilimkar 	rtc_data[4] = bin2bcd(tm->tm_mday);
310b07682b6SSantosh Shilimkar 	rtc_data[5] = bin2bcd(tm->tm_mon + 1);
311b07682b6SSantosh Shilimkar 	rtc_data[6] = bin2bcd(tm->tm_year - 100);
312b07682b6SSantosh Shilimkar 
313b07682b6SSantosh Shilimkar 	/* Stop RTC while updating the TC registers */
314ef3b7d0dSBalaji T K 	ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
315b07682b6SSantosh Shilimkar 	if (ret < 0)
316b07682b6SSantosh Shilimkar 		goto out;
317b07682b6SSantosh Shilimkar 
318b07682b6SSantosh Shilimkar 	save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M;
3198f6b0dd3SJesper Juhl 	ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
320b07682b6SSantosh Shilimkar 	if (ret < 0)
321b07682b6SSantosh Shilimkar 		goto out;
322b07682b6SSantosh Shilimkar 
323b07682b6SSantosh Shilimkar 	/* update all the time registers in one shot */
324ef3b7d0dSBalaji T K 	ret = twl_i2c_write(TWL_MODULE_RTC, rtc_data,
325a6b49ffdSBalaji T K 		(rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS);
326b07682b6SSantosh Shilimkar 	if (ret < 0) {
327b07682b6SSantosh Shilimkar 		dev_err(dev, "rtc_set_time error %d\n", ret);
328b07682b6SSantosh Shilimkar 		goto out;
329b07682b6SSantosh Shilimkar 	}
330b07682b6SSantosh Shilimkar 
331b07682b6SSantosh Shilimkar 	/* Start back RTC */
332b07682b6SSantosh Shilimkar 	save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M;
333ef3b7d0dSBalaji T K 	ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
334b07682b6SSantosh Shilimkar 
335b07682b6SSantosh Shilimkar out:
336b07682b6SSantosh Shilimkar 	return ret;
337b07682b6SSantosh Shilimkar }
338b07682b6SSantosh Shilimkar 
339b07682b6SSantosh Shilimkar /*
340ef3b7d0dSBalaji T K  * Gets current TWL RTC alarm time.
341b07682b6SSantosh Shilimkar  */
342ef3b7d0dSBalaji T K static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
343b07682b6SSantosh Shilimkar {
344b07682b6SSantosh Shilimkar 	unsigned char rtc_data[ALL_TIME_REGS + 1];
345b07682b6SSantosh Shilimkar 	int ret;
346b07682b6SSantosh Shilimkar 
347ef3b7d0dSBalaji T K 	ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data,
348a6b49ffdSBalaji T K 			(rtc_reg_map[REG_ALARM_SECONDS_REG]), ALL_TIME_REGS);
349b07682b6SSantosh Shilimkar 	if (ret < 0) {
350b07682b6SSantosh Shilimkar 		dev_err(dev, "rtc_read_alarm error %d\n", ret);
351b07682b6SSantosh Shilimkar 		return ret;
352b07682b6SSantosh Shilimkar 	}
353b07682b6SSantosh Shilimkar 
354b07682b6SSantosh Shilimkar 	/* some of these fields may be wildcard/"match all" */
355b07682b6SSantosh Shilimkar 	alm->time.tm_sec = bcd2bin(rtc_data[0]);
356b07682b6SSantosh Shilimkar 	alm->time.tm_min = bcd2bin(rtc_data[1]);
357b07682b6SSantosh Shilimkar 	alm->time.tm_hour = bcd2bin(rtc_data[2]);
358b07682b6SSantosh Shilimkar 	alm->time.tm_mday = bcd2bin(rtc_data[3]);
359b07682b6SSantosh Shilimkar 	alm->time.tm_mon = bcd2bin(rtc_data[4]) - 1;
360b07682b6SSantosh Shilimkar 	alm->time.tm_year = bcd2bin(rtc_data[5]) + 100;
361b07682b6SSantosh Shilimkar 
362b07682b6SSantosh Shilimkar 	/* report cached alarm enable state */
363b07682b6SSantosh Shilimkar 	if (rtc_irq_bits & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
364b07682b6SSantosh Shilimkar 		alm->enabled = 1;
365b07682b6SSantosh Shilimkar 
366b07682b6SSantosh Shilimkar 	return ret;
367b07682b6SSantosh Shilimkar }
368b07682b6SSantosh Shilimkar 
369ef3b7d0dSBalaji T K static int twl_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
370b07682b6SSantosh Shilimkar {
371b07682b6SSantosh Shilimkar 	unsigned char alarm_data[ALL_TIME_REGS + 1];
372b07682b6SSantosh Shilimkar 	int ret;
373b07682b6SSantosh Shilimkar 
374ef3b7d0dSBalaji T K 	ret = twl_rtc_alarm_irq_enable(dev, 0);
375b07682b6SSantosh Shilimkar 	if (ret)
376b07682b6SSantosh Shilimkar 		goto out;
377b07682b6SSantosh Shilimkar 
378b07682b6SSantosh Shilimkar 	alarm_data[1] = bin2bcd(alm->time.tm_sec);
379b07682b6SSantosh Shilimkar 	alarm_data[2] = bin2bcd(alm->time.tm_min);
380b07682b6SSantosh Shilimkar 	alarm_data[3] = bin2bcd(alm->time.tm_hour);
381b07682b6SSantosh Shilimkar 	alarm_data[4] = bin2bcd(alm->time.tm_mday);
382b07682b6SSantosh Shilimkar 	alarm_data[5] = bin2bcd(alm->time.tm_mon + 1);
383b07682b6SSantosh Shilimkar 	alarm_data[6] = bin2bcd(alm->time.tm_year - 100);
384b07682b6SSantosh Shilimkar 
385b07682b6SSantosh Shilimkar 	/* update all the alarm registers in one shot */
386ef3b7d0dSBalaji T K 	ret = twl_i2c_write(TWL_MODULE_RTC, alarm_data,
387a6b49ffdSBalaji T K 		(rtc_reg_map[REG_ALARM_SECONDS_REG]), ALL_TIME_REGS);
388b07682b6SSantosh Shilimkar 	if (ret) {
389b07682b6SSantosh Shilimkar 		dev_err(dev, "rtc_set_alarm error %d\n", ret);
390b07682b6SSantosh Shilimkar 		goto out;
391b07682b6SSantosh Shilimkar 	}
392b07682b6SSantosh Shilimkar 
393b07682b6SSantosh Shilimkar 	if (alm->enabled)
394ef3b7d0dSBalaji T K 		ret = twl_rtc_alarm_irq_enable(dev, 1);
395b07682b6SSantosh Shilimkar out:
396b07682b6SSantosh Shilimkar 	return ret;
397b07682b6SSantosh Shilimkar }
398b07682b6SSantosh Shilimkar 
399ef3b7d0dSBalaji T K static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
400b07682b6SSantosh Shilimkar {
4012778ebccSVenu Byravarasu 	unsigned long events;
402b07682b6SSantosh Shilimkar 	int ret = IRQ_NONE;
403b07682b6SSantosh Shilimkar 	int res;
404b07682b6SSantosh Shilimkar 	u8 rd_reg;
405b07682b6SSantosh Shilimkar 
406ef3b7d0dSBalaji T K 	res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
407b07682b6SSantosh Shilimkar 	if (res)
408b07682b6SSantosh Shilimkar 		goto out;
409b07682b6SSantosh Shilimkar 	/*
410b07682b6SSantosh Shilimkar 	 * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG.
411b07682b6SSantosh Shilimkar 	 * only one (ALARM or RTC) interrupt source may be enabled
412b07682b6SSantosh Shilimkar 	 * at time, we also could check our results
413b07682b6SSantosh Shilimkar 	 * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM]
414b07682b6SSantosh Shilimkar 	 */
415b07682b6SSantosh Shilimkar 	if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
4162778ebccSVenu Byravarasu 		events = RTC_IRQF | RTC_AF;
417b07682b6SSantosh Shilimkar 	else
4182778ebccSVenu Byravarasu 		events = RTC_IRQF | RTC_PF;
419b07682b6SSantosh Shilimkar 
42094a339d0SVenu Byravarasu 	res = twl_rtc_write_u8(BIT_RTC_STATUS_REG_ALARM_M,
421b07682b6SSantosh Shilimkar 				   REG_RTC_STATUS_REG);
422b07682b6SSantosh Shilimkar 	if (res)
423b07682b6SSantosh Shilimkar 		goto out;
424b07682b6SSantosh Shilimkar 
425a6b49ffdSBalaji T K 	if (twl_class_is_4030()) {
426b07682b6SSantosh Shilimkar 		/* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1
427b07682b6SSantosh Shilimkar 		 * needs 2 reads to clear the interrupt. One read is done in
428ef3b7d0dSBalaji T K 		 * do_twl_pwrirq(). Doing the second read, to clear
429b07682b6SSantosh Shilimkar 		 * the bit.
430b07682b6SSantosh Shilimkar 		 *
431b07682b6SSantosh Shilimkar 		 * FIXME the reason PWR_ISR1 needs an extra read is that
432b07682b6SSantosh Shilimkar 		 * RTC_IF retriggered until we cleared REG_ALARM_M above.
433b07682b6SSantosh Shilimkar 		 * But re-reading like this is a bad hack; by doing so we
434b07682b6SSantosh Shilimkar 		 * risk wrongly clearing status for some other IRQ (losing
435b07682b6SSantosh Shilimkar 		 * the interrupt).  Be smarter about handling RTC_UF ...
436b07682b6SSantosh Shilimkar 		 */
437fc7b92fcSBalaji T K 		res = twl_i2c_read_u8(TWL4030_MODULE_INT,
438b07682b6SSantosh Shilimkar 			&rd_reg, TWL4030_INT_PWR_ISR1);
439b07682b6SSantosh Shilimkar 		if (res)
440b07682b6SSantosh Shilimkar 			goto out;
441a6b49ffdSBalaji T K 	}
442b07682b6SSantosh Shilimkar 
443b07682b6SSantosh Shilimkar 	/* Notify RTC core on event */
444b07682b6SSantosh Shilimkar 	rtc_update_irq(rtc, 1, events);
445b07682b6SSantosh Shilimkar 
446b07682b6SSantosh Shilimkar 	ret = IRQ_HANDLED;
447b07682b6SSantosh Shilimkar out:
448b07682b6SSantosh Shilimkar 	return ret;
449b07682b6SSantosh Shilimkar }
450b07682b6SSantosh Shilimkar 
451ef3b7d0dSBalaji T K static struct rtc_class_ops twl_rtc_ops = {
452ef3b7d0dSBalaji T K 	.read_time	= twl_rtc_read_time,
453ef3b7d0dSBalaji T K 	.set_time	= twl_rtc_set_time,
454ef3b7d0dSBalaji T K 	.read_alarm	= twl_rtc_read_alarm,
455ef3b7d0dSBalaji T K 	.set_alarm	= twl_rtc_set_alarm,
456ef3b7d0dSBalaji T K 	.alarm_irq_enable = twl_rtc_alarm_irq_enable,
457b07682b6SSantosh Shilimkar };
458b07682b6SSantosh Shilimkar 
459b07682b6SSantosh Shilimkar /*----------------------------------------------------------------------*/
460b07682b6SSantosh Shilimkar 
461ef3b7d0dSBalaji T K static int __devinit twl_rtc_probe(struct platform_device *pdev)
462b07682b6SSantosh Shilimkar {
463b07682b6SSantosh Shilimkar 	struct rtc_device *rtc;
4647e72c686STodd Poynor 	int ret = -EINVAL;
465b07682b6SSantosh Shilimkar 	int irq = platform_get_irq(pdev, 0);
466b07682b6SSantosh Shilimkar 	u8 rd_reg;
467b07682b6SSantosh Shilimkar 
468b07682b6SSantosh Shilimkar 	if (irq <= 0)
4697e72c686STodd Poynor 		goto out1;
470b07682b6SSantosh Shilimkar 
471ef3b7d0dSBalaji T K 	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
472b07682b6SSantosh Shilimkar 	if (ret < 0)
473b07682b6SSantosh Shilimkar 		goto out1;
474b07682b6SSantosh Shilimkar 
475b07682b6SSantosh Shilimkar 	if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
476b07682b6SSantosh Shilimkar 		dev_warn(&pdev->dev, "Power up reset detected.\n");
477b07682b6SSantosh Shilimkar 
478b07682b6SSantosh Shilimkar 	if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
479b07682b6SSantosh Shilimkar 		dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");
480b07682b6SSantosh Shilimkar 
481b07682b6SSantosh Shilimkar 	/* Clear RTC Power up reset and pending alarm interrupts */
482ef3b7d0dSBalaji T K 	ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
483b07682b6SSantosh Shilimkar 	if (ret < 0)
484b07682b6SSantosh Shilimkar 		goto out1;
485b07682b6SSantosh Shilimkar 
486a6b49ffdSBalaji T K 	if (twl_class_is_6030()) {
487a6b49ffdSBalaji T K 		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
488a6b49ffdSBalaji T K 			REG_INT_MSK_LINE_A);
489a6b49ffdSBalaji T K 		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
490a6b49ffdSBalaji T K 			REG_INT_MSK_STS_A);
491a6b49ffdSBalaji T K 	}
492a6b49ffdSBalaji T K 
493f7439bcbSVenu Byravarasu 	dev_info(&pdev->dev, "Enabling TWL-RTC\n");
494f7439bcbSVenu Byravarasu 	ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG);
495b07682b6SSantosh Shilimkar 	if (ret < 0)
4967e72c686STodd Poynor 		goto out1;
497b07682b6SSantosh Shilimkar 
498*8dcebaa9SKevin Hilman 	/* ensure interrupts are disabled, bootloaders can be strange */
499*8dcebaa9SKevin Hilman 	ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG);
500*8dcebaa9SKevin Hilman 	if (ret < 0)
501*8dcebaa9SKevin Hilman 		dev_warn(&pdev->dev, "unable to disable interrupt\n");
502*8dcebaa9SKevin Hilman 
503b07682b6SSantosh Shilimkar 	/* init cached IRQ enable bits */
504ef3b7d0dSBalaji T K 	ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
505b07682b6SSantosh Shilimkar 	if (ret < 0)
5067e72c686STodd Poynor 		goto out1;
507b07682b6SSantosh Shilimkar 
5087e72c686STodd Poynor 	rtc = rtc_device_register(pdev->name,
5097e72c686STodd Poynor 				  &pdev->dev, &twl_rtc_ops, THIS_MODULE);
5107e72c686STodd Poynor 	if (IS_ERR(rtc)) {
5117e72c686STodd Poynor 		ret = PTR_ERR(rtc);
5127e72c686STodd Poynor 		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
5137e72c686STodd Poynor 			PTR_ERR(rtc));
5147e72c686STodd Poynor 		goto out1;
5157e72c686STodd Poynor 	}
5167e72c686STodd Poynor 
5177e72c686STodd Poynor 	ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
5186b91bf1aSKevin Hilman 				   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
5197e72c686STodd Poynor 				   dev_name(&rtc->dev), rtc);
5207e72c686STodd Poynor 	if (ret < 0) {
5217e72c686STodd Poynor 		dev_err(&pdev->dev, "IRQ is not free.\n");
5227e72c686STodd Poynor 		goto out2;
5237e72c686STodd Poynor 	}
5247e72c686STodd Poynor 
5257e72c686STodd Poynor 	platform_set_drvdata(pdev, rtc);
5267e72c686STodd Poynor 	return 0;
527b07682b6SSantosh Shilimkar 
528b07682b6SSantosh Shilimkar out2:
529b07682b6SSantosh Shilimkar 	rtc_device_unregister(rtc);
5307e72c686STodd Poynor out1:
531b07682b6SSantosh Shilimkar 	return ret;
532b07682b6SSantosh Shilimkar }
533b07682b6SSantosh Shilimkar 
534b07682b6SSantosh Shilimkar /*
535ef3b7d0dSBalaji T K  * Disable all TWL RTC module interrupts.
536b07682b6SSantosh Shilimkar  * Sets status flag to free.
537b07682b6SSantosh Shilimkar  */
538ef3b7d0dSBalaji T K static int __devexit twl_rtc_remove(struct platform_device *pdev)
539b07682b6SSantosh Shilimkar {
540b07682b6SSantosh Shilimkar 	/* leave rtc running, but disable irqs */
541b07682b6SSantosh Shilimkar 	struct rtc_device *rtc = platform_get_drvdata(pdev);
542b07682b6SSantosh Shilimkar 	int irq = platform_get_irq(pdev, 0);
543b07682b6SSantosh Shilimkar 
544b07682b6SSantosh Shilimkar 	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
545b07682b6SSantosh Shilimkar 	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
546a6b49ffdSBalaji T K 	if (twl_class_is_6030()) {
547a6b49ffdSBalaji T K 		twl6030_interrupt_mask(TWL6030_RTC_INT_MASK,
548a6b49ffdSBalaji T K 			REG_INT_MSK_LINE_A);
549a6b49ffdSBalaji T K 		twl6030_interrupt_mask(TWL6030_RTC_INT_MASK,
550a6b49ffdSBalaji T K 			REG_INT_MSK_STS_A);
551a6b49ffdSBalaji T K 	}
552a6b49ffdSBalaji T K 
553b07682b6SSantosh Shilimkar 
554b07682b6SSantosh Shilimkar 	free_irq(irq, rtc);
555b07682b6SSantosh Shilimkar 
556b07682b6SSantosh Shilimkar 	rtc_device_unregister(rtc);
557b07682b6SSantosh Shilimkar 	platform_set_drvdata(pdev, NULL);
558b07682b6SSantosh Shilimkar 	return 0;
559b07682b6SSantosh Shilimkar }
560b07682b6SSantosh Shilimkar 
561ef3b7d0dSBalaji T K static void twl_rtc_shutdown(struct platform_device *pdev)
562b07682b6SSantosh Shilimkar {
563b07682b6SSantosh Shilimkar 	/* mask timer interrupts, but leave alarm interrupts on to enable
564b07682b6SSantosh Shilimkar 	   power-on when alarm is triggered */
565b07682b6SSantosh Shilimkar 	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
566b07682b6SSantosh Shilimkar }
567b07682b6SSantosh Shilimkar 
568b07682b6SSantosh Shilimkar #ifdef CONFIG_PM
569b07682b6SSantosh Shilimkar 
570b07682b6SSantosh Shilimkar static unsigned char irqstat;
571b07682b6SSantosh Shilimkar 
572ef3b7d0dSBalaji T K static int twl_rtc_suspend(struct platform_device *pdev, pm_message_t state)
573b07682b6SSantosh Shilimkar {
574b07682b6SSantosh Shilimkar 	irqstat = rtc_irq_bits;
575b07682b6SSantosh Shilimkar 
576b07682b6SSantosh Shilimkar 	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
577b07682b6SSantosh Shilimkar 	return 0;
578b07682b6SSantosh Shilimkar }
579b07682b6SSantosh Shilimkar 
580ef3b7d0dSBalaji T K static int twl_rtc_resume(struct platform_device *pdev)
581b07682b6SSantosh Shilimkar {
582b07682b6SSantosh Shilimkar 	set_rtc_irq_bit(irqstat);
583b07682b6SSantosh Shilimkar 	return 0;
584b07682b6SSantosh Shilimkar }
585b07682b6SSantosh Shilimkar 
586b07682b6SSantosh Shilimkar #else
587ef3b7d0dSBalaji T K #define twl_rtc_suspend NULL
588ef3b7d0dSBalaji T K #define twl_rtc_resume  NULL
589b07682b6SSantosh Shilimkar #endif
590b07682b6SSantosh Shilimkar 
591948170f8SBenoit Cousson static const struct of_device_id twl_rtc_of_match[] = {
592948170f8SBenoit Cousson 	{.compatible = "ti,twl4030-rtc", },
593948170f8SBenoit Cousson 	{ },
594948170f8SBenoit Cousson };
595948170f8SBenoit Cousson MODULE_DEVICE_TABLE(of, twl_rtc_of_match);
596ef3b7d0dSBalaji T K MODULE_ALIAS("platform:twl_rtc");
597b07682b6SSantosh Shilimkar 
598b07682b6SSantosh Shilimkar static struct platform_driver twl4030rtc_driver = {
599ef3b7d0dSBalaji T K 	.probe		= twl_rtc_probe,
600ef3b7d0dSBalaji T K 	.remove		= __devexit_p(twl_rtc_remove),
601ef3b7d0dSBalaji T K 	.shutdown	= twl_rtc_shutdown,
602ef3b7d0dSBalaji T K 	.suspend	= twl_rtc_suspend,
603ef3b7d0dSBalaji T K 	.resume		= twl_rtc_resume,
604b07682b6SSantosh Shilimkar 	.driver		= {
605b07682b6SSantosh Shilimkar 		.owner		= THIS_MODULE,
606ef3b7d0dSBalaji T K 		.name		= "twl_rtc",
607948170f8SBenoit Cousson 		.of_match_table = twl_rtc_of_match,
608b07682b6SSantosh Shilimkar 	},
609b07682b6SSantosh Shilimkar };
610b07682b6SSantosh Shilimkar 
611ef3b7d0dSBalaji T K static int __init twl_rtc_init(void)
612b07682b6SSantosh Shilimkar {
613a6b49ffdSBalaji T K 	if (twl_class_is_4030())
614a6b49ffdSBalaji T K 		rtc_reg_map = (u8 *) twl4030_rtc_reg_map;
615a6b49ffdSBalaji T K 	else
616a6b49ffdSBalaji T K 		rtc_reg_map = (u8 *) twl6030_rtc_reg_map;
617a6b49ffdSBalaji T K 
618b07682b6SSantosh Shilimkar 	return platform_driver_register(&twl4030rtc_driver);
619b07682b6SSantosh Shilimkar }
620ef3b7d0dSBalaji T K module_init(twl_rtc_init);
621b07682b6SSantosh Shilimkar 
622ef3b7d0dSBalaji T K static void __exit twl_rtc_exit(void)
623b07682b6SSantosh Shilimkar {
624b07682b6SSantosh Shilimkar 	platform_driver_unregister(&twl4030rtc_driver);
625b07682b6SSantosh Shilimkar }
626ef3b7d0dSBalaji T K module_exit(twl_rtc_exit);
627b07682b6SSantosh Shilimkar 
628b07682b6SSantosh Shilimkar MODULE_AUTHOR("Texas Instruments, MontaVista Software");
629b07682b6SSantosh Shilimkar MODULE_LICENSE("GPL");
630