xref: /OK3568_Linux_fs/kernel/drivers/rtc/rtc-pcf8523.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2012 Avionic Design GmbH
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/bcd.h>
7*4882a593Smuzhiyun #include <linux/i2c.h>
8*4882a593Smuzhiyun #include <linux/module.h>
9*4882a593Smuzhiyun #include <linux/rtc.h>
10*4882a593Smuzhiyun #include <linux/of.h>
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #define DRIVER_NAME "rtc-pcf8523"
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #define REG_CONTROL1 0x00
15*4882a593Smuzhiyun #define REG_CONTROL1_CAP_SEL (1 << 7)
16*4882a593Smuzhiyun #define REG_CONTROL1_STOP    (1 << 5)
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #define REG_CONTROL3 0x02
19*4882a593Smuzhiyun #define REG_CONTROL3_PM_BLD (1 << 7) /* battery low detection disabled */
20*4882a593Smuzhiyun #define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */
21*4882a593Smuzhiyun #define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */
22*4882a593Smuzhiyun #define REG_CONTROL3_PM_MASK 0xe0
23*4882a593Smuzhiyun #define REG_CONTROL3_BLF (1 << 2) /* battery low bit, read-only */
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define REG_SECONDS  0x03
26*4882a593Smuzhiyun #define REG_SECONDS_OS (1 << 7)
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define REG_MINUTES  0x04
29*4882a593Smuzhiyun #define REG_HOURS    0x05
30*4882a593Smuzhiyun #define REG_DAYS     0x06
31*4882a593Smuzhiyun #define REG_WEEKDAYS 0x07
32*4882a593Smuzhiyun #define REG_MONTHS   0x08
33*4882a593Smuzhiyun #define REG_YEARS    0x09
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #define REG_OFFSET   0x0e
36*4882a593Smuzhiyun #define REG_OFFSET_MODE BIT(7)
37*4882a593Smuzhiyun 
pcf8523_read(struct i2c_client * client,u8 reg,u8 * valuep)38*4882a593Smuzhiyun static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun 	struct i2c_msg msgs[2];
41*4882a593Smuzhiyun 	u8 value = 0;
42*4882a593Smuzhiyun 	int err;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	msgs[0].addr = client->addr;
45*4882a593Smuzhiyun 	msgs[0].flags = 0;
46*4882a593Smuzhiyun 	msgs[0].len = sizeof(reg);
47*4882a593Smuzhiyun 	msgs[0].buf = &reg;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	msgs[1].addr = client->addr;
50*4882a593Smuzhiyun 	msgs[1].flags = I2C_M_RD;
51*4882a593Smuzhiyun 	msgs[1].len = sizeof(value);
52*4882a593Smuzhiyun 	msgs[1].buf = &value;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
55*4882a593Smuzhiyun 	if (err < 0)
56*4882a593Smuzhiyun 		return err;
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	*valuep = value;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	return 0;
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun 
pcf8523_write(struct i2c_client * client,u8 reg,u8 value)63*4882a593Smuzhiyun static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value)
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun 	u8 buffer[2] = { reg, value };
66*4882a593Smuzhiyun 	struct i2c_msg msg;
67*4882a593Smuzhiyun 	int err;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	msg.addr = client->addr;
70*4882a593Smuzhiyun 	msg.flags = 0;
71*4882a593Smuzhiyun 	msg.len = sizeof(buffer);
72*4882a593Smuzhiyun 	msg.buf = buffer;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	err = i2c_transfer(client->adapter, &msg, 1);
75*4882a593Smuzhiyun 	if (err < 0)
76*4882a593Smuzhiyun 		return err;
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	return 0;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
pcf8523_voltage_low(struct i2c_client * client)81*4882a593Smuzhiyun static int pcf8523_voltage_low(struct i2c_client *client)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	u8 value;
84*4882a593Smuzhiyun 	int err;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	err = pcf8523_read(client, REG_CONTROL3, &value);
87*4882a593Smuzhiyun 	if (err < 0)
88*4882a593Smuzhiyun 		return err;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	return !!(value & REG_CONTROL3_BLF);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
pcf8523_load_capacitance(struct i2c_client * client)93*4882a593Smuzhiyun static int pcf8523_load_capacitance(struct i2c_client *client)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	u32 load;
96*4882a593Smuzhiyun 	u8 value;
97*4882a593Smuzhiyun 	int err;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	err = pcf8523_read(client, REG_CONTROL1, &value);
100*4882a593Smuzhiyun 	if (err < 0)
101*4882a593Smuzhiyun 		return err;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	load = 12500;
104*4882a593Smuzhiyun 	of_property_read_u32(client->dev.of_node, "quartz-load-femtofarads",
105*4882a593Smuzhiyun 			     &load);
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	switch (load) {
108*4882a593Smuzhiyun 	default:
109*4882a593Smuzhiyun 		dev_warn(&client->dev, "Unknown quartz-load-femtofarads value: %d. Assuming 12500",
110*4882a593Smuzhiyun 			 load);
111*4882a593Smuzhiyun 		fallthrough;
112*4882a593Smuzhiyun 	case 12500:
113*4882a593Smuzhiyun 		value |= REG_CONTROL1_CAP_SEL;
114*4882a593Smuzhiyun 		break;
115*4882a593Smuzhiyun 	case 7000:
116*4882a593Smuzhiyun 		value &= ~REG_CONTROL1_CAP_SEL;
117*4882a593Smuzhiyun 		break;
118*4882a593Smuzhiyun 	}
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	err = pcf8523_write(client, REG_CONTROL1, value);
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	return err;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
pcf8523_set_pm(struct i2c_client * client,u8 pm)125*4882a593Smuzhiyun static int pcf8523_set_pm(struct i2c_client *client, u8 pm)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun 	u8 value;
128*4882a593Smuzhiyun 	int err;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	err = pcf8523_read(client, REG_CONTROL3, &value);
131*4882a593Smuzhiyun 	if (err < 0)
132*4882a593Smuzhiyun 		return err;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	value = (value & ~REG_CONTROL3_PM_MASK) | pm;
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	err = pcf8523_write(client, REG_CONTROL3, value);
137*4882a593Smuzhiyun 	if (err < 0)
138*4882a593Smuzhiyun 		return err;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	return 0;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
pcf8523_stop_rtc(struct i2c_client * client)143*4882a593Smuzhiyun static int pcf8523_stop_rtc(struct i2c_client *client)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	u8 value;
146*4882a593Smuzhiyun 	int err;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	err = pcf8523_read(client, REG_CONTROL1, &value);
149*4882a593Smuzhiyun 	if (err < 0)
150*4882a593Smuzhiyun 		return err;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	value |= REG_CONTROL1_STOP;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	err = pcf8523_write(client, REG_CONTROL1, value);
155*4882a593Smuzhiyun 	if (err < 0)
156*4882a593Smuzhiyun 		return err;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	return 0;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun 
pcf8523_start_rtc(struct i2c_client * client)161*4882a593Smuzhiyun static int pcf8523_start_rtc(struct i2c_client *client)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	u8 value;
164*4882a593Smuzhiyun 	int err;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	err = pcf8523_read(client, REG_CONTROL1, &value);
167*4882a593Smuzhiyun 	if (err < 0)
168*4882a593Smuzhiyun 		return err;
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	value &= ~REG_CONTROL1_STOP;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	err = pcf8523_write(client, REG_CONTROL1, value);
173*4882a593Smuzhiyun 	if (err < 0)
174*4882a593Smuzhiyun 		return err;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	return 0;
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun 
pcf8523_rtc_read_time(struct device * dev,struct rtc_time * tm)179*4882a593Smuzhiyun static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun 	struct i2c_client *client = to_i2c_client(dev);
182*4882a593Smuzhiyun 	u8 start = REG_SECONDS, regs[7];
183*4882a593Smuzhiyun 	struct i2c_msg msgs[2];
184*4882a593Smuzhiyun 	int err;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	err = pcf8523_voltage_low(client);
187*4882a593Smuzhiyun 	if (err < 0) {
188*4882a593Smuzhiyun 		return err;
189*4882a593Smuzhiyun 	} else if (err > 0) {
190*4882a593Smuzhiyun 		dev_err(dev, "low voltage detected, time is unreliable\n");
191*4882a593Smuzhiyun 		return -EINVAL;
192*4882a593Smuzhiyun 	}
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	msgs[0].addr = client->addr;
195*4882a593Smuzhiyun 	msgs[0].flags = 0;
196*4882a593Smuzhiyun 	msgs[0].len = 1;
197*4882a593Smuzhiyun 	msgs[0].buf = &start;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	msgs[1].addr = client->addr;
200*4882a593Smuzhiyun 	msgs[1].flags = I2C_M_RD;
201*4882a593Smuzhiyun 	msgs[1].len = sizeof(regs);
202*4882a593Smuzhiyun 	msgs[1].buf = regs;
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
205*4882a593Smuzhiyun 	if (err < 0)
206*4882a593Smuzhiyun 		return err;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	if (regs[0] & REG_SECONDS_OS)
209*4882a593Smuzhiyun 		return -EINVAL;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	tm->tm_sec = bcd2bin(regs[0] & 0x7f);
212*4882a593Smuzhiyun 	tm->tm_min = bcd2bin(regs[1] & 0x7f);
213*4882a593Smuzhiyun 	tm->tm_hour = bcd2bin(regs[2] & 0x3f);
214*4882a593Smuzhiyun 	tm->tm_mday = bcd2bin(regs[3] & 0x3f);
215*4882a593Smuzhiyun 	tm->tm_wday = regs[4] & 0x7;
216*4882a593Smuzhiyun 	tm->tm_mon = bcd2bin(regs[5] & 0x1f) - 1;
217*4882a593Smuzhiyun 	tm->tm_year = bcd2bin(regs[6]) + 100;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	return 0;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun 
pcf8523_rtc_set_time(struct device * dev,struct rtc_time * tm)222*4882a593Smuzhiyun static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun 	struct i2c_client *client = to_i2c_client(dev);
225*4882a593Smuzhiyun 	struct i2c_msg msg;
226*4882a593Smuzhiyun 	u8 regs[8];
227*4882a593Smuzhiyun 	int err;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	/*
230*4882a593Smuzhiyun 	 * The hardware can only store values between 0 and 99 in it's YEAR
231*4882a593Smuzhiyun 	 * register (with 99 overflowing to 0 on increment).
232*4882a593Smuzhiyun 	 * After 2100-02-28 we could start interpreting the year to be in the
233*4882a593Smuzhiyun 	 * interval [2100, 2199], but there is no path to switch in a smooth way
234*4882a593Smuzhiyun 	 * because the chip handles YEAR=0x00 (and the out-of-spec
235*4882a593Smuzhiyun 	 * YEAR=0xa0) as a leap year, but 2100 isn't.
236*4882a593Smuzhiyun 	 */
237*4882a593Smuzhiyun 	if (tm->tm_year < 100 || tm->tm_year >= 200)
238*4882a593Smuzhiyun 		return -EINVAL;
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	err = pcf8523_stop_rtc(client);
241*4882a593Smuzhiyun 	if (err < 0)
242*4882a593Smuzhiyun 		return err;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	regs[0] = REG_SECONDS;
245*4882a593Smuzhiyun 	/* This will purposely overwrite REG_SECONDS_OS */
246*4882a593Smuzhiyun 	regs[1] = bin2bcd(tm->tm_sec);
247*4882a593Smuzhiyun 	regs[2] = bin2bcd(tm->tm_min);
248*4882a593Smuzhiyun 	regs[3] = bin2bcd(tm->tm_hour);
249*4882a593Smuzhiyun 	regs[4] = bin2bcd(tm->tm_mday);
250*4882a593Smuzhiyun 	regs[5] = tm->tm_wday;
251*4882a593Smuzhiyun 	regs[6] = bin2bcd(tm->tm_mon + 1);
252*4882a593Smuzhiyun 	regs[7] = bin2bcd(tm->tm_year - 100);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	msg.addr = client->addr;
255*4882a593Smuzhiyun 	msg.flags = 0;
256*4882a593Smuzhiyun 	msg.len = sizeof(regs);
257*4882a593Smuzhiyun 	msg.buf = regs;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	err = i2c_transfer(client->adapter, &msg, 1);
260*4882a593Smuzhiyun 	if (err < 0) {
261*4882a593Smuzhiyun 		/*
262*4882a593Smuzhiyun 		 * If the time cannot be set, restart the RTC anyway. Note
263*4882a593Smuzhiyun 		 * that errors are ignored if the RTC cannot be started so
264*4882a593Smuzhiyun 		 * that we have a chance to propagate the original error.
265*4882a593Smuzhiyun 		 */
266*4882a593Smuzhiyun 		pcf8523_start_rtc(client);
267*4882a593Smuzhiyun 		return err;
268*4882a593Smuzhiyun 	}
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	return pcf8523_start_rtc(client);
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun #ifdef CONFIG_RTC_INTF_DEV
pcf8523_rtc_ioctl(struct device * dev,unsigned int cmd,unsigned long arg)274*4882a593Smuzhiyun static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
275*4882a593Smuzhiyun 			     unsigned long arg)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun 	struct i2c_client *client = to_i2c_client(dev);
278*4882a593Smuzhiyun 	int ret;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	switch (cmd) {
281*4882a593Smuzhiyun 	case RTC_VL_READ:
282*4882a593Smuzhiyun 		ret = pcf8523_voltage_low(client);
283*4882a593Smuzhiyun 		if (ret < 0)
284*4882a593Smuzhiyun 			return ret;
285*4882a593Smuzhiyun 		if (ret)
286*4882a593Smuzhiyun 			ret = RTC_VL_BACKUP_LOW;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 		return put_user(ret, (unsigned int __user *)arg);
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	default:
291*4882a593Smuzhiyun 		return -ENOIOCTLCMD;
292*4882a593Smuzhiyun 	}
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun #else
295*4882a593Smuzhiyun #define pcf8523_rtc_ioctl NULL
296*4882a593Smuzhiyun #endif
297*4882a593Smuzhiyun 
pcf8523_rtc_read_offset(struct device * dev,long * offset)298*4882a593Smuzhiyun static int pcf8523_rtc_read_offset(struct device *dev, long *offset)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun 	struct i2c_client *client = to_i2c_client(dev);
301*4882a593Smuzhiyun 	int err;
302*4882a593Smuzhiyun 	u8 value;
303*4882a593Smuzhiyun 	s8 val;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	err = pcf8523_read(client, REG_OFFSET, &value);
306*4882a593Smuzhiyun 	if (err < 0)
307*4882a593Smuzhiyun 		return err;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	/* sign extend the 7-bit offset value */
310*4882a593Smuzhiyun 	val = value << 1;
311*4882a593Smuzhiyun 	*offset = (value & REG_OFFSET_MODE ? 4069 : 4340) * (val >> 1);
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	return 0;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun 
pcf8523_rtc_set_offset(struct device * dev,long offset)316*4882a593Smuzhiyun static int pcf8523_rtc_set_offset(struct device *dev, long offset)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun 	struct i2c_client *client = to_i2c_client(dev);
319*4882a593Smuzhiyun 	long reg_m0, reg_m1;
320*4882a593Smuzhiyun 	u8 value;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	reg_m0 = clamp(DIV_ROUND_CLOSEST(offset, 4340), -64L, 63L);
323*4882a593Smuzhiyun 	reg_m1 = clamp(DIV_ROUND_CLOSEST(offset, 4069), -64L, 63L);
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	if (abs(reg_m0 * 4340 - offset) < abs(reg_m1 * 4069 - offset))
326*4882a593Smuzhiyun 		value = reg_m0 & 0x7f;
327*4882a593Smuzhiyun 	else
328*4882a593Smuzhiyun 		value = (reg_m1 & 0x7f) | REG_OFFSET_MODE;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	return pcf8523_write(client, REG_OFFSET, value);
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun static const struct rtc_class_ops pcf8523_rtc_ops = {
334*4882a593Smuzhiyun 	.read_time = pcf8523_rtc_read_time,
335*4882a593Smuzhiyun 	.set_time = pcf8523_rtc_set_time,
336*4882a593Smuzhiyun 	.ioctl = pcf8523_rtc_ioctl,
337*4882a593Smuzhiyun 	.read_offset = pcf8523_rtc_read_offset,
338*4882a593Smuzhiyun 	.set_offset = pcf8523_rtc_set_offset,
339*4882a593Smuzhiyun };
340*4882a593Smuzhiyun 
pcf8523_probe(struct i2c_client * client,const struct i2c_device_id * id)341*4882a593Smuzhiyun static int pcf8523_probe(struct i2c_client *client,
342*4882a593Smuzhiyun 			 const struct i2c_device_id *id)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun 	struct rtc_device *rtc;
345*4882a593Smuzhiyun 	int err;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
348*4882a593Smuzhiyun 		return -ENODEV;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	err = pcf8523_load_capacitance(client);
351*4882a593Smuzhiyun 	if (err < 0)
352*4882a593Smuzhiyun 		dev_warn(&client->dev, "failed to set xtal load capacitance: %d",
353*4882a593Smuzhiyun 			 err);
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	err = pcf8523_set_pm(client, 0);
356*4882a593Smuzhiyun 	if (err < 0)
357*4882a593Smuzhiyun 		return err;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	rtc = devm_rtc_device_register(&client->dev, DRIVER_NAME,
360*4882a593Smuzhiyun 				       &pcf8523_rtc_ops, THIS_MODULE);
361*4882a593Smuzhiyun 	if (IS_ERR(rtc))
362*4882a593Smuzhiyun 		return PTR_ERR(rtc);
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	return 0;
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun static const struct i2c_device_id pcf8523_id[] = {
368*4882a593Smuzhiyun 	{ "pcf8523", 0 },
369*4882a593Smuzhiyun 	{ }
370*4882a593Smuzhiyun };
371*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, pcf8523_id);
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun #ifdef CONFIG_OF
374*4882a593Smuzhiyun static const struct of_device_id pcf8523_of_match[] = {
375*4882a593Smuzhiyun 	{ .compatible = "nxp,pcf8523" },
376*4882a593Smuzhiyun 	{ .compatible = "microcrystal,rv8523" },
377*4882a593Smuzhiyun 	{ }
378*4882a593Smuzhiyun };
379*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, pcf8523_of_match);
380*4882a593Smuzhiyun #endif
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun static struct i2c_driver pcf8523_driver = {
383*4882a593Smuzhiyun 	.driver = {
384*4882a593Smuzhiyun 		.name = DRIVER_NAME,
385*4882a593Smuzhiyun 		.of_match_table = of_match_ptr(pcf8523_of_match),
386*4882a593Smuzhiyun 	},
387*4882a593Smuzhiyun 	.probe = pcf8523_probe,
388*4882a593Smuzhiyun 	.id_table = pcf8523_id,
389*4882a593Smuzhiyun };
390*4882a593Smuzhiyun module_i2c_driver(pcf8523_driver);
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
393*4882a593Smuzhiyun MODULE_DESCRIPTION("NXP PCF8523 RTC driver");
394*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
395