xref: /linux/drivers/rtc/rtc-rv8803.c (revision 1e3929ef0e1c4c7127b785ce7a236965b3739406)
1*1e3929efSAlexandre Belloni /*
2*1e3929efSAlexandre Belloni  * RTC driver for the Micro Crystal RV8803
3*1e3929efSAlexandre Belloni  *
4*1e3929efSAlexandre Belloni  * Copyright (C) 2015 Micro Crystal SA
5*1e3929efSAlexandre Belloni  *
6*1e3929efSAlexandre Belloni  * Alexandre Belloni <alexandre.belloni@free-electrons.com>
7*1e3929efSAlexandre Belloni  *
8*1e3929efSAlexandre Belloni  * This program is free software; you can redistribute it and/or modify
9*1e3929efSAlexandre Belloni  * it under the terms of the GNU General Public License version 2 as
10*1e3929efSAlexandre Belloni  * published by the Free Software Foundation.
11*1e3929efSAlexandre Belloni  *
12*1e3929efSAlexandre Belloni  */
13*1e3929efSAlexandre Belloni 
14*1e3929efSAlexandre Belloni #include <linux/bcd.h>
15*1e3929efSAlexandre Belloni #include <linux/bitops.h>
16*1e3929efSAlexandre Belloni #include <linux/i2c.h>
17*1e3929efSAlexandre Belloni #include <linux/interrupt.h>
18*1e3929efSAlexandre Belloni #include <linux/kernel.h>
19*1e3929efSAlexandre Belloni #include <linux/module.h>
20*1e3929efSAlexandre Belloni #include <linux/rtc.h>
21*1e3929efSAlexandre Belloni 
22*1e3929efSAlexandre Belloni #define RV8803_SEC			0x00
23*1e3929efSAlexandre Belloni #define RV8803_MIN			0x01
24*1e3929efSAlexandre Belloni #define RV8803_HOUR			0x02
25*1e3929efSAlexandre Belloni #define RV8803_WEEK			0x03
26*1e3929efSAlexandre Belloni #define RV8803_DAY			0x04
27*1e3929efSAlexandre Belloni #define RV8803_MONTH			0x05
28*1e3929efSAlexandre Belloni #define RV8803_YEAR			0x06
29*1e3929efSAlexandre Belloni #define RV8803_RAM			0x07
30*1e3929efSAlexandre Belloni #define RV8803_ALARM_MIN		0x08
31*1e3929efSAlexandre Belloni #define RV8803_ALARM_HOUR		0x09
32*1e3929efSAlexandre Belloni #define RV8803_ALARM_WEEK_OR_DAY	0x0A
33*1e3929efSAlexandre Belloni #define RV8803_EXT			0x0D
34*1e3929efSAlexandre Belloni #define RV8803_FLAG			0x0E
35*1e3929efSAlexandre Belloni #define RV8803_CTRL			0x0F
36*1e3929efSAlexandre Belloni 
37*1e3929efSAlexandre Belloni #define RV8803_EXT_WADA			BIT(6)
38*1e3929efSAlexandre Belloni 
39*1e3929efSAlexandre Belloni #define RV8803_FLAG_V1F			BIT(0)
40*1e3929efSAlexandre Belloni #define RV8803_FLAG_V2F			BIT(1)
41*1e3929efSAlexandre Belloni #define RV8803_FLAG_AF			BIT(3)
42*1e3929efSAlexandre Belloni #define RV8803_FLAG_TF			BIT(4)
43*1e3929efSAlexandre Belloni #define RV8803_FLAG_UF			BIT(5)
44*1e3929efSAlexandre Belloni 
45*1e3929efSAlexandre Belloni #define RV8803_CTRL_RESET		BIT(0)
46*1e3929efSAlexandre Belloni 
47*1e3929efSAlexandre Belloni #define RV8803_CTRL_EIE			BIT(2)
48*1e3929efSAlexandre Belloni #define RV8803_CTRL_AIE			BIT(3)
49*1e3929efSAlexandre Belloni #define RV8803_CTRL_TIE			BIT(4)
50*1e3929efSAlexandre Belloni #define RV8803_CTRL_UIE			BIT(5)
51*1e3929efSAlexandre Belloni 
52*1e3929efSAlexandre Belloni struct rv8803_data {
53*1e3929efSAlexandre Belloni 	struct i2c_client *client;
54*1e3929efSAlexandre Belloni 	struct rtc_device *rtc;
55*1e3929efSAlexandre Belloni 	spinlock_t flags_lock;
56*1e3929efSAlexandre Belloni 	u8 ctrl;
57*1e3929efSAlexandre Belloni };
58*1e3929efSAlexandre Belloni 
59*1e3929efSAlexandre Belloni static irqreturn_t rv8803_handle_irq(int irq, void *dev_id)
60*1e3929efSAlexandre Belloni {
61*1e3929efSAlexandre Belloni 	struct i2c_client *client = dev_id;
62*1e3929efSAlexandre Belloni 	struct rv8803_data *rv8803 = i2c_get_clientdata(client);
63*1e3929efSAlexandre Belloni 	unsigned long events = 0;
64*1e3929efSAlexandre Belloni 	u8 flags;
65*1e3929efSAlexandre Belloni 
66*1e3929efSAlexandre Belloni 	spin_lock(&rv8803->flags_lock);
67*1e3929efSAlexandre Belloni 
68*1e3929efSAlexandre Belloni 	flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
69*1e3929efSAlexandre Belloni 	if (flags <= 0) {
70*1e3929efSAlexandre Belloni 		spin_unlock(&rv8803->flags_lock);
71*1e3929efSAlexandre Belloni 		return IRQ_NONE;
72*1e3929efSAlexandre Belloni 	}
73*1e3929efSAlexandre Belloni 
74*1e3929efSAlexandre Belloni 	if (flags & RV8803_FLAG_V1F)
75*1e3929efSAlexandre Belloni 		dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
76*1e3929efSAlexandre Belloni 
77*1e3929efSAlexandre Belloni 	if (flags & RV8803_FLAG_V2F)
78*1e3929efSAlexandre Belloni 		dev_warn(&client->dev, "Voltage low, data loss detected.\n");
79*1e3929efSAlexandre Belloni 
80*1e3929efSAlexandre Belloni 	if (flags & RV8803_FLAG_TF) {
81*1e3929efSAlexandre Belloni 		flags &= ~RV8803_FLAG_TF;
82*1e3929efSAlexandre Belloni 		rv8803->ctrl &= ~RV8803_CTRL_TIE;
83*1e3929efSAlexandre Belloni 		events |= RTC_PF;
84*1e3929efSAlexandre Belloni 	}
85*1e3929efSAlexandre Belloni 
86*1e3929efSAlexandre Belloni 	if (flags & RV8803_FLAG_AF) {
87*1e3929efSAlexandre Belloni 		flags &= ~RV8803_FLAG_AF;
88*1e3929efSAlexandre Belloni 		rv8803->ctrl &= ~RV8803_CTRL_AIE;
89*1e3929efSAlexandre Belloni 		events |= RTC_AF;
90*1e3929efSAlexandre Belloni 	}
91*1e3929efSAlexandre Belloni 
92*1e3929efSAlexandre Belloni 	if (flags & RV8803_FLAG_UF) {
93*1e3929efSAlexandre Belloni 		flags &= ~RV8803_FLAG_UF;
94*1e3929efSAlexandre Belloni 		rv8803->ctrl &= ~RV8803_CTRL_UIE;
95*1e3929efSAlexandre Belloni 		events |= RTC_UF;
96*1e3929efSAlexandre Belloni 	}
97*1e3929efSAlexandre Belloni 
98*1e3929efSAlexandre Belloni 	if (events) {
99*1e3929efSAlexandre Belloni 		rtc_update_irq(rv8803->rtc, 1, events);
100*1e3929efSAlexandre Belloni 		i2c_smbus_write_byte_data(client, RV8803_FLAG, flags);
101*1e3929efSAlexandre Belloni 		i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL,
102*1e3929efSAlexandre Belloni 					  rv8803->ctrl);
103*1e3929efSAlexandre Belloni 	}
104*1e3929efSAlexandre Belloni 
105*1e3929efSAlexandre Belloni 	spin_unlock(&rv8803->flags_lock);
106*1e3929efSAlexandre Belloni 
107*1e3929efSAlexandre Belloni 	return IRQ_HANDLED;
108*1e3929efSAlexandre Belloni }
109*1e3929efSAlexandre Belloni 
110*1e3929efSAlexandre Belloni static int rv8803_get_time(struct device *dev, struct rtc_time *tm)
111*1e3929efSAlexandre Belloni {
112*1e3929efSAlexandre Belloni 	struct rv8803_data *rv8803 = dev_get_drvdata(dev);
113*1e3929efSAlexandre Belloni 	u8 date1[7];
114*1e3929efSAlexandre Belloni 	u8 date2[7];
115*1e3929efSAlexandre Belloni 	u8 *date = date1;
116*1e3929efSAlexandre Belloni 	int ret, flags;
117*1e3929efSAlexandre Belloni 
118*1e3929efSAlexandre Belloni 	flags = i2c_smbus_read_byte_data(rv8803->client, RV8803_FLAG);
119*1e3929efSAlexandre Belloni 	if (flags < 0)
120*1e3929efSAlexandre Belloni 		return flags;
121*1e3929efSAlexandre Belloni 
122*1e3929efSAlexandre Belloni 	if (flags & RV8803_FLAG_V2F) {
123*1e3929efSAlexandre Belloni 		dev_warn(dev, "Voltage low, data is invalid.\n");
124*1e3929efSAlexandre Belloni 		return -EINVAL;
125*1e3929efSAlexandre Belloni 	}
126*1e3929efSAlexandre Belloni 
127*1e3929efSAlexandre Belloni 	ret = i2c_smbus_read_i2c_block_data(rv8803->client, RV8803_SEC,
128*1e3929efSAlexandre Belloni 					    7, date);
129*1e3929efSAlexandre Belloni 	if (ret != 7)
130*1e3929efSAlexandre Belloni 		return ret < 0 ? ret : -EIO;
131*1e3929efSAlexandre Belloni 
132*1e3929efSAlexandre Belloni 	if ((date1[RV8803_SEC] & 0x7f) == bin2bcd(59)) {
133*1e3929efSAlexandre Belloni 		ret = i2c_smbus_read_i2c_block_data(rv8803->client, RV8803_SEC,
134*1e3929efSAlexandre Belloni 						    7, date2);
135*1e3929efSAlexandre Belloni 		if (ret != 7)
136*1e3929efSAlexandre Belloni 			return ret < 0 ? ret : -EIO;
137*1e3929efSAlexandre Belloni 
138*1e3929efSAlexandre Belloni 		if ((date2[RV8803_SEC] & 0x7f) != bin2bcd(59))
139*1e3929efSAlexandre Belloni 			date = date2;
140*1e3929efSAlexandre Belloni 	}
141*1e3929efSAlexandre Belloni 
142*1e3929efSAlexandre Belloni 	tm->tm_sec  = bcd2bin(date[RV8803_SEC] & 0x7f);
143*1e3929efSAlexandre Belloni 	tm->tm_min  = bcd2bin(date[RV8803_MIN] & 0x7f);
144*1e3929efSAlexandre Belloni 	tm->tm_hour = bcd2bin(date[RV8803_HOUR] & 0x3f);
145*1e3929efSAlexandre Belloni 	tm->tm_wday = ffs(date[RV8803_WEEK] & 0x7f);
146*1e3929efSAlexandre Belloni 	tm->tm_mday = bcd2bin(date[RV8803_DAY] & 0x3f);
147*1e3929efSAlexandre Belloni 	tm->tm_mon  = bcd2bin(date[RV8803_MONTH] & 0x1f) - 1;
148*1e3929efSAlexandre Belloni 	tm->tm_year = bcd2bin(date[RV8803_YEAR]) + 100;
149*1e3929efSAlexandre Belloni 
150*1e3929efSAlexandre Belloni 	return rtc_valid_tm(tm);
151*1e3929efSAlexandre Belloni }
152*1e3929efSAlexandre Belloni 
153*1e3929efSAlexandre Belloni static int rv8803_set_time(struct device *dev, struct rtc_time *tm)
154*1e3929efSAlexandre Belloni {
155*1e3929efSAlexandre Belloni 	struct rv8803_data *rv8803 = dev_get_drvdata(dev);
156*1e3929efSAlexandre Belloni 	u8 date[7];
157*1e3929efSAlexandre Belloni 	int flags, ret;
158*1e3929efSAlexandre Belloni 	unsigned long irqflags;
159*1e3929efSAlexandre Belloni 
160*1e3929efSAlexandre Belloni 	if ((tm->tm_year < 100) || (tm->tm_year > 199))
161*1e3929efSAlexandre Belloni 		return -EINVAL;
162*1e3929efSAlexandre Belloni 
163*1e3929efSAlexandre Belloni 	date[RV8803_SEC]   = bin2bcd(tm->tm_sec);
164*1e3929efSAlexandre Belloni 	date[RV8803_MIN]   = bin2bcd(tm->tm_min);
165*1e3929efSAlexandre Belloni 	date[RV8803_HOUR]  = bin2bcd(tm->tm_hour);
166*1e3929efSAlexandre Belloni 	date[RV8803_WEEK]  = 1 << (tm->tm_wday);
167*1e3929efSAlexandre Belloni 	date[RV8803_DAY]   = bin2bcd(tm->tm_mday);
168*1e3929efSAlexandre Belloni 	date[RV8803_MONTH] = bin2bcd(tm->tm_mon + 1);
169*1e3929efSAlexandre Belloni 	date[RV8803_YEAR]  = bin2bcd(tm->tm_year - 100);
170*1e3929efSAlexandre Belloni 
171*1e3929efSAlexandre Belloni 	ret = i2c_smbus_write_i2c_block_data(rv8803->client, RV8803_SEC,
172*1e3929efSAlexandre Belloni 					     7, date);
173*1e3929efSAlexandre Belloni 	if (ret < 0)
174*1e3929efSAlexandre Belloni 		return ret;
175*1e3929efSAlexandre Belloni 
176*1e3929efSAlexandre Belloni 	spin_lock_irqsave(&rv8803->flags_lock, irqflags);
177*1e3929efSAlexandre Belloni 
178*1e3929efSAlexandre Belloni 	flags = i2c_smbus_read_byte_data(rv8803->client, RV8803_FLAG);
179*1e3929efSAlexandre Belloni 	if (flags < 0) {
180*1e3929efSAlexandre Belloni 		spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
181*1e3929efSAlexandre Belloni 		return flags;
182*1e3929efSAlexandre Belloni 	}
183*1e3929efSAlexandre Belloni 
184*1e3929efSAlexandre Belloni 	ret = i2c_smbus_write_byte_data(rv8803->client, RV8803_FLAG,
185*1e3929efSAlexandre Belloni 					flags & ~RV8803_FLAG_V2F);
186*1e3929efSAlexandre Belloni 
187*1e3929efSAlexandre Belloni 	spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
188*1e3929efSAlexandre Belloni 
189*1e3929efSAlexandre Belloni 	return ret;
190*1e3929efSAlexandre Belloni }
191*1e3929efSAlexandre Belloni 
192*1e3929efSAlexandre Belloni static int rv8803_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
193*1e3929efSAlexandre Belloni {
194*1e3929efSAlexandre Belloni 	struct rv8803_data *rv8803 = dev_get_drvdata(dev);
195*1e3929efSAlexandre Belloni 	struct i2c_client *client = rv8803->client;
196*1e3929efSAlexandre Belloni 	u8 alarmvals[3];
197*1e3929efSAlexandre Belloni 	int flags, ret;
198*1e3929efSAlexandre Belloni 
199*1e3929efSAlexandre Belloni 	ret = i2c_smbus_read_i2c_block_data(client, RV8803_ALARM_MIN,
200*1e3929efSAlexandre Belloni 					    3, alarmvals);
201*1e3929efSAlexandre Belloni 	if (ret != 3)
202*1e3929efSAlexandre Belloni 		return ret < 0 ? ret : -EIO;
203*1e3929efSAlexandre Belloni 
204*1e3929efSAlexandre Belloni 	flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
205*1e3929efSAlexandre Belloni 	if (flags < 0)
206*1e3929efSAlexandre Belloni 		return flags;
207*1e3929efSAlexandre Belloni 
208*1e3929efSAlexandre Belloni 	alrm->time.tm_sec  = 0;
209*1e3929efSAlexandre Belloni 	alrm->time.tm_min  = bcd2bin(alarmvals[0] & 0x7f);
210*1e3929efSAlexandre Belloni 	alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f);
211*1e3929efSAlexandre Belloni 	alrm->time.tm_wday = -1;
212*1e3929efSAlexandre Belloni 	alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f);
213*1e3929efSAlexandre Belloni 	alrm->time.tm_mon  = -1;
214*1e3929efSAlexandre Belloni 	alrm->time.tm_year = -1;
215*1e3929efSAlexandre Belloni 
216*1e3929efSAlexandre Belloni 	alrm->enabled = !!(rv8803->ctrl & RV8803_CTRL_AIE);
217*1e3929efSAlexandre Belloni 	alrm->pending = (flags & RV8803_FLAG_AF) && alrm->enabled;
218*1e3929efSAlexandre Belloni 
219*1e3929efSAlexandre Belloni 	return 0;
220*1e3929efSAlexandre Belloni }
221*1e3929efSAlexandre Belloni 
222*1e3929efSAlexandre Belloni static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
223*1e3929efSAlexandre Belloni {
224*1e3929efSAlexandre Belloni 	struct i2c_client *client = to_i2c_client(dev);
225*1e3929efSAlexandre Belloni 	struct rv8803_data *rv8803 = dev_get_drvdata(dev);
226*1e3929efSAlexandre Belloni 	u8 alarmvals[3];
227*1e3929efSAlexandre Belloni 	u8 ctrl[2];
228*1e3929efSAlexandre Belloni 	int ret, err;
229*1e3929efSAlexandre Belloni 	unsigned long irqflags;
230*1e3929efSAlexandre Belloni 
231*1e3929efSAlexandre Belloni 	/* The alarm has no seconds, round up to nearest minute */
232*1e3929efSAlexandre Belloni 	if (alrm->time.tm_sec) {
233*1e3929efSAlexandre Belloni 		time64_t alarm_time = rtc_tm_to_time64(&alrm->time);
234*1e3929efSAlexandre Belloni 
235*1e3929efSAlexandre Belloni 		alarm_time += 60 - alrm->time.tm_sec;
236*1e3929efSAlexandre Belloni 		rtc_time64_to_tm(alarm_time, &alrm->time);
237*1e3929efSAlexandre Belloni 	}
238*1e3929efSAlexandre Belloni 
239*1e3929efSAlexandre Belloni 	spin_lock_irqsave(&rv8803->flags_lock, irqflags);
240*1e3929efSAlexandre Belloni 
241*1e3929efSAlexandre Belloni 	ret = i2c_smbus_read_i2c_block_data(client, RV8803_FLAG, 2, ctrl);
242*1e3929efSAlexandre Belloni 	if (ret != 2) {
243*1e3929efSAlexandre Belloni 		spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
244*1e3929efSAlexandre Belloni 		return ret < 0 ? ret : -EIO;
245*1e3929efSAlexandre Belloni 	}
246*1e3929efSAlexandre Belloni 
247*1e3929efSAlexandre Belloni 	alarmvals[0] = bin2bcd(alrm->time.tm_min);
248*1e3929efSAlexandre Belloni 	alarmvals[1] = bin2bcd(alrm->time.tm_hour);
249*1e3929efSAlexandre Belloni 	alarmvals[2] = bin2bcd(alrm->time.tm_mday);
250*1e3929efSAlexandre Belloni 
251*1e3929efSAlexandre Belloni 	if (rv8803->ctrl & (RV8803_CTRL_AIE | RV8803_CTRL_UIE)) {
252*1e3929efSAlexandre Belloni 		rv8803->ctrl &= ~(RV8803_CTRL_AIE | RV8803_CTRL_UIE);
253*1e3929efSAlexandre Belloni 		err = i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL,
254*1e3929efSAlexandre Belloni 						rv8803->ctrl);
255*1e3929efSAlexandre Belloni 		if (err) {
256*1e3929efSAlexandre Belloni 			spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
257*1e3929efSAlexandre Belloni 			return err;
258*1e3929efSAlexandre Belloni 		}
259*1e3929efSAlexandre Belloni 	}
260*1e3929efSAlexandre Belloni 
261*1e3929efSAlexandre Belloni 	ctrl[1] &= ~RV8803_FLAG_AF;
262*1e3929efSAlexandre Belloni 	err = i2c_smbus_write_byte_data(rv8803->client, RV8803_FLAG, ctrl[1]);
263*1e3929efSAlexandre Belloni 	spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
264*1e3929efSAlexandre Belloni 	if (err)
265*1e3929efSAlexandre Belloni 		return err;
266*1e3929efSAlexandre Belloni 
267*1e3929efSAlexandre Belloni 	err = i2c_smbus_write_i2c_block_data(rv8803->client, RV8803_ALARM_MIN,
268*1e3929efSAlexandre Belloni 					     3, alarmvals);
269*1e3929efSAlexandre Belloni 	if (err)
270*1e3929efSAlexandre Belloni 		return err;
271*1e3929efSAlexandre Belloni 
272*1e3929efSAlexandre Belloni 	if (alrm->enabled) {
273*1e3929efSAlexandre Belloni 		if (rv8803->rtc->uie_rtctimer.enabled)
274*1e3929efSAlexandre Belloni 			rv8803->ctrl |= RV8803_CTRL_UIE;
275*1e3929efSAlexandre Belloni 		if (rv8803->rtc->aie_timer.enabled)
276*1e3929efSAlexandre Belloni 			rv8803->ctrl |= RV8803_CTRL_AIE;
277*1e3929efSAlexandre Belloni 
278*1e3929efSAlexandre Belloni 		err = i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL,
279*1e3929efSAlexandre Belloni 						rv8803->ctrl);
280*1e3929efSAlexandre Belloni 		if (err)
281*1e3929efSAlexandre Belloni 			return err;
282*1e3929efSAlexandre Belloni 	}
283*1e3929efSAlexandre Belloni 
284*1e3929efSAlexandre Belloni 	return 0;
285*1e3929efSAlexandre Belloni }
286*1e3929efSAlexandre Belloni 
287*1e3929efSAlexandre Belloni static int rv8803_alarm_irq_enable(struct device *dev, unsigned int enabled)
288*1e3929efSAlexandre Belloni {
289*1e3929efSAlexandre Belloni 	struct i2c_client *client = to_i2c_client(dev);
290*1e3929efSAlexandre Belloni 	struct rv8803_data *rv8803 = dev_get_drvdata(dev);
291*1e3929efSAlexandre Belloni 	int ctrl, flags, err;
292*1e3929efSAlexandre Belloni 	unsigned long irqflags;
293*1e3929efSAlexandre Belloni 
294*1e3929efSAlexandre Belloni 	ctrl = rv8803->ctrl;
295*1e3929efSAlexandre Belloni 
296*1e3929efSAlexandre Belloni 	if (enabled) {
297*1e3929efSAlexandre Belloni 		if (rv8803->rtc->uie_rtctimer.enabled)
298*1e3929efSAlexandre Belloni 			ctrl |= RV8803_CTRL_UIE;
299*1e3929efSAlexandre Belloni 		if (rv8803->rtc->aie_timer.enabled)
300*1e3929efSAlexandre Belloni 			ctrl |= RV8803_CTRL_AIE;
301*1e3929efSAlexandre Belloni 	} else {
302*1e3929efSAlexandre Belloni 		if (!rv8803->rtc->uie_rtctimer.enabled)
303*1e3929efSAlexandre Belloni 			ctrl &= ~RV8803_CTRL_UIE;
304*1e3929efSAlexandre Belloni 		if (!rv8803->rtc->aie_timer.enabled)
305*1e3929efSAlexandre Belloni 			ctrl &= ~RV8803_CTRL_AIE;
306*1e3929efSAlexandre Belloni 	}
307*1e3929efSAlexandre Belloni 
308*1e3929efSAlexandre Belloni 	spin_lock_irqsave(&rv8803->flags_lock, irqflags);
309*1e3929efSAlexandre Belloni 	flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
310*1e3929efSAlexandre Belloni 	if (flags < 0) {
311*1e3929efSAlexandre Belloni 		spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
312*1e3929efSAlexandre Belloni 		return flags;
313*1e3929efSAlexandre Belloni 	}
314*1e3929efSAlexandre Belloni 	flags &= ~(RV8803_FLAG_AF | RV8803_FLAG_UF);
315*1e3929efSAlexandre Belloni 	err = i2c_smbus_write_byte_data(client, RV8803_FLAG, flags);
316*1e3929efSAlexandre Belloni 	spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
317*1e3929efSAlexandre Belloni 	if (err)
318*1e3929efSAlexandre Belloni 		return err;
319*1e3929efSAlexandre Belloni 
320*1e3929efSAlexandre Belloni 	if (ctrl != rv8803->ctrl) {
321*1e3929efSAlexandre Belloni 		rv8803->ctrl = ctrl;
322*1e3929efSAlexandre Belloni 		err = i2c_smbus_write_byte_data(client, RV8803_CTRL,
323*1e3929efSAlexandre Belloni 						rv8803->ctrl);
324*1e3929efSAlexandre Belloni 		if (err)
325*1e3929efSAlexandre Belloni 			return err;
326*1e3929efSAlexandre Belloni 	}
327*1e3929efSAlexandre Belloni 
328*1e3929efSAlexandre Belloni 	return 0;
329*1e3929efSAlexandre Belloni }
330*1e3929efSAlexandre Belloni 
331*1e3929efSAlexandre Belloni static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
332*1e3929efSAlexandre Belloni {
333*1e3929efSAlexandre Belloni 	struct i2c_client *client = to_i2c_client(dev);
334*1e3929efSAlexandre Belloni 	struct rv8803_data *rv8803 = dev_get_drvdata(dev);
335*1e3929efSAlexandre Belloni 	int flags, ret = 0;
336*1e3929efSAlexandre Belloni 	unsigned long irqflags;
337*1e3929efSAlexandre Belloni 
338*1e3929efSAlexandre Belloni 	switch (cmd) {
339*1e3929efSAlexandre Belloni 	case RTC_VL_READ:
340*1e3929efSAlexandre Belloni 		flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
341*1e3929efSAlexandre Belloni 		if (flags < 0)
342*1e3929efSAlexandre Belloni 			return flags;
343*1e3929efSAlexandre Belloni 
344*1e3929efSAlexandre Belloni 		if (flags & RV8803_FLAG_V1F)
345*1e3929efSAlexandre Belloni 			dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
346*1e3929efSAlexandre Belloni 
347*1e3929efSAlexandre Belloni 		if (flags & RV8803_FLAG_V2F)
348*1e3929efSAlexandre Belloni 			dev_warn(&client->dev, "Voltage low, data loss detected.\n");
349*1e3929efSAlexandre Belloni 
350*1e3929efSAlexandre Belloni 		flags &= RV8803_FLAG_V1F | RV8803_FLAG_V2F;
351*1e3929efSAlexandre Belloni 
352*1e3929efSAlexandre Belloni 		if (copy_to_user((void __user *)arg, &flags, sizeof(int)))
353*1e3929efSAlexandre Belloni 			return -EFAULT;
354*1e3929efSAlexandre Belloni 
355*1e3929efSAlexandre Belloni 		return 0;
356*1e3929efSAlexandre Belloni 
357*1e3929efSAlexandre Belloni 	case RTC_VL_CLR:
358*1e3929efSAlexandre Belloni 		spin_lock_irqsave(&rv8803->flags_lock, irqflags);
359*1e3929efSAlexandre Belloni 		flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
360*1e3929efSAlexandre Belloni 		if (flags < 0) {
361*1e3929efSAlexandre Belloni 			spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
362*1e3929efSAlexandre Belloni 			return flags;
363*1e3929efSAlexandre Belloni 		}
364*1e3929efSAlexandre Belloni 
365*1e3929efSAlexandre Belloni 		flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F);
366*1e3929efSAlexandre Belloni 		ret = i2c_smbus_write_byte_data(client, RV8803_FLAG, flags);
367*1e3929efSAlexandre Belloni 		spin_unlock_irqrestore(&rv8803->flags_lock, irqflags);
368*1e3929efSAlexandre Belloni 		if (ret < 0)
369*1e3929efSAlexandre Belloni 			return ret;
370*1e3929efSAlexandre Belloni 
371*1e3929efSAlexandre Belloni 		return 0;
372*1e3929efSAlexandre Belloni 
373*1e3929efSAlexandre Belloni 	default:
374*1e3929efSAlexandre Belloni 		return -ENOIOCTLCMD;
375*1e3929efSAlexandre Belloni 	}
376*1e3929efSAlexandre Belloni }
377*1e3929efSAlexandre Belloni 
378*1e3929efSAlexandre Belloni static ssize_t rv8803_nvram_write(struct file *filp, struct kobject *kobj,
379*1e3929efSAlexandre Belloni 				  struct bin_attribute *attr,
380*1e3929efSAlexandre Belloni 				  char *buf, loff_t off, size_t count)
381*1e3929efSAlexandre Belloni {
382*1e3929efSAlexandre Belloni 	struct device *dev = kobj_to_dev(kobj);
383*1e3929efSAlexandre Belloni 	struct i2c_client *client = to_i2c_client(dev);
384*1e3929efSAlexandre Belloni 	int ret;
385*1e3929efSAlexandre Belloni 
386*1e3929efSAlexandre Belloni 	ret = i2c_smbus_write_byte_data(client, RV8803_RAM, buf[0]);
387*1e3929efSAlexandre Belloni 	if (ret < 0)
388*1e3929efSAlexandre Belloni 		return ret;
389*1e3929efSAlexandre Belloni 
390*1e3929efSAlexandre Belloni 	return 1;
391*1e3929efSAlexandre Belloni }
392*1e3929efSAlexandre Belloni 
393*1e3929efSAlexandre Belloni static ssize_t rv8803_nvram_read(struct file *filp, struct kobject *kobj,
394*1e3929efSAlexandre Belloni 				 struct bin_attribute *attr,
395*1e3929efSAlexandre Belloni 				 char *buf, loff_t off, size_t count)
396*1e3929efSAlexandre Belloni {
397*1e3929efSAlexandre Belloni 	struct device *dev = kobj_to_dev(kobj);
398*1e3929efSAlexandre Belloni 	struct i2c_client *client = to_i2c_client(dev);
399*1e3929efSAlexandre Belloni 	int ret;
400*1e3929efSAlexandre Belloni 
401*1e3929efSAlexandre Belloni 	ret = i2c_smbus_read_byte_data(client, RV8803_RAM);
402*1e3929efSAlexandre Belloni 	if (ret < 0)
403*1e3929efSAlexandre Belloni 		return ret;
404*1e3929efSAlexandre Belloni 
405*1e3929efSAlexandre Belloni 	buf[0] = ret;
406*1e3929efSAlexandre Belloni 
407*1e3929efSAlexandre Belloni 	return 1;
408*1e3929efSAlexandre Belloni }
409*1e3929efSAlexandre Belloni 
410*1e3929efSAlexandre Belloni static struct bin_attribute rv8803_nvram_attr = {
411*1e3929efSAlexandre Belloni 	.attr = {
412*1e3929efSAlexandre Belloni 		.name = "nvram",
413*1e3929efSAlexandre Belloni 		.mode = S_IRUGO | S_IWUSR,
414*1e3929efSAlexandre Belloni 	},
415*1e3929efSAlexandre Belloni 	.size = 1,
416*1e3929efSAlexandre Belloni 	.read = rv8803_nvram_read,
417*1e3929efSAlexandre Belloni 	.write = rv8803_nvram_write,
418*1e3929efSAlexandre Belloni };
419*1e3929efSAlexandre Belloni 
420*1e3929efSAlexandre Belloni static struct rtc_class_ops rv8803_rtc_ops = {
421*1e3929efSAlexandre Belloni 	.read_time = rv8803_get_time,
422*1e3929efSAlexandre Belloni 	.set_time = rv8803_set_time,
423*1e3929efSAlexandre Belloni 	.ioctl = rv8803_ioctl,
424*1e3929efSAlexandre Belloni };
425*1e3929efSAlexandre Belloni 
426*1e3929efSAlexandre Belloni static int rv8803_probe(struct i2c_client *client,
427*1e3929efSAlexandre Belloni 			const struct i2c_device_id *id)
428*1e3929efSAlexandre Belloni {
429*1e3929efSAlexandre Belloni 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
430*1e3929efSAlexandre Belloni 	struct rv8803_data *rv8803;
431*1e3929efSAlexandre Belloni 	int err, flags;
432*1e3929efSAlexandre Belloni 
433*1e3929efSAlexandre Belloni 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
434*1e3929efSAlexandre Belloni 				     I2C_FUNC_SMBUS_I2C_BLOCK)) {
435*1e3929efSAlexandre Belloni 		dev_err(&adapter->dev, "doesn't support I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK\n");
436*1e3929efSAlexandre Belloni 		return -EIO;
437*1e3929efSAlexandre Belloni 	}
438*1e3929efSAlexandre Belloni 
439*1e3929efSAlexandre Belloni 	rv8803 = devm_kzalloc(&client->dev, sizeof(struct rv8803_data),
440*1e3929efSAlexandre Belloni 			      GFP_KERNEL);
441*1e3929efSAlexandre Belloni 	if (!rv8803)
442*1e3929efSAlexandre Belloni 		return -ENOMEM;
443*1e3929efSAlexandre Belloni 
444*1e3929efSAlexandre Belloni 	rv8803->client = client;
445*1e3929efSAlexandre Belloni 	i2c_set_clientdata(client, rv8803);
446*1e3929efSAlexandre Belloni 
447*1e3929efSAlexandre Belloni 	flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
448*1e3929efSAlexandre Belloni 	if (flags < 0)
449*1e3929efSAlexandre Belloni 		return flags;
450*1e3929efSAlexandre Belloni 
451*1e3929efSAlexandre Belloni 	if (flags & RV8803_FLAG_V1F)
452*1e3929efSAlexandre Belloni 		dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
453*1e3929efSAlexandre Belloni 
454*1e3929efSAlexandre Belloni 	if (flags & RV8803_FLAG_V2F)
455*1e3929efSAlexandre Belloni 		dev_warn(&client->dev, "Voltage low, data loss detected.\n");
456*1e3929efSAlexandre Belloni 
457*1e3929efSAlexandre Belloni 	if (flags & RV8803_FLAG_AF)
458*1e3929efSAlexandre Belloni 		dev_warn(&client->dev, "An alarm maybe have been missed.\n");
459*1e3929efSAlexandre Belloni 
460*1e3929efSAlexandre Belloni 	if (client->irq > 0) {
461*1e3929efSAlexandre Belloni 		err = devm_request_threaded_irq(&client->dev, client->irq,
462*1e3929efSAlexandre Belloni 						NULL, rv8803_handle_irq,
463*1e3929efSAlexandre Belloni 						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
464*1e3929efSAlexandre Belloni 						"rv8803", client);
465*1e3929efSAlexandre Belloni 		if (err) {
466*1e3929efSAlexandre Belloni 			dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
467*1e3929efSAlexandre Belloni 			client->irq = 0;
468*1e3929efSAlexandre Belloni 		} else {
469*1e3929efSAlexandre Belloni 			rv8803_rtc_ops.read_alarm = rv8803_get_alarm;
470*1e3929efSAlexandre Belloni 			rv8803_rtc_ops.set_alarm = rv8803_set_alarm;
471*1e3929efSAlexandre Belloni 			rv8803_rtc_ops.alarm_irq_enable = rv8803_alarm_irq_enable;
472*1e3929efSAlexandre Belloni 		}
473*1e3929efSAlexandre Belloni 	}
474*1e3929efSAlexandre Belloni 
475*1e3929efSAlexandre Belloni 	rv8803->rtc = devm_rtc_device_register(&client->dev, client->name,
476*1e3929efSAlexandre Belloni 					       &rv8803_rtc_ops, THIS_MODULE);
477*1e3929efSAlexandre Belloni 	if (IS_ERR(rv8803->rtc)) {
478*1e3929efSAlexandre Belloni 		dev_err(&client->dev, "unable to register the class device\n");
479*1e3929efSAlexandre Belloni 		return PTR_ERR(rv8803->rtc);
480*1e3929efSAlexandre Belloni 	}
481*1e3929efSAlexandre Belloni 
482*1e3929efSAlexandre Belloni 	err = i2c_smbus_write_byte_data(rv8803->client, RV8803_EXT,
483*1e3929efSAlexandre Belloni 					RV8803_EXT_WADA);
484*1e3929efSAlexandre Belloni 	if (err)
485*1e3929efSAlexandre Belloni 		return err;
486*1e3929efSAlexandre Belloni 
487*1e3929efSAlexandre Belloni 	err = device_create_bin_file(&client->dev, &rv8803_nvram_attr);
488*1e3929efSAlexandre Belloni 	if (err)
489*1e3929efSAlexandre Belloni 		return err;
490*1e3929efSAlexandre Belloni 
491*1e3929efSAlexandre Belloni 	rv8803->rtc->max_user_freq = 1;
492*1e3929efSAlexandre Belloni 
493*1e3929efSAlexandre Belloni 	return 0;
494*1e3929efSAlexandre Belloni }
495*1e3929efSAlexandre Belloni 
496*1e3929efSAlexandre Belloni static int rv8803_remove(struct i2c_client *client)
497*1e3929efSAlexandre Belloni {
498*1e3929efSAlexandre Belloni 	device_remove_bin_file(&client->dev, &rv8803_nvram_attr);
499*1e3929efSAlexandre Belloni 
500*1e3929efSAlexandre Belloni 	return 0;
501*1e3929efSAlexandre Belloni }
502*1e3929efSAlexandre Belloni 
503*1e3929efSAlexandre Belloni static const struct i2c_device_id rv8803_id[] = {
504*1e3929efSAlexandre Belloni 	{ "rv8803", 0 },
505*1e3929efSAlexandre Belloni 	{ }
506*1e3929efSAlexandre Belloni };
507*1e3929efSAlexandre Belloni MODULE_DEVICE_TABLE(i2c, rv8803_id);
508*1e3929efSAlexandre Belloni 
509*1e3929efSAlexandre Belloni static struct i2c_driver rv8803_driver = {
510*1e3929efSAlexandre Belloni 	.driver = {
511*1e3929efSAlexandre Belloni 		.name = "rtc-rv8803",
512*1e3929efSAlexandre Belloni 	},
513*1e3929efSAlexandre Belloni 	.probe		= rv8803_probe,
514*1e3929efSAlexandre Belloni 	.remove		= rv8803_remove,
515*1e3929efSAlexandre Belloni 	.id_table	= rv8803_id,
516*1e3929efSAlexandre Belloni };
517*1e3929efSAlexandre Belloni module_i2c_driver(rv8803_driver);
518*1e3929efSAlexandre Belloni 
519*1e3929efSAlexandre Belloni MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
520*1e3929efSAlexandre Belloni MODULE_DESCRIPTION("Micro Crystal RV8803 RTC driver");
521*1e3929efSAlexandre Belloni MODULE_LICENSE("GPL v2");
522