xref: /openbmc/linux/drivers/rtc/rtc-rv3028.c (revision e6e7376cfd7b3f9b63de3a22792f64d9bfb2ab53)
1*e6e7376cSAlexandre Belloni // SPDX-License-Identifier: GPL-2.0
2*e6e7376cSAlexandre Belloni /*
3*e6e7376cSAlexandre Belloni  * RTC driver for the Micro Crystal RV3028
4*e6e7376cSAlexandre Belloni  *
5*e6e7376cSAlexandre Belloni  * Copyright (C) 2019 Micro Crystal SA
6*e6e7376cSAlexandre Belloni  *
7*e6e7376cSAlexandre Belloni  * Alexandre Belloni <alexandre.belloni@bootlin.com>
8*e6e7376cSAlexandre Belloni  *
9*e6e7376cSAlexandre Belloni  */
10*e6e7376cSAlexandre Belloni 
11*e6e7376cSAlexandre Belloni #include <linux/bcd.h>
12*e6e7376cSAlexandre Belloni #include <linux/bitops.h>
13*e6e7376cSAlexandre Belloni #include <linux/i2c.h>
14*e6e7376cSAlexandre Belloni #include <linux/interrupt.h>
15*e6e7376cSAlexandre Belloni #include <linux/kernel.h>
16*e6e7376cSAlexandre Belloni #include <linux/log2.h>
17*e6e7376cSAlexandre Belloni #include <linux/module.h>
18*e6e7376cSAlexandre Belloni #include <linux/of_device.h>
19*e6e7376cSAlexandre Belloni #include <linux/regmap.h>
20*e6e7376cSAlexandre Belloni #include <linux/rtc.h>
21*e6e7376cSAlexandre Belloni 
22*e6e7376cSAlexandre Belloni #define RV3028_SEC			0x00
23*e6e7376cSAlexandre Belloni #define RV3028_MIN			0x01
24*e6e7376cSAlexandre Belloni #define RV3028_HOUR			0x02
25*e6e7376cSAlexandre Belloni #define RV3028_WDAY			0x03
26*e6e7376cSAlexandre Belloni #define RV3028_DAY			0x04
27*e6e7376cSAlexandre Belloni #define RV3028_MONTH			0x05
28*e6e7376cSAlexandre Belloni #define RV3028_YEAR			0x06
29*e6e7376cSAlexandre Belloni #define RV3028_ALARM_MIN		0x07
30*e6e7376cSAlexandre Belloni #define RV3028_ALARM_HOUR		0x08
31*e6e7376cSAlexandre Belloni #define RV3028_ALARM_DAY		0x09
32*e6e7376cSAlexandre Belloni #define RV3028_STATUS			0x0E
33*e6e7376cSAlexandre Belloni #define RV3028_CTRL1			0x0F
34*e6e7376cSAlexandre Belloni #define RV3028_CTRL2			0x10
35*e6e7376cSAlexandre Belloni #define RV3028_EVT_CTRL			0x13
36*e6e7376cSAlexandre Belloni #define RV3028_TS_COUNT			0x14
37*e6e7376cSAlexandre Belloni #define RV3028_TS_SEC			0x15
38*e6e7376cSAlexandre Belloni #define RV3028_RAM1			0x1F
39*e6e7376cSAlexandre Belloni #define RV3028_EEPROM_ADDR		0x25
40*e6e7376cSAlexandre Belloni #define RV3028_EEPROM_DATA		0x26
41*e6e7376cSAlexandre Belloni #define RV3028_EEPROM_CMD		0x27
42*e6e7376cSAlexandre Belloni #define RV3028_CLKOUT			0x35
43*e6e7376cSAlexandre Belloni #define RV3028_OFFSET			0x36
44*e6e7376cSAlexandre Belloni #define RV3028_BACKUP			0x37
45*e6e7376cSAlexandre Belloni 
46*e6e7376cSAlexandre Belloni #define RV3028_STATUS_PORF		BIT(0)
47*e6e7376cSAlexandre Belloni #define RV3028_STATUS_EVF		BIT(1)
48*e6e7376cSAlexandre Belloni #define RV3028_STATUS_AF		BIT(2)
49*e6e7376cSAlexandre Belloni #define RV3028_STATUS_TF		BIT(3)
50*e6e7376cSAlexandre Belloni #define RV3028_STATUS_UF		BIT(4)
51*e6e7376cSAlexandre Belloni #define RV3028_STATUS_BSF		BIT(5)
52*e6e7376cSAlexandre Belloni #define RV3028_STATUS_CLKF		BIT(6)
53*e6e7376cSAlexandre Belloni #define RV3028_STATUS_EEBUSY		BIT(7)
54*e6e7376cSAlexandre Belloni 
55*e6e7376cSAlexandre Belloni #define RV3028_CTRL1_EERD		BIT(3)
56*e6e7376cSAlexandre Belloni #define RV3028_CTRL1_WADA		BIT(5)
57*e6e7376cSAlexandre Belloni 
58*e6e7376cSAlexandre Belloni #define RV3028_CTRL2_RESET		BIT(0)
59*e6e7376cSAlexandre Belloni #define RV3028_CTRL2_12_24		BIT(1)
60*e6e7376cSAlexandre Belloni #define RV3028_CTRL2_EIE		BIT(2)
61*e6e7376cSAlexandre Belloni #define RV3028_CTRL2_AIE		BIT(3)
62*e6e7376cSAlexandre Belloni #define RV3028_CTRL2_TIE		BIT(4)
63*e6e7376cSAlexandre Belloni #define RV3028_CTRL2_UIE		BIT(5)
64*e6e7376cSAlexandre Belloni #define RV3028_CTRL2_TSE		BIT(7)
65*e6e7376cSAlexandre Belloni 
66*e6e7376cSAlexandre Belloni #define RV3028_EVT_CTRL_TSR		BIT(2)
67*e6e7376cSAlexandre Belloni 
68*e6e7376cSAlexandre Belloni #define RV3028_EEPROM_CMD_WRITE		0x21
69*e6e7376cSAlexandre Belloni #define RV3028_EEPROM_CMD_READ		0x22
70*e6e7376cSAlexandre Belloni 
71*e6e7376cSAlexandre Belloni #define RV3028_EEBUSY_POLL		10000
72*e6e7376cSAlexandre Belloni #define RV3028_EEBUSY_TIMEOUT		100000
73*e6e7376cSAlexandre Belloni 
74*e6e7376cSAlexandre Belloni #define RV3028_BACKUP_TCE		BIT(5)
75*e6e7376cSAlexandre Belloni #define RV3028_BACKUP_TCR_MASK		GENMASK(1,0)
76*e6e7376cSAlexandre Belloni 
77*e6e7376cSAlexandre Belloni #define OFFSET_STEP_PPT			953674
78*e6e7376cSAlexandre Belloni 
79*e6e7376cSAlexandre Belloni enum rv3028_type {
80*e6e7376cSAlexandre Belloni 	rv_3028,
81*e6e7376cSAlexandre Belloni };
82*e6e7376cSAlexandre Belloni 
83*e6e7376cSAlexandre Belloni struct rv3028_data {
84*e6e7376cSAlexandre Belloni 	struct regmap *regmap;
85*e6e7376cSAlexandre Belloni 	struct rtc_device *rtc;
86*e6e7376cSAlexandre Belloni 	enum rv3028_type type;
87*e6e7376cSAlexandre Belloni };
88*e6e7376cSAlexandre Belloni 
89*e6e7376cSAlexandre Belloni static u16 rv3028_trickle_resistors[] = {1000, 3000, 6000, 11000};
90*e6e7376cSAlexandre Belloni 
91*e6e7376cSAlexandre Belloni static ssize_t timestamp0_store(struct device *dev,
92*e6e7376cSAlexandre Belloni 				struct device_attribute *attr,
93*e6e7376cSAlexandre Belloni 				const char *buf, size_t count)
94*e6e7376cSAlexandre Belloni {
95*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent);
96*e6e7376cSAlexandre Belloni 
97*e6e7376cSAlexandre Belloni 	regmap_update_bits(rv3028->regmap, RV3028_EVT_CTRL, RV3028_EVT_CTRL_TSR,
98*e6e7376cSAlexandre Belloni 			   RV3028_EVT_CTRL_TSR);
99*e6e7376cSAlexandre Belloni 
100*e6e7376cSAlexandre Belloni 	return count;
101*e6e7376cSAlexandre Belloni };
102*e6e7376cSAlexandre Belloni 
103*e6e7376cSAlexandre Belloni static ssize_t timestamp0_show(struct device *dev,
104*e6e7376cSAlexandre Belloni 			       struct device_attribute *attr, char *buf)
105*e6e7376cSAlexandre Belloni {
106*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent);
107*e6e7376cSAlexandre Belloni 	struct rtc_time tm;
108*e6e7376cSAlexandre Belloni 	int ret, count;
109*e6e7376cSAlexandre Belloni 	u8 date[6];
110*e6e7376cSAlexandre Belloni 
111*e6e7376cSAlexandre Belloni 	ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count);
112*e6e7376cSAlexandre Belloni 	if (ret)
113*e6e7376cSAlexandre Belloni 		return ret;
114*e6e7376cSAlexandre Belloni 
115*e6e7376cSAlexandre Belloni 	if (!count)
116*e6e7376cSAlexandre Belloni 		return 0;
117*e6e7376cSAlexandre Belloni 
118*e6e7376cSAlexandre Belloni 	ret = regmap_bulk_read(rv3028->regmap, RV3028_TS_SEC, date,
119*e6e7376cSAlexandre Belloni 			       sizeof(date));
120*e6e7376cSAlexandre Belloni 	if (ret)
121*e6e7376cSAlexandre Belloni 		return ret;
122*e6e7376cSAlexandre Belloni 
123*e6e7376cSAlexandre Belloni 	tm.tm_sec = bcd2bin(date[0]);
124*e6e7376cSAlexandre Belloni 	tm.tm_min = bcd2bin(date[1]);
125*e6e7376cSAlexandre Belloni 	tm.tm_hour = bcd2bin(date[2]);
126*e6e7376cSAlexandre Belloni 	tm.tm_mday = bcd2bin(date[3]);
127*e6e7376cSAlexandre Belloni 	tm.tm_mon = bcd2bin(date[4]) - 1;
128*e6e7376cSAlexandre Belloni 	tm.tm_year = bcd2bin(date[5]) + 100;
129*e6e7376cSAlexandre Belloni 
130*e6e7376cSAlexandre Belloni 	ret = rtc_valid_tm(&tm);
131*e6e7376cSAlexandre Belloni 	if (ret)
132*e6e7376cSAlexandre Belloni 		return ret;
133*e6e7376cSAlexandre Belloni 
134*e6e7376cSAlexandre Belloni 	return sprintf(buf, "%llu\n",
135*e6e7376cSAlexandre Belloni 		       (unsigned long long)rtc_tm_to_time64(&tm));
136*e6e7376cSAlexandre Belloni };
137*e6e7376cSAlexandre Belloni 
138*e6e7376cSAlexandre Belloni static DEVICE_ATTR_RW(timestamp0);
139*e6e7376cSAlexandre Belloni 
140*e6e7376cSAlexandre Belloni static ssize_t timestamp0_count_show(struct device *dev,
141*e6e7376cSAlexandre Belloni 				     struct device_attribute *attr, char *buf)
142*e6e7376cSAlexandre Belloni {
143*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent);
144*e6e7376cSAlexandre Belloni 	int ret, count;
145*e6e7376cSAlexandre Belloni 
146*e6e7376cSAlexandre Belloni 	ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count);
147*e6e7376cSAlexandre Belloni 	if (ret)
148*e6e7376cSAlexandre Belloni 		return ret;
149*e6e7376cSAlexandre Belloni 
150*e6e7376cSAlexandre Belloni 	return sprintf(buf, "%u\n", count);
151*e6e7376cSAlexandre Belloni };
152*e6e7376cSAlexandre Belloni 
153*e6e7376cSAlexandre Belloni static DEVICE_ATTR_RO(timestamp0_count);
154*e6e7376cSAlexandre Belloni 
155*e6e7376cSAlexandre Belloni static struct attribute *rv3028_attrs[] = {
156*e6e7376cSAlexandre Belloni 	&dev_attr_timestamp0.attr,
157*e6e7376cSAlexandre Belloni 	&dev_attr_timestamp0_count.attr,
158*e6e7376cSAlexandre Belloni 	NULL
159*e6e7376cSAlexandre Belloni };
160*e6e7376cSAlexandre Belloni 
161*e6e7376cSAlexandre Belloni static const struct attribute_group rv3028_attr_group = {
162*e6e7376cSAlexandre Belloni 	.attrs	= rv3028_attrs,
163*e6e7376cSAlexandre Belloni };
164*e6e7376cSAlexandre Belloni 
165*e6e7376cSAlexandre Belloni static irqreturn_t rv3028_handle_irq(int irq, void *dev_id)
166*e6e7376cSAlexandre Belloni {
167*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_id;
168*e6e7376cSAlexandre Belloni 	unsigned long events = 0;
169*e6e7376cSAlexandre Belloni 	u32 status = 0, ctrl = 0;
170*e6e7376cSAlexandre Belloni 
171*e6e7376cSAlexandre Belloni 	if (regmap_read(rv3028->regmap, RV3028_STATUS, &status) < 0 ||
172*e6e7376cSAlexandre Belloni 	   status == 0) {
173*e6e7376cSAlexandre Belloni 		return IRQ_NONE;
174*e6e7376cSAlexandre Belloni 	}
175*e6e7376cSAlexandre Belloni 
176*e6e7376cSAlexandre Belloni 	if (status & RV3028_STATUS_PORF)
177*e6e7376cSAlexandre Belloni 		dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n");
178*e6e7376cSAlexandre Belloni 
179*e6e7376cSAlexandre Belloni 	if (status & RV3028_STATUS_TF) {
180*e6e7376cSAlexandre Belloni 		status |= RV3028_STATUS_TF;
181*e6e7376cSAlexandre Belloni 		ctrl |= RV3028_CTRL2_TIE;
182*e6e7376cSAlexandre Belloni 		events |= RTC_PF;
183*e6e7376cSAlexandre Belloni 	}
184*e6e7376cSAlexandre Belloni 
185*e6e7376cSAlexandre Belloni 	if (status & RV3028_STATUS_AF) {
186*e6e7376cSAlexandre Belloni 		status |= RV3028_STATUS_AF;
187*e6e7376cSAlexandre Belloni 		ctrl |= RV3028_CTRL2_AIE;
188*e6e7376cSAlexandre Belloni 		events |= RTC_AF;
189*e6e7376cSAlexandre Belloni 	}
190*e6e7376cSAlexandre Belloni 
191*e6e7376cSAlexandre Belloni 	if (status & RV3028_STATUS_UF) {
192*e6e7376cSAlexandre Belloni 		status |= RV3028_STATUS_UF;
193*e6e7376cSAlexandre Belloni 		ctrl |= RV3028_CTRL2_UIE;
194*e6e7376cSAlexandre Belloni 		events |= RTC_UF;
195*e6e7376cSAlexandre Belloni 	}
196*e6e7376cSAlexandre Belloni 
197*e6e7376cSAlexandre Belloni 	if (events) {
198*e6e7376cSAlexandre Belloni 		rtc_update_irq(rv3028->rtc, 1, events);
199*e6e7376cSAlexandre Belloni 		regmap_update_bits(rv3028->regmap, RV3028_STATUS, status, 0);
200*e6e7376cSAlexandre Belloni 		regmap_update_bits(rv3028->regmap, RV3028_CTRL2, ctrl, 0);
201*e6e7376cSAlexandre Belloni 	}
202*e6e7376cSAlexandre Belloni 
203*e6e7376cSAlexandre Belloni 	if (status & RV3028_STATUS_EVF) {
204*e6e7376cSAlexandre Belloni 		sysfs_notify(&rv3028->rtc->dev.kobj, NULL,
205*e6e7376cSAlexandre Belloni 			     dev_attr_timestamp0.attr.name);
206*e6e7376cSAlexandre Belloni 		dev_warn(&rv3028->rtc->dev, "event detected");
207*e6e7376cSAlexandre Belloni 	}
208*e6e7376cSAlexandre Belloni 
209*e6e7376cSAlexandre Belloni 	return IRQ_HANDLED;
210*e6e7376cSAlexandre Belloni }
211*e6e7376cSAlexandre Belloni 
212*e6e7376cSAlexandre Belloni static int rv3028_get_time(struct device *dev, struct rtc_time *tm)
213*e6e7376cSAlexandre Belloni {
214*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
215*e6e7376cSAlexandre Belloni 	u8 date[7];
216*e6e7376cSAlexandre Belloni 	int ret, status;
217*e6e7376cSAlexandre Belloni 
218*e6e7376cSAlexandre Belloni 	ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status);
219*e6e7376cSAlexandre Belloni 	if (ret < 0)
220*e6e7376cSAlexandre Belloni 		return ret;
221*e6e7376cSAlexandre Belloni 
222*e6e7376cSAlexandre Belloni 	if (status & RV3028_STATUS_PORF) {
223*e6e7376cSAlexandre Belloni 		dev_warn(dev, "Voltage low, data is invalid.\n");
224*e6e7376cSAlexandre Belloni 		return -EINVAL;
225*e6e7376cSAlexandre Belloni 	}
226*e6e7376cSAlexandre Belloni 
227*e6e7376cSAlexandre Belloni 	ret = regmap_bulk_read(rv3028->regmap, RV3028_SEC, date, sizeof(date));
228*e6e7376cSAlexandre Belloni 	if (ret)
229*e6e7376cSAlexandre Belloni 		return ret;
230*e6e7376cSAlexandre Belloni 
231*e6e7376cSAlexandre Belloni 	tm->tm_sec  = bcd2bin(date[RV3028_SEC] & 0x7f);
232*e6e7376cSAlexandre Belloni 	tm->tm_min  = bcd2bin(date[RV3028_MIN] & 0x7f);
233*e6e7376cSAlexandre Belloni 	tm->tm_hour = bcd2bin(date[RV3028_HOUR] & 0x3f);
234*e6e7376cSAlexandre Belloni 	tm->tm_wday = ilog2(date[RV3028_WDAY] & 0x7f);
235*e6e7376cSAlexandre Belloni 	tm->tm_mday = bcd2bin(date[RV3028_DAY] & 0x3f);
236*e6e7376cSAlexandre Belloni 	tm->tm_mon  = bcd2bin(date[RV3028_MONTH] & 0x1f) - 1;
237*e6e7376cSAlexandre Belloni 	tm->tm_year = bcd2bin(date[RV3028_YEAR]) + 100;
238*e6e7376cSAlexandre Belloni 
239*e6e7376cSAlexandre Belloni 	return 0;
240*e6e7376cSAlexandre Belloni }
241*e6e7376cSAlexandre Belloni 
242*e6e7376cSAlexandre Belloni static int rv3028_set_time(struct device *dev, struct rtc_time *tm)
243*e6e7376cSAlexandre Belloni {
244*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
245*e6e7376cSAlexandre Belloni 	u8 date[7];
246*e6e7376cSAlexandre Belloni 	int ret;
247*e6e7376cSAlexandre Belloni 
248*e6e7376cSAlexandre Belloni 	date[RV3028_SEC]   = bin2bcd(tm->tm_sec);
249*e6e7376cSAlexandre Belloni 	date[RV3028_MIN]   = bin2bcd(tm->tm_min);
250*e6e7376cSAlexandre Belloni 	date[RV3028_HOUR]  = bin2bcd(tm->tm_hour);
251*e6e7376cSAlexandre Belloni 	date[RV3028_WDAY]  = 1 << (tm->tm_wday);
252*e6e7376cSAlexandre Belloni 	date[RV3028_DAY]   = bin2bcd(tm->tm_mday);
253*e6e7376cSAlexandre Belloni 	date[RV3028_MONTH] = bin2bcd(tm->tm_mon + 1);
254*e6e7376cSAlexandre Belloni 	date[RV3028_YEAR]  = bin2bcd(tm->tm_year - 100);
255*e6e7376cSAlexandre Belloni 
256*e6e7376cSAlexandre Belloni 	/*
257*e6e7376cSAlexandre Belloni 	 * Writing to the Seconds register has the same effect as setting RESET
258*e6e7376cSAlexandre Belloni 	 * bit to 1
259*e6e7376cSAlexandre Belloni 	 */
260*e6e7376cSAlexandre Belloni 	ret = regmap_bulk_write(rv3028->regmap, RV3028_SEC, date,
261*e6e7376cSAlexandre Belloni 				sizeof(date));
262*e6e7376cSAlexandre Belloni 	if (ret)
263*e6e7376cSAlexandre Belloni 		return ret;
264*e6e7376cSAlexandre Belloni 
265*e6e7376cSAlexandre Belloni 	ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
266*e6e7376cSAlexandre Belloni 				 RV3028_STATUS_PORF, 0);
267*e6e7376cSAlexandre Belloni 
268*e6e7376cSAlexandre Belloni 	return ret;
269*e6e7376cSAlexandre Belloni }
270*e6e7376cSAlexandre Belloni 
271*e6e7376cSAlexandre Belloni static int rv3028_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
272*e6e7376cSAlexandre Belloni {
273*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
274*e6e7376cSAlexandre Belloni 	u8 alarmvals[3];
275*e6e7376cSAlexandre Belloni 	int status, ctrl, ret;
276*e6e7376cSAlexandre Belloni 
277*e6e7376cSAlexandre Belloni 	ret = regmap_bulk_read(rv3028->regmap, RV3028_ALARM_MIN, alarmvals,
278*e6e7376cSAlexandre Belloni 			       sizeof(alarmvals));
279*e6e7376cSAlexandre Belloni 	if (ret)
280*e6e7376cSAlexandre Belloni 		return ret;
281*e6e7376cSAlexandre Belloni 
282*e6e7376cSAlexandre Belloni 	ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status);
283*e6e7376cSAlexandre Belloni 	if (ret < 0)
284*e6e7376cSAlexandre Belloni 		return ret;
285*e6e7376cSAlexandre Belloni 
286*e6e7376cSAlexandre Belloni 	ret = regmap_read(rv3028->regmap, RV3028_CTRL2, &ctrl);
287*e6e7376cSAlexandre Belloni 	if (ret < 0)
288*e6e7376cSAlexandre Belloni 		return ret;
289*e6e7376cSAlexandre Belloni 
290*e6e7376cSAlexandre Belloni 	alrm->time.tm_sec  = 0;
291*e6e7376cSAlexandre Belloni 	alrm->time.tm_min  = bcd2bin(alarmvals[0] & 0x7f);
292*e6e7376cSAlexandre Belloni 	alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f);
293*e6e7376cSAlexandre Belloni 	alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f);
294*e6e7376cSAlexandre Belloni 
295*e6e7376cSAlexandre Belloni 	alrm->enabled = !!(ctrl & RV3028_CTRL2_AIE);
296*e6e7376cSAlexandre Belloni 	alrm->pending = (status & RV3028_STATUS_AF) && alrm->enabled;
297*e6e7376cSAlexandre Belloni 
298*e6e7376cSAlexandre Belloni 	return 0;
299*e6e7376cSAlexandre Belloni }
300*e6e7376cSAlexandre Belloni 
301*e6e7376cSAlexandre Belloni static int rv3028_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
302*e6e7376cSAlexandre Belloni {
303*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
304*e6e7376cSAlexandre Belloni 	u8 alarmvals[3];
305*e6e7376cSAlexandre Belloni 	u8 ctrl = 0;
306*e6e7376cSAlexandre Belloni 	int ret;
307*e6e7376cSAlexandre Belloni 
308*e6e7376cSAlexandre Belloni 	/* The alarm has no seconds, round up to nearest minute */
309*e6e7376cSAlexandre Belloni 	if (alrm->time.tm_sec) {
310*e6e7376cSAlexandre Belloni 		time64_t alarm_time = rtc_tm_to_time64(&alrm->time);
311*e6e7376cSAlexandre Belloni 
312*e6e7376cSAlexandre Belloni 		alarm_time += 60 - alrm->time.tm_sec;
313*e6e7376cSAlexandre Belloni 		rtc_time64_to_tm(alarm_time, &alrm->time);
314*e6e7376cSAlexandre Belloni 	}
315*e6e7376cSAlexandre Belloni 
316*e6e7376cSAlexandre Belloni 	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2,
317*e6e7376cSAlexandre Belloni 				 RV3028_CTRL2_AIE | RV3028_CTRL2_UIE, 0);
318*e6e7376cSAlexandre Belloni 	if (ret)
319*e6e7376cSAlexandre Belloni 		return ret;
320*e6e7376cSAlexandre Belloni 
321*e6e7376cSAlexandre Belloni 	alarmvals[0] = bin2bcd(alrm->time.tm_min);
322*e6e7376cSAlexandre Belloni 	alarmvals[1] = bin2bcd(alrm->time.tm_hour);
323*e6e7376cSAlexandre Belloni 	alarmvals[2] = bin2bcd(alrm->time.tm_mday);
324*e6e7376cSAlexandre Belloni 
325*e6e7376cSAlexandre Belloni 	ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
326*e6e7376cSAlexandre Belloni 				 RV3028_STATUS_AF, 0);
327*e6e7376cSAlexandre Belloni 	if (ret)
328*e6e7376cSAlexandre Belloni 		return ret;
329*e6e7376cSAlexandre Belloni 
330*e6e7376cSAlexandre Belloni 	ret = regmap_bulk_write(rv3028->regmap, RV3028_ALARM_MIN, alarmvals,
331*e6e7376cSAlexandre Belloni 				sizeof(alarmvals));
332*e6e7376cSAlexandre Belloni 	if (ret)
333*e6e7376cSAlexandre Belloni 		return ret;
334*e6e7376cSAlexandre Belloni 
335*e6e7376cSAlexandre Belloni 	if (alrm->enabled) {
336*e6e7376cSAlexandre Belloni 		if (rv3028->rtc->uie_rtctimer.enabled)
337*e6e7376cSAlexandre Belloni 			ctrl |= RV3028_CTRL2_UIE;
338*e6e7376cSAlexandre Belloni 		if (rv3028->rtc->aie_timer.enabled)
339*e6e7376cSAlexandre Belloni 			ctrl |= RV3028_CTRL2_AIE;
340*e6e7376cSAlexandre Belloni 	}
341*e6e7376cSAlexandre Belloni 
342*e6e7376cSAlexandre Belloni 	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2,
343*e6e7376cSAlexandre Belloni 				 RV3028_CTRL2_UIE | RV3028_CTRL2_AIE, ctrl);
344*e6e7376cSAlexandre Belloni 
345*e6e7376cSAlexandre Belloni 	return ret;
346*e6e7376cSAlexandre Belloni }
347*e6e7376cSAlexandre Belloni 
348*e6e7376cSAlexandre Belloni static int rv3028_alarm_irq_enable(struct device *dev, unsigned int enabled)
349*e6e7376cSAlexandre Belloni {
350*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
351*e6e7376cSAlexandre Belloni 	int ctrl = 0, ret;
352*e6e7376cSAlexandre Belloni 
353*e6e7376cSAlexandre Belloni 	if (enabled) {
354*e6e7376cSAlexandre Belloni 		if (rv3028->rtc->uie_rtctimer.enabled)
355*e6e7376cSAlexandre Belloni 			ctrl |= RV3028_CTRL2_UIE;
356*e6e7376cSAlexandre Belloni 		if (rv3028->rtc->aie_timer.enabled)
357*e6e7376cSAlexandre Belloni 			ctrl |= RV3028_CTRL2_AIE;
358*e6e7376cSAlexandre Belloni 	}
359*e6e7376cSAlexandre Belloni 
360*e6e7376cSAlexandre Belloni 	ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
361*e6e7376cSAlexandre Belloni 				 RV3028_STATUS_AF | RV3028_STATUS_UF, 0);
362*e6e7376cSAlexandre Belloni 	if (ret)
363*e6e7376cSAlexandre Belloni 		return ret;
364*e6e7376cSAlexandre Belloni 
365*e6e7376cSAlexandre Belloni 	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2,
366*e6e7376cSAlexandre Belloni 				 RV3028_CTRL2_UIE | RV3028_CTRL2_AIE, ctrl);
367*e6e7376cSAlexandre Belloni 	if (ret)
368*e6e7376cSAlexandre Belloni 		return ret;
369*e6e7376cSAlexandre Belloni 
370*e6e7376cSAlexandre Belloni 	return 0;
371*e6e7376cSAlexandre Belloni }
372*e6e7376cSAlexandre Belloni 
373*e6e7376cSAlexandre Belloni static int rv3028_read_offset(struct device *dev, long *offset)
374*e6e7376cSAlexandre Belloni {
375*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
376*e6e7376cSAlexandre Belloni 	int ret, value, steps;
377*e6e7376cSAlexandre Belloni 
378*e6e7376cSAlexandre Belloni 	ret = regmap_read(rv3028->regmap, RV3028_OFFSET, &value);
379*e6e7376cSAlexandre Belloni 	if (ret < 0)
380*e6e7376cSAlexandre Belloni 		return ret;
381*e6e7376cSAlexandre Belloni 
382*e6e7376cSAlexandre Belloni 	steps = sign_extend32(value << 1, 8);
383*e6e7376cSAlexandre Belloni 
384*e6e7376cSAlexandre Belloni 	ret = regmap_read(rv3028->regmap, RV3028_BACKUP, &value);
385*e6e7376cSAlexandre Belloni 	if (ret < 0)
386*e6e7376cSAlexandre Belloni 		return ret;
387*e6e7376cSAlexandre Belloni 
388*e6e7376cSAlexandre Belloni 	steps += value >> 7;
389*e6e7376cSAlexandre Belloni 
390*e6e7376cSAlexandre Belloni 	*offset = DIV_ROUND_CLOSEST(steps * OFFSET_STEP_PPT, 1000);
391*e6e7376cSAlexandre Belloni 
392*e6e7376cSAlexandre Belloni 	return 0;
393*e6e7376cSAlexandre Belloni }
394*e6e7376cSAlexandre Belloni 
395*e6e7376cSAlexandre Belloni static int rv3028_set_offset(struct device *dev, long offset)
396*e6e7376cSAlexandre Belloni {
397*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
398*e6e7376cSAlexandre Belloni 	int ret;
399*e6e7376cSAlexandre Belloni 
400*e6e7376cSAlexandre Belloni 	offset = clamp(offset, -244141L, 243187L) * 1000;
401*e6e7376cSAlexandre Belloni 	offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT);
402*e6e7376cSAlexandre Belloni 
403*e6e7376cSAlexandre Belloni 	ret = regmap_write(rv3028->regmap, RV3028_OFFSET, offset >> 1);
404*e6e7376cSAlexandre Belloni 	if (ret < 0)
405*e6e7376cSAlexandre Belloni 		return ret;
406*e6e7376cSAlexandre Belloni 
407*e6e7376cSAlexandre Belloni 	return regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7),
408*e6e7376cSAlexandre Belloni 				  offset << 7);
409*e6e7376cSAlexandre Belloni }
410*e6e7376cSAlexandre Belloni 
411*e6e7376cSAlexandre Belloni static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
412*e6e7376cSAlexandre Belloni {
413*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028 = dev_get_drvdata(dev);
414*e6e7376cSAlexandre Belloni 	int status, ret = 0;
415*e6e7376cSAlexandre Belloni 
416*e6e7376cSAlexandre Belloni 	switch (cmd) {
417*e6e7376cSAlexandre Belloni 	case RTC_VL_READ:
418*e6e7376cSAlexandre Belloni 		ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status);
419*e6e7376cSAlexandre Belloni 		if (ret < 0)
420*e6e7376cSAlexandre Belloni 			return ret;
421*e6e7376cSAlexandre Belloni 
422*e6e7376cSAlexandre Belloni 		if (status & RV3028_STATUS_PORF)
423*e6e7376cSAlexandre Belloni 			dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n");
424*e6e7376cSAlexandre Belloni 
425*e6e7376cSAlexandre Belloni 		status &= RV3028_STATUS_PORF;
426*e6e7376cSAlexandre Belloni 
427*e6e7376cSAlexandre Belloni 		if (copy_to_user((void __user *)arg, &status, sizeof(int)))
428*e6e7376cSAlexandre Belloni 			return -EFAULT;
429*e6e7376cSAlexandre Belloni 
430*e6e7376cSAlexandre Belloni 		return 0;
431*e6e7376cSAlexandre Belloni 
432*e6e7376cSAlexandre Belloni 	case RTC_VL_CLR:
433*e6e7376cSAlexandre Belloni 		ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
434*e6e7376cSAlexandre Belloni 					 RV3028_STATUS_PORF, 0);
435*e6e7376cSAlexandre Belloni 
436*e6e7376cSAlexandre Belloni 		return ret;
437*e6e7376cSAlexandre Belloni 
438*e6e7376cSAlexandre Belloni 	default:
439*e6e7376cSAlexandre Belloni 		return -ENOIOCTLCMD;
440*e6e7376cSAlexandre Belloni 	}
441*e6e7376cSAlexandre Belloni }
442*e6e7376cSAlexandre Belloni 
443*e6e7376cSAlexandre Belloni static int rv3028_nvram_write(void *priv, unsigned int offset, void *val,
444*e6e7376cSAlexandre Belloni 			      size_t bytes)
445*e6e7376cSAlexandre Belloni {
446*e6e7376cSAlexandre Belloni 	return regmap_bulk_write(priv, RV3028_RAM1 + offset, val, bytes);
447*e6e7376cSAlexandre Belloni }
448*e6e7376cSAlexandre Belloni 
449*e6e7376cSAlexandre Belloni static int rv3028_nvram_read(void *priv, unsigned int offset, void *val,
450*e6e7376cSAlexandre Belloni 			     size_t bytes)
451*e6e7376cSAlexandre Belloni {
452*e6e7376cSAlexandre Belloni 	return regmap_bulk_read(priv, RV3028_RAM1 + offset, val, bytes);
453*e6e7376cSAlexandre Belloni }
454*e6e7376cSAlexandre Belloni 
455*e6e7376cSAlexandre Belloni static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val,
456*e6e7376cSAlexandre Belloni 			       size_t bytes)
457*e6e7376cSAlexandre Belloni {
458*e6e7376cSAlexandre Belloni 	u32 status, ctrl1;
459*e6e7376cSAlexandre Belloni 	int i, ret, err;
460*e6e7376cSAlexandre Belloni 	u8 *buf = val;
461*e6e7376cSAlexandre Belloni 
462*e6e7376cSAlexandre Belloni 	ret = regmap_read(priv, RV3028_CTRL1, &ctrl1);
463*e6e7376cSAlexandre Belloni 	if (ret)
464*e6e7376cSAlexandre Belloni 		return ret;
465*e6e7376cSAlexandre Belloni 
466*e6e7376cSAlexandre Belloni 	if (!(ctrl1 & RV3028_CTRL1_EERD)) {
467*e6e7376cSAlexandre Belloni 		ret = regmap_update_bits(priv, RV3028_CTRL1,
468*e6e7376cSAlexandre Belloni 					 RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
469*e6e7376cSAlexandre Belloni 		if (ret)
470*e6e7376cSAlexandre Belloni 			return ret;
471*e6e7376cSAlexandre Belloni 
472*e6e7376cSAlexandre Belloni 		ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
473*e6e7376cSAlexandre Belloni 					       !(status & RV3028_STATUS_EEBUSY),
474*e6e7376cSAlexandre Belloni 					       RV3028_EEBUSY_POLL,
475*e6e7376cSAlexandre Belloni 					       RV3028_EEBUSY_TIMEOUT);
476*e6e7376cSAlexandre Belloni 		if (ret)
477*e6e7376cSAlexandre Belloni 			goto restore_eerd;
478*e6e7376cSAlexandre Belloni 	}
479*e6e7376cSAlexandre Belloni 
480*e6e7376cSAlexandre Belloni 	for (i = 0; i < bytes; i++) {
481*e6e7376cSAlexandre Belloni 		ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i);
482*e6e7376cSAlexandre Belloni 		if (ret)
483*e6e7376cSAlexandre Belloni 			goto restore_eerd;
484*e6e7376cSAlexandre Belloni 
485*e6e7376cSAlexandre Belloni 		ret = regmap_write(priv, RV3028_EEPROM_DATA, buf[i]);
486*e6e7376cSAlexandre Belloni 		if (ret)
487*e6e7376cSAlexandre Belloni 			goto restore_eerd;
488*e6e7376cSAlexandre Belloni 
489*e6e7376cSAlexandre Belloni 		ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0);
490*e6e7376cSAlexandre Belloni 		if (ret)
491*e6e7376cSAlexandre Belloni 			goto restore_eerd;
492*e6e7376cSAlexandre Belloni 
493*e6e7376cSAlexandre Belloni 		ret = regmap_write(priv, RV3028_EEPROM_CMD,
494*e6e7376cSAlexandre Belloni 				   RV3028_EEPROM_CMD_WRITE);
495*e6e7376cSAlexandre Belloni 		if (ret)
496*e6e7376cSAlexandre Belloni 			goto restore_eerd;
497*e6e7376cSAlexandre Belloni 
498*e6e7376cSAlexandre Belloni 		usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
499*e6e7376cSAlexandre Belloni 
500*e6e7376cSAlexandre Belloni 		ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
501*e6e7376cSAlexandre Belloni 					       !(status & RV3028_STATUS_EEBUSY),
502*e6e7376cSAlexandre Belloni 					       RV3028_EEBUSY_POLL,
503*e6e7376cSAlexandre Belloni 					       RV3028_EEBUSY_TIMEOUT);
504*e6e7376cSAlexandre Belloni 		if (ret)
505*e6e7376cSAlexandre Belloni 			goto restore_eerd;
506*e6e7376cSAlexandre Belloni 	}
507*e6e7376cSAlexandre Belloni 
508*e6e7376cSAlexandre Belloni restore_eerd:
509*e6e7376cSAlexandre Belloni 	if (!(ctrl1 & RV3028_CTRL1_EERD))
510*e6e7376cSAlexandre Belloni 	{
511*e6e7376cSAlexandre Belloni 		err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
512*e6e7376cSAlexandre Belloni 					 0);
513*e6e7376cSAlexandre Belloni 		if (err && !ret)
514*e6e7376cSAlexandre Belloni 			ret = err;
515*e6e7376cSAlexandre Belloni 	}
516*e6e7376cSAlexandre Belloni 
517*e6e7376cSAlexandre Belloni 	return ret;
518*e6e7376cSAlexandre Belloni }
519*e6e7376cSAlexandre Belloni 
520*e6e7376cSAlexandre Belloni static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val,
521*e6e7376cSAlexandre Belloni 			      size_t bytes)
522*e6e7376cSAlexandre Belloni {
523*e6e7376cSAlexandre Belloni 	u32 status, ctrl1, data;
524*e6e7376cSAlexandre Belloni 	int i, ret, err;
525*e6e7376cSAlexandre Belloni 	u8 *buf = val;
526*e6e7376cSAlexandre Belloni 
527*e6e7376cSAlexandre Belloni 	ret = regmap_read(priv, RV3028_CTRL1, &ctrl1);
528*e6e7376cSAlexandre Belloni 	if (ret)
529*e6e7376cSAlexandre Belloni 		return ret;
530*e6e7376cSAlexandre Belloni 
531*e6e7376cSAlexandre Belloni 	if (!(ctrl1 & RV3028_CTRL1_EERD)) {
532*e6e7376cSAlexandre Belloni 		ret = regmap_update_bits(priv, RV3028_CTRL1,
533*e6e7376cSAlexandre Belloni 					 RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
534*e6e7376cSAlexandre Belloni 		if (ret)
535*e6e7376cSAlexandre Belloni 			return ret;
536*e6e7376cSAlexandre Belloni 
537*e6e7376cSAlexandre Belloni 		ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
538*e6e7376cSAlexandre Belloni 					       !(status & RV3028_STATUS_EEBUSY),
539*e6e7376cSAlexandre Belloni 					       RV3028_EEBUSY_POLL,
540*e6e7376cSAlexandre Belloni 					       RV3028_EEBUSY_TIMEOUT);
541*e6e7376cSAlexandre Belloni 		if (ret)
542*e6e7376cSAlexandre Belloni 			goto restore_eerd;
543*e6e7376cSAlexandre Belloni 	}
544*e6e7376cSAlexandre Belloni 
545*e6e7376cSAlexandre Belloni 	for (i = 0; i < bytes; i++) {
546*e6e7376cSAlexandre Belloni 		ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i);
547*e6e7376cSAlexandre Belloni 		if (ret)
548*e6e7376cSAlexandre Belloni 			goto restore_eerd;
549*e6e7376cSAlexandre Belloni 
550*e6e7376cSAlexandre Belloni 		ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0);
551*e6e7376cSAlexandre Belloni 		if (ret)
552*e6e7376cSAlexandre Belloni 			goto restore_eerd;
553*e6e7376cSAlexandre Belloni 
554*e6e7376cSAlexandre Belloni 		ret = regmap_write(priv, RV3028_EEPROM_CMD,
555*e6e7376cSAlexandre Belloni 				   RV3028_EEPROM_CMD_READ);
556*e6e7376cSAlexandre Belloni 		if (ret)
557*e6e7376cSAlexandre Belloni 			goto restore_eerd;
558*e6e7376cSAlexandre Belloni 
559*e6e7376cSAlexandre Belloni 		ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
560*e6e7376cSAlexandre Belloni 					       !(status & RV3028_STATUS_EEBUSY),
561*e6e7376cSAlexandre Belloni 					       RV3028_EEBUSY_POLL,
562*e6e7376cSAlexandre Belloni 					       RV3028_EEBUSY_TIMEOUT);
563*e6e7376cSAlexandre Belloni 		if (ret)
564*e6e7376cSAlexandre Belloni 			goto restore_eerd;
565*e6e7376cSAlexandre Belloni 
566*e6e7376cSAlexandre Belloni 		ret = regmap_read(priv, RV3028_EEPROM_DATA, &data);
567*e6e7376cSAlexandre Belloni 		if (ret)
568*e6e7376cSAlexandre Belloni 			goto restore_eerd;
569*e6e7376cSAlexandre Belloni 		buf[i] = data;
570*e6e7376cSAlexandre Belloni 	}
571*e6e7376cSAlexandre Belloni 
572*e6e7376cSAlexandre Belloni restore_eerd:
573*e6e7376cSAlexandre Belloni 	if (!(ctrl1 & RV3028_CTRL1_EERD))
574*e6e7376cSAlexandre Belloni 	{
575*e6e7376cSAlexandre Belloni 		err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
576*e6e7376cSAlexandre Belloni 					 0);
577*e6e7376cSAlexandre Belloni 		if (err && !ret)
578*e6e7376cSAlexandre Belloni 			ret = err;
579*e6e7376cSAlexandre Belloni 	}
580*e6e7376cSAlexandre Belloni 
581*e6e7376cSAlexandre Belloni 	return ret;
582*e6e7376cSAlexandre Belloni }
583*e6e7376cSAlexandre Belloni 
584*e6e7376cSAlexandre Belloni static struct rtc_class_ops rv3028_rtc_ops = {
585*e6e7376cSAlexandre Belloni 	.read_time = rv3028_get_time,
586*e6e7376cSAlexandre Belloni 	.set_time = rv3028_set_time,
587*e6e7376cSAlexandre Belloni 	.read_offset = rv3028_read_offset,
588*e6e7376cSAlexandre Belloni 	.set_offset = rv3028_set_offset,
589*e6e7376cSAlexandre Belloni 	.ioctl = rv3028_ioctl,
590*e6e7376cSAlexandre Belloni };
591*e6e7376cSAlexandre Belloni 
592*e6e7376cSAlexandre Belloni static const struct regmap_config regmap_config = {
593*e6e7376cSAlexandre Belloni         .reg_bits = 8,
594*e6e7376cSAlexandre Belloni         .val_bits = 8,
595*e6e7376cSAlexandre Belloni         .max_register = 0x37,
596*e6e7376cSAlexandre Belloni };
597*e6e7376cSAlexandre Belloni 
598*e6e7376cSAlexandre Belloni static int rv3028_probe(struct i2c_client *client)
599*e6e7376cSAlexandre Belloni {
600*e6e7376cSAlexandre Belloni 	struct rv3028_data *rv3028;
601*e6e7376cSAlexandre Belloni 	int ret, status;
602*e6e7376cSAlexandre Belloni 	u32 ohms;
603*e6e7376cSAlexandre Belloni 	struct nvmem_config nvmem_cfg = {
604*e6e7376cSAlexandre Belloni 		.name = "rv3028_nvram",
605*e6e7376cSAlexandre Belloni 		.word_size = 1,
606*e6e7376cSAlexandre Belloni 		.stride = 1,
607*e6e7376cSAlexandre Belloni 		.size = 2,
608*e6e7376cSAlexandre Belloni 		.type = NVMEM_TYPE_BATTERY_BACKED,
609*e6e7376cSAlexandre Belloni 		.reg_read = rv3028_nvram_read,
610*e6e7376cSAlexandre Belloni 		.reg_write = rv3028_nvram_write,
611*e6e7376cSAlexandre Belloni 	};
612*e6e7376cSAlexandre Belloni 	struct nvmem_config eeprom_cfg = {
613*e6e7376cSAlexandre Belloni 		.name = "rv3028_eeprom",
614*e6e7376cSAlexandre Belloni 		.word_size = 1,
615*e6e7376cSAlexandre Belloni 		.stride = 1,
616*e6e7376cSAlexandre Belloni 		.size = 43,
617*e6e7376cSAlexandre Belloni 		.type = NVMEM_TYPE_EEPROM,
618*e6e7376cSAlexandre Belloni 		.reg_read = rv3028_eeprom_read,
619*e6e7376cSAlexandre Belloni 		.reg_write = rv3028_eeprom_write,
620*e6e7376cSAlexandre Belloni 	};
621*e6e7376cSAlexandre Belloni 
622*e6e7376cSAlexandre Belloni 	rv3028 = devm_kzalloc(&client->dev, sizeof(struct rv3028_data),
623*e6e7376cSAlexandre Belloni 			      GFP_KERNEL);
624*e6e7376cSAlexandre Belloni 	if (!rv3028)
625*e6e7376cSAlexandre Belloni 		return -ENOMEM;
626*e6e7376cSAlexandre Belloni 
627*e6e7376cSAlexandre Belloni 	rv3028->regmap = devm_regmap_init_i2c(client, &regmap_config);
628*e6e7376cSAlexandre Belloni 
629*e6e7376cSAlexandre Belloni 	i2c_set_clientdata(client, rv3028);
630*e6e7376cSAlexandre Belloni 
631*e6e7376cSAlexandre Belloni 	ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status);
632*e6e7376cSAlexandre Belloni 	if (ret < 0)
633*e6e7376cSAlexandre Belloni 		return ret;
634*e6e7376cSAlexandre Belloni 
635*e6e7376cSAlexandre Belloni 	if (status & RV3028_STATUS_PORF)
636*e6e7376cSAlexandre Belloni 		dev_warn(&client->dev, "Voltage low, data loss detected.\n");
637*e6e7376cSAlexandre Belloni 
638*e6e7376cSAlexandre Belloni 	if (status & RV3028_STATUS_AF)
639*e6e7376cSAlexandre Belloni 		dev_warn(&client->dev, "An alarm may have been missed.\n");
640*e6e7376cSAlexandre Belloni 
641*e6e7376cSAlexandre Belloni 	rv3028->rtc = devm_rtc_allocate_device(&client->dev);
642*e6e7376cSAlexandre Belloni 	if (IS_ERR(rv3028->rtc)) {
643*e6e7376cSAlexandre Belloni 		return PTR_ERR(rv3028->rtc);
644*e6e7376cSAlexandre Belloni 	}
645*e6e7376cSAlexandre Belloni 
646*e6e7376cSAlexandre Belloni 	if (client->irq > 0) {
647*e6e7376cSAlexandre Belloni 		ret = devm_request_threaded_irq(&client->dev, client->irq,
648*e6e7376cSAlexandre Belloni 						NULL, rv3028_handle_irq,
649*e6e7376cSAlexandre Belloni 						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
650*e6e7376cSAlexandre Belloni 						"rv3028", rv3028);
651*e6e7376cSAlexandre Belloni 		if (ret) {
652*e6e7376cSAlexandre Belloni 			dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
653*e6e7376cSAlexandre Belloni 			client->irq = 0;
654*e6e7376cSAlexandre Belloni 		} else {
655*e6e7376cSAlexandre Belloni 			rv3028_rtc_ops.read_alarm = rv3028_get_alarm;
656*e6e7376cSAlexandre Belloni 			rv3028_rtc_ops.set_alarm = rv3028_set_alarm;
657*e6e7376cSAlexandre Belloni 			rv3028_rtc_ops.alarm_irq_enable = rv3028_alarm_irq_enable;
658*e6e7376cSAlexandre Belloni 		}
659*e6e7376cSAlexandre Belloni 	}
660*e6e7376cSAlexandre Belloni 
661*e6e7376cSAlexandre Belloni 	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1,
662*e6e7376cSAlexandre Belloni 				 RV3028_CTRL1_WADA, RV3028_CTRL1_WADA);
663*e6e7376cSAlexandre Belloni 	if (ret)
664*e6e7376cSAlexandre Belloni 		return ret;
665*e6e7376cSAlexandre Belloni 
666*e6e7376cSAlexandre Belloni 	/* setup timestamping */
667*e6e7376cSAlexandre Belloni 	ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2,
668*e6e7376cSAlexandre Belloni 				 RV3028_CTRL2_EIE | RV3028_CTRL2_TSE,
669*e6e7376cSAlexandre Belloni 				 RV3028_CTRL2_EIE | RV3028_CTRL2_TSE);
670*e6e7376cSAlexandre Belloni 	if (ret)
671*e6e7376cSAlexandre Belloni 		return ret;
672*e6e7376cSAlexandre Belloni 
673*e6e7376cSAlexandre Belloni 	/* setup trickle charger */
674*e6e7376cSAlexandre Belloni 	if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms",
675*e6e7376cSAlexandre Belloni 				      &ohms)) {
676*e6e7376cSAlexandre Belloni 		int i;
677*e6e7376cSAlexandre Belloni 
678*e6e7376cSAlexandre Belloni 		for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++)
679*e6e7376cSAlexandre Belloni 			if (ohms == rv3028_trickle_resistors[i])
680*e6e7376cSAlexandre Belloni 				break;
681*e6e7376cSAlexandre Belloni 
682*e6e7376cSAlexandre Belloni 		if (i < ARRAY_SIZE(rv3028_trickle_resistors)) {
683*e6e7376cSAlexandre Belloni 			ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP,
684*e6e7376cSAlexandre Belloni 						 RV3028_BACKUP_TCE |
685*e6e7376cSAlexandre Belloni 						 RV3028_BACKUP_TCR_MASK,
686*e6e7376cSAlexandre Belloni 						 RV3028_BACKUP_TCE | i);
687*e6e7376cSAlexandre Belloni 			if (ret)
688*e6e7376cSAlexandre Belloni 				return ret;
689*e6e7376cSAlexandre Belloni 		} else {
690*e6e7376cSAlexandre Belloni 			dev_warn(&client->dev, "invalid trickle resistor value\n");
691*e6e7376cSAlexandre Belloni 		}
692*e6e7376cSAlexandre Belloni 	}
693*e6e7376cSAlexandre Belloni 
694*e6e7376cSAlexandre Belloni 	ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group);
695*e6e7376cSAlexandre Belloni 	if (ret)
696*e6e7376cSAlexandre Belloni 		return ret;
697*e6e7376cSAlexandre Belloni 
698*e6e7376cSAlexandre Belloni 	rv3028->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
699*e6e7376cSAlexandre Belloni 	rv3028->rtc->range_max = RTC_TIMESTAMP_END_2099;
700*e6e7376cSAlexandre Belloni 	rv3028->rtc->ops = &rv3028_rtc_ops;
701*e6e7376cSAlexandre Belloni 	ret = rtc_register_device(rv3028->rtc);
702*e6e7376cSAlexandre Belloni 	if (ret)
703*e6e7376cSAlexandre Belloni 		return ret;
704*e6e7376cSAlexandre Belloni 
705*e6e7376cSAlexandre Belloni 	nvmem_cfg.priv = rv3028->regmap;
706*e6e7376cSAlexandre Belloni 	rtc_nvmem_register(rv3028->rtc, &nvmem_cfg);
707*e6e7376cSAlexandre Belloni 	eeprom_cfg.priv = rv3028->regmap;
708*e6e7376cSAlexandre Belloni 	rtc_nvmem_register(rv3028->rtc, &eeprom_cfg);
709*e6e7376cSAlexandre Belloni 
710*e6e7376cSAlexandre Belloni 	rv3028->rtc->max_user_freq = 1;
711*e6e7376cSAlexandre Belloni 
712*e6e7376cSAlexandre Belloni 	return 0;
713*e6e7376cSAlexandre Belloni }
714*e6e7376cSAlexandre Belloni 
715*e6e7376cSAlexandre Belloni static const struct of_device_id rv3028_of_match[] = {
716*e6e7376cSAlexandre Belloni 	{ .compatible = "microcrystal,rv3028", },
717*e6e7376cSAlexandre Belloni 	{ }
718*e6e7376cSAlexandre Belloni };
719*e6e7376cSAlexandre Belloni MODULE_DEVICE_TABLE(of, rv3028_of_match);
720*e6e7376cSAlexandre Belloni 
721*e6e7376cSAlexandre Belloni static struct i2c_driver rv3028_driver = {
722*e6e7376cSAlexandre Belloni 	.driver = {
723*e6e7376cSAlexandre Belloni 		.name = "rtc-rv3028",
724*e6e7376cSAlexandre Belloni 		.of_match_table = of_match_ptr(rv3028_of_match),
725*e6e7376cSAlexandre Belloni 	},
726*e6e7376cSAlexandre Belloni 	.probe_new	= rv3028_probe,
727*e6e7376cSAlexandre Belloni };
728*e6e7376cSAlexandre Belloni module_i2c_driver(rv3028_driver);
729*e6e7376cSAlexandre Belloni 
730*e6e7376cSAlexandre Belloni MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
731*e6e7376cSAlexandre Belloni MODULE_DESCRIPTION("Micro Crystal RV3028 RTC driver");
732*e6e7376cSAlexandre Belloni MODULE_LICENSE("GPL v2");
733