1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) ST-Ericsson SA 2010
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Author: Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * RTC clock driver for the RTC part of the AB8500 Power management chip.
8*4882a593Smuzhiyun * Based on RTC clock driver for the AB3100 Analog Baseband Chip by
9*4882a593Smuzhiyun * Linus Walleij <linus.walleij@stericsson.com>
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/kernel.h>
14*4882a593Smuzhiyun #include <linux/init.h>
15*4882a593Smuzhiyun #include <linux/platform_device.h>
16*4882a593Smuzhiyun #include <linux/rtc.h>
17*4882a593Smuzhiyun #include <linux/mfd/abx500.h>
18*4882a593Smuzhiyun #include <linux/mfd/abx500/ab8500.h>
19*4882a593Smuzhiyun #include <linux/delay.h>
20*4882a593Smuzhiyun #include <linux/of.h>
21*4882a593Smuzhiyun #include <linux/pm_wakeirq.h>
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #define AB8500_RTC_SOFF_STAT_REG 0x00
24*4882a593Smuzhiyun #define AB8500_RTC_CC_CONF_REG 0x01
25*4882a593Smuzhiyun #define AB8500_RTC_READ_REQ_REG 0x02
26*4882a593Smuzhiyun #define AB8500_RTC_WATCH_TSECMID_REG 0x03
27*4882a593Smuzhiyun #define AB8500_RTC_WATCH_TSECHI_REG 0x04
28*4882a593Smuzhiyun #define AB8500_RTC_WATCH_TMIN_LOW_REG 0x05
29*4882a593Smuzhiyun #define AB8500_RTC_WATCH_TMIN_MID_REG 0x06
30*4882a593Smuzhiyun #define AB8500_RTC_WATCH_TMIN_HI_REG 0x07
31*4882a593Smuzhiyun #define AB8500_RTC_ALRM_MIN_LOW_REG 0x08
32*4882a593Smuzhiyun #define AB8500_RTC_ALRM_MIN_MID_REG 0x09
33*4882a593Smuzhiyun #define AB8500_RTC_ALRM_MIN_HI_REG 0x0A
34*4882a593Smuzhiyun #define AB8500_RTC_STAT_REG 0x0B
35*4882a593Smuzhiyun #define AB8500_RTC_BKUP_CHG_REG 0x0C
36*4882a593Smuzhiyun #define AB8500_RTC_FORCE_BKUP_REG 0x0D
37*4882a593Smuzhiyun #define AB8500_RTC_CALIB_REG 0x0E
38*4882a593Smuzhiyun #define AB8500_RTC_SWITCH_STAT_REG 0x0F
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun /* RtcReadRequest bits */
41*4882a593Smuzhiyun #define RTC_READ_REQUEST 0x01
42*4882a593Smuzhiyun #define RTC_WRITE_REQUEST 0x02
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /* RtcCtrl bits */
45*4882a593Smuzhiyun #define RTC_ALARM_ENA 0x04
46*4882a593Smuzhiyun #define RTC_STATUS_DATA 0x01
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun #define COUNTS_PER_SEC (0xF000 / 60)
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun static const u8 ab8500_rtc_time_regs[] = {
51*4882a593Smuzhiyun AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG,
52*4882a593Smuzhiyun AB8500_RTC_WATCH_TMIN_LOW_REG, AB8500_RTC_WATCH_TSECHI_REG,
53*4882a593Smuzhiyun AB8500_RTC_WATCH_TSECMID_REG
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun static const u8 ab8500_rtc_alarm_regs[] = {
57*4882a593Smuzhiyun AB8500_RTC_ALRM_MIN_HI_REG, AB8500_RTC_ALRM_MIN_MID_REG,
58*4882a593Smuzhiyun AB8500_RTC_ALRM_MIN_LOW_REG
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun
ab8500_rtc_read_time(struct device * dev,struct rtc_time * tm)61*4882a593Smuzhiyun static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun unsigned long timeout = jiffies + HZ;
64*4882a593Smuzhiyun int retval, i;
65*4882a593Smuzhiyun unsigned long mins, secs;
66*4882a593Smuzhiyun unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)];
67*4882a593Smuzhiyun u8 value;
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun /* Request a data read */
70*4882a593Smuzhiyun retval = abx500_set_register_interruptible(dev,
71*4882a593Smuzhiyun AB8500_RTC, AB8500_RTC_READ_REQ_REG, RTC_READ_REQUEST);
72*4882a593Smuzhiyun if (retval < 0)
73*4882a593Smuzhiyun return retval;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /* Wait for some cycles after enabling the rtc read in ab8500 */
76*4882a593Smuzhiyun while (time_before(jiffies, timeout)) {
77*4882a593Smuzhiyun retval = abx500_get_register_interruptible(dev,
78*4882a593Smuzhiyun AB8500_RTC, AB8500_RTC_READ_REQ_REG, &value);
79*4882a593Smuzhiyun if (retval < 0)
80*4882a593Smuzhiyun return retval;
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun if (!(value & RTC_READ_REQUEST))
83*4882a593Smuzhiyun break;
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun usleep_range(1000, 5000);
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun /* Read the Watchtime registers */
89*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) {
90*4882a593Smuzhiyun retval = abx500_get_register_interruptible(dev,
91*4882a593Smuzhiyun AB8500_RTC, ab8500_rtc_time_regs[i], &value);
92*4882a593Smuzhiyun if (retval < 0)
93*4882a593Smuzhiyun return retval;
94*4882a593Smuzhiyun buf[i] = value;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun mins = (buf[0] << 16) | (buf[1] << 8) | buf[2];
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun secs = (buf[3] << 8) | buf[4];
100*4882a593Smuzhiyun secs = secs / COUNTS_PER_SEC;
101*4882a593Smuzhiyun secs = secs + (mins * 60);
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun rtc_time64_to_tm(secs, tm);
104*4882a593Smuzhiyun return 0;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun
ab8500_rtc_set_time(struct device * dev,struct rtc_time * tm)107*4882a593Smuzhiyun static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun int retval, i;
110*4882a593Smuzhiyun unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)];
111*4882a593Smuzhiyun unsigned long no_secs, no_mins, secs = 0;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun secs = rtc_tm_to_time64(tm);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun no_mins = secs / 60;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun no_secs = secs % 60;
118*4882a593Smuzhiyun /* Make the seconds count as per the RTC resolution */
119*4882a593Smuzhiyun no_secs = no_secs * COUNTS_PER_SEC;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun buf[4] = no_secs & 0xFF;
122*4882a593Smuzhiyun buf[3] = (no_secs >> 8) & 0xFF;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun buf[2] = no_mins & 0xFF;
125*4882a593Smuzhiyun buf[1] = (no_mins >> 8) & 0xFF;
126*4882a593Smuzhiyun buf[0] = (no_mins >> 16) & 0xFF;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) {
129*4882a593Smuzhiyun retval = abx500_set_register_interruptible(dev, AB8500_RTC,
130*4882a593Smuzhiyun ab8500_rtc_time_regs[i], buf[i]);
131*4882a593Smuzhiyun if (retval < 0)
132*4882a593Smuzhiyun return retval;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun /* Request a data write */
136*4882a593Smuzhiyun return abx500_set_register_interruptible(dev, AB8500_RTC,
137*4882a593Smuzhiyun AB8500_RTC_READ_REQ_REG, RTC_WRITE_REQUEST);
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun
ab8500_rtc_read_alarm(struct device * dev,struct rtc_wkalrm * alarm)140*4882a593Smuzhiyun static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun int retval, i;
143*4882a593Smuzhiyun u8 rtc_ctrl, value;
144*4882a593Smuzhiyun unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)];
145*4882a593Smuzhiyun unsigned long secs, mins;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun /* Check if the alarm is enabled or not */
148*4882a593Smuzhiyun retval = abx500_get_register_interruptible(dev, AB8500_RTC,
149*4882a593Smuzhiyun AB8500_RTC_STAT_REG, &rtc_ctrl);
150*4882a593Smuzhiyun if (retval < 0)
151*4882a593Smuzhiyun return retval;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun if (rtc_ctrl & RTC_ALARM_ENA)
154*4882a593Smuzhiyun alarm->enabled = 1;
155*4882a593Smuzhiyun else
156*4882a593Smuzhiyun alarm->enabled = 0;
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun alarm->pending = 0;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) {
161*4882a593Smuzhiyun retval = abx500_get_register_interruptible(dev, AB8500_RTC,
162*4882a593Smuzhiyun ab8500_rtc_alarm_regs[i], &value);
163*4882a593Smuzhiyun if (retval < 0)
164*4882a593Smuzhiyun return retval;
165*4882a593Smuzhiyun buf[i] = value;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
169*4882a593Smuzhiyun secs = mins * 60;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun rtc_time64_to_tm(secs, &alarm->time);
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun return 0;
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
ab8500_rtc_irq_enable(struct device * dev,unsigned int enabled)176*4882a593Smuzhiyun static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun return abx500_mask_and_set_register_interruptible(dev, AB8500_RTC,
179*4882a593Smuzhiyun AB8500_RTC_STAT_REG, RTC_ALARM_ENA,
180*4882a593Smuzhiyun enabled ? RTC_ALARM_ENA : 0);
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
ab8500_rtc_set_alarm(struct device * dev,struct rtc_wkalrm * alarm)183*4882a593Smuzhiyun static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun int retval, i;
186*4882a593Smuzhiyun unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)];
187*4882a593Smuzhiyun unsigned long mins, secs = 0, cursec = 0;
188*4882a593Smuzhiyun struct rtc_time curtm;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun /* Get the number of seconds since 1970 */
191*4882a593Smuzhiyun secs = rtc_tm_to_time64(&alarm->time);
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun /*
194*4882a593Smuzhiyun * Check whether alarm is set less than 1min.
195*4882a593Smuzhiyun * Since our RTC doesn't support alarm resolution less than 1min,
196*4882a593Smuzhiyun * return -EINVAL, so UIE EMUL can take it up, incase of UIE_ON
197*4882a593Smuzhiyun */
198*4882a593Smuzhiyun ab8500_rtc_read_time(dev, &curtm); /* Read current time */
199*4882a593Smuzhiyun cursec = rtc_tm_to_time64(&curtm);
200*4882a593Smuzhiyun if ((secs - cursec) < 59) {
201*4882a593Smuzhiyun dev_dbg(dev, "Alarm less than 1 minute not supported\r\n");
202*4882a593Smuzhiyun return -EINVAL;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun mins = secs / 60;
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun buf[2] = mins & 0xFF;
208*4882a593Smuzhiyun buf[1] = (mins >> 8) & 0xFF;
209*4882a593Smuzhiyun buf[0] = (mins >> 16) & 0xFF;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* Set the alarm time */
212*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) {
213*4882a593Smuzhiyun retval = abx500_set_register_interruptible(dev, AB8500_RTC,
214*4882a593Smuzhiyun ab8500_rtc_alarm_regs[i], buf[i]);
215*4882a593Smuzhiyun if (retval < 0)
216*4882a593Smuzhiyun return retval;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun return ab8500_rtc_irq_enable(dev, alarm->enabled);
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
ab8500_rtc_set_calibration(struct device * dev,int calibration)222*4882a593Smuzhiyun static int ab8500_rtc_set_calibration(struct device *dev, int calibration)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun int retval;
225*4882a593Smuzhiyun u8 rtccal = 0;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun /*
228*4882a593Smuzhiyun * Check that the calibration value (which is in units of 0.5
229*4882a593Smuzhiyun * parts-per-million) is in the AB8500's range for RtcCalibration
230*4882a593Smuzhiyun * register. -128 (0x80) is not permitted because the AB8500 uses
231*4882a593Smuzhiyun * a sign-bit rather than two's complement, so 0x80 is just another
232*4882a593Smuzhiyun * representation of zero.
233*4882a593Smuzhiyun */
234*4882a593Smuzhiyun if ((calibration < -127) || (calibration > 127)) {
235*4882a593Smuzhiyun dev_err(dev, "RtcCalibration value outside permitted range\n");
236*4882a593Smuzhiyun return -EINVAL;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun /*
240*4882a593Smuzhiyun * The AB8500 uses sign (in bit7) and magnitude (in bits0-7)
241*4882a593Smuzhiyun * so need to convert to this sort of representation before writing
242*4882a593Smuzhiyun * into RtcCalibration register...
243*4882a593Smuzhiyun */
244*4882a593Smuzhiyun if (calibration >= 0)
245*4882a593Smuzhiyun rtccal = 0x7F & calibration;
246*4882a593Smuzhiyun else
247*4882a593Smuzhiyun rtccal = ~(calibration - 1) | 0x80;
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun retval = abx500_set_register_interruptible(dev, AB8500_RTC,
250*4882a593Smuzhiyun AB8500_RTC_CALIB_REG, rtccal);
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun return retval;
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun
ab8500_rtc_get_calibration(struct device * dev,int * calibration)255*4882a593Smuzhiyun static int ab8500_rtc_get_calibration(struct device *dev, int *calibration)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun int retval;
258*4882a593Smuzhiyun u8 rtccal = 0;
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun retval = abx500_get_register_interruptible(dev, AB8500_RTC,
261*4882a593Smuzhiyun AB8500_RTC_CALIB_REG, &rtccal);
262*4882a593Smuzhiyun if (retval >= 0) {
263*4882a593Smuzhiyun /*
264*4882a593Smuzhiyun * The AB8500 uses sign (in bit7) and magnitude (in bits0-7)
265*4882a593Smuzhiyun * so need to convert value from RtcCalibration register into
266*4882a593Smuzhiyun * a two's complement signed value...
267*4882a593Smuzhiyun */
268*4882a593Smuzhiyun if (rtccal & 0x80)
269*4882a593Smuzhiyun *calibration = 0 - (rtccal & 0x7F);
270*4882a593Smuzhiyun else
271*4882a593Smuzhiyun *calibration = 0x7F & rtccal;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun return retval;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun
ab8500_sysfs_store_rtc_calibration(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)277*4882a593Smuzhiyun static ssize_t ab8500_sysfs_store_rtc_calibration(struct device *dev,
278*4882a593Smuzhiyun struct device_attribute *attr,
279*4882a593Smuzhiyun const char *buf, size_t count)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun int retval;
282*4882a593Smuzhiyun int calibration = 0;
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun if (sscanf(buf, " %i ", &calibration) != 1) {
285*4882a593Smuzhiyun dev_err(dev, "Failed to store RTC calibration attribute\n");
286*4882a593Smuzhiyun return -EINVAL;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun retval = ab8500_rtc_set_calibration(dev, calibration);
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun return retval ? retval : count;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun
ab8500_sysfs_show_rtc_calibration(struct device * dev,struct device_attribute * attr,char * buf)294*4882a593Smuzhiyun static ssize_t ab8500_sysfs_show_rtc_calibration(struct device *dev,
295*4882a593Smuzhiyun struct device_attribute *attr, char *buf)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun int retval = 0;
298*4882a593Smuzhiyun int calibration = 0;
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun retval = ab8500_rtc_get_calibration(dev, &calibration);
301*4882a593Smuzhiyun if (retval < 0) {
302*4882a593Smuzhiyun dev_err(dev, "Failed to read RTC calibration attribute\n");
303*4882a593Smuzhiyun sprintf(buf, "0\n");
304*4882a593Smuzhiyun return retval;
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun return sprintf(buf, "%d\n", calibration);
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun static DEVICE_ATTR(rtc_calibration, S_IRUGO | S_IWUSR,
311*4882a593Smuzhiyun ab8500_sysfs_show_rtc_calibration,
312*4882a593Smuzhiyun ab8500_sysfs_store_rtc_calibration);
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun static struct attribute *ab8500_rtc_attrs[] = {
315*4882a593Smuzhiyun &dev_attr_rtc_calibration.attr,
316*4882a593Smuzhiyun NULL
317*4882a593Smuzhiyun };
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun static const struct attribute_group ab8500_rtc_sysfs_files = {
320*4882a593Smuzhiyun .attrs = ab8500_rtc_attrs,
321*4882a593Smuzhiyun };
322*4882a593Smuzhiyun
rtc_alarm_handler(int irq,void * data)323*4882a593Smuzhiyun static irqreturn_t rtc_alarm_handler(int irq, void *data)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun struct rtc_device *rtc = data;
326*4882a593Smuzhiyun unsigned long events = RTC_IRQF | RTC_AF;
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun dev_dbg(&rtc->dev, "%s\n", __func__);
329*4882a593Smuzhiyun rtc_update_irq(rtc, 1, events);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun return IRQ_HANDLED;
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun static const struct rtc_class_ops ab8500_rtc_ops = {
335*4882a593Smuzhiyun .read_time = ab8500_rtc_read_time,
336*4882a593Smuzhiyun .set_time = ab8500_rtc_set_time,
337*4882a593Smuzhiyun .read_alarm = ab8500_rtc_read_alarm,
338*4882a593Smuzhiyun .set_alarm = ab8500_rtc_set_alarm,
339*4882a593Smuzhiyun .alarm_irq_enable = ab8500_rtc_irq_enable,
340*4882a593Smuzhiyun };
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun static const struct platform_device_id ab85xx_rtc_ids[] = {
343*4882a593Smuzhiyun { "ab8500-rtc", (kernel_ulong_t)&ab8500_rtc_ops, },
344*4882a593Smuzhiyun { /* sentinel */ }
345*4882a593Smuzhiyun };
346*4882a593Smuzhiyun MODULE_DEVICE_TABLE(platform, ab85xx_rtc_ids);
347*4882a593Smuzhiyun
ab8500_rtc_probe(struct platform_device * pdev)348*4882a593Smuzhiyun static int ab8500_rtc_probe(struct platform_device *pdev)
349*4882a593Smuzhiyun {
350*4882a593Smuzhiyun const struct platform_device_id *platid = platform_get_device_id(pdev);
351*4882a593Smuzhiyun int err;
352*4882a593Smuzhiyun struct rtc_device *rtc;
353*4882a593Smuzhiyun u8 rtc_ctrl;
354*4882a593Smuzhiyun int irq;
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun irq = platform_get_irq_byname(pdev, "ALARM");
357*4882a593Smuzhiyun if (irq < 0)
358*4882a593Smuzhiyun return irq;
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun /* For RTC supply test */
361*4882a593Smuzhiyun err = abx500_mask_and_set_register_interruptible(&pdev->dev, AB8500_RTC,
362*4882a593Smuzhiyun AB8500_RTC_STAT_REG, RTC_STATUS_DATA, RTC_STATUS_DATA);
363*4882a593Smuzhiyun if (err < 0)
364*4882a593Smuzhiyun return err;
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun /* Wait for reset by the PorRtc */
367*4882a593Smuzhiyun usleep_range(1000, 5000);
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun err = abx500_get_register_interruptible(&pdev->dev, AB8500_RTC,
370*4882a593Smuzhiyun AB8500_RTC_STAT_REG, &rtc_ctrl);
371*4882a593Smuzhiyun if (err < 0)
372*4882a593Smuzhiyun return err;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun /* Check if the RTC Supply fails */
375*4882a593Smuzhiyun if (!(rtc_ctrl & RTC_STATUS_DATA)) {
376*4882a593Smuzhiyun dev_err(&pdev->dev, "RTC supply failure\n");
377*4882a593Smuzhiyun return -ENODEV;
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun device_init_wakeup(&pdev->dev, true);
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun rtc = devm_rtc_allocate_device(&pdev->dev);
383*4882a593Smuzhiyun if (IS_ERR(rtc))
384*4882a593Smuzhiyun return PTR_ERR(rtc);
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun rtc->ops = (struct rtc_class_ops *)platid->driver_data;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
389*4882a593Smuzhiyun rtc_alarm_handler, IRQF_ONESHOT,
390*4882a593Smuzhiyun "ab8500-rtc", rtc);
391*4882a593Smuzhiyun if (err < 0)
392*4882a593Smuzhiyun return err;
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun dev_pm_set_wake_irq(&pdev->dev, irq);
395*4882a593Smuzhiyun platform_set_drvdata(pdev, rtc);
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun rtc->uie_unsupported = 1;
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun rtc->range_max = (1ULL << 24) * 60 - 1; // 24-bit minutes + 59 secs
400*4882a593Smuzhiyun rtc->start_secs = RTC_TIMESTAMP_BEGIN_2000;
401*4882a593Smuzhiyun rtc->set_start_time = true;
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun err = rtc_add_group(rtc, &ab8500_rtc_sysfs_files);
404*4882a593Smuzhiyun if (err)
405*4882a593Smuzhiyun return err;
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun return rtc_register_device(rtc);
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun
ab8500_rtc_remove(struct platform_device * pdev)410*4882a593Smuzhiyun static int ab8500_rtc_remove(struct platform_device *pdev)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun dev_pm_clear_wake_irq(&pdev->dev);
413*4882a593Smuzhiyun device_init_wakeup(&pdev->dev, false);
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun return 0;
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun static struct platform_driver ab8500_rtc_driver = {
419*4882a593Smuzhiyun .driver = {
420*4882a593Smuzhiyun .name = "ab8500-rtc",
421*4882a593Smuzhiyun },
422*4882a593Smuzhiyun .probe = ab8500_rtc_probe,
423*4882a593Smuzhiyun .remove = ab8500_rtc_remove,
424*4882a593Smuzhiyun .id_table = ab85xx_rtc_ids,
425*4882a593Smuzhiyun };
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun module_platform_driver(ab8500_rtc_driver);
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun MODULE_AUTHOR("Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>");
430*4882a593Smuzhiyun MODULE_DESCRIPTION("AB8500 RTC Driver");
431*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
432