xref: /linux/drivers/rtc/rtc-x1205.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21fec7c66SAlessandro Zummo /*
31fec7c66SAlessandro Zummo  * An i2c driver for the Xicor/Intersil X1205 RTC
41fec7c66SAlessandro Zummo  * Copyright 2004 Karen Spearel
51fec7c66SAlessandro Zummo  * Copyright 2005 Alessandro Zummo
61fec7c66SAlessandro Zummo  *
71fec7c66SAlessandro Zummo  * please send all reports to:
81fec7c66SAlessandro Zummo  *	Karen Spearel <kas111 at gmail dot com>
91fec7c66SAlessandro Zummo  *	Alessandro Zummo <a.zummo@towertech.it>
101fec7c66SAlessandro Zummo  *
111fec7c66SAlessandro Zummo  * based on a lot of other RTC drivers.
121fec7c66SAlessandro Zummo  *
13890e0375SJean Delvare  * Information and datasheet:
14890e0375SJean Delvare  * http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html
151fec7c66SAlessandro Zummo  */
161fec7c66SAlessandro Zummo 
171fec7c66SAlessandro Zummo #include <linux/i2c.h>
181fec7c66SAlessandro Zummo #include <linux/bcd.h>
191fec7c66SAlessandro Zummo #include <linux/rtc.h>
201fec7c66SAlessandro Zummo #include <linux/delay.h>
212113852bSPaul Gortmaker #include <linux/module.h>
2286e66604SMartin Kepplinger #include <linux/bitops.h>
231fec7c66SAlessandro Zummo 
241fec7c66SAlessandro Zummo /* offsets into CCR area */
251fec7c66SAlessandro Zummo 
261fec7c66SAlessandro Zummo #define CCR_SEC			0
271fec7c66SAlessandro Zummo #define CCR_MIN			1
281fec7c66SAlessandro Zummo #define CCR_HOUR		2
291fec7c66SAlessandro Zummo #define CCR_MDAY		3
301fec7c66SAlessandro Zummo #define CCR_MONTH		4
311fec7c66SAlessandro Zummo #define CCR_YEAR		5
321fec7c66SAlessandro Zummo #define CCR_WDAY		6
331fec7c66SAlessandro Zummo #define CCR_Y2K			7
341fec7c66SAlessandro Zummo 
351fec7c66SAlessandro Zummo #define X1205_REG_SR		0x3F	/* status register */
361fec7c66SAlessandro Zummo #define X1205_REG_Y2K		0x37
371fec7c66SAlessandro Zummo #define X1205_REG_DW		0x36
381fec7c66SAlessandro Zummo #define X1205_REG_YR		0x35
391fec7c66SAlessandro Zummo #define X1205_REG_MO		0x34
401fec7c66SAlessandro Zummo #define X1205_REG_DT		0x33
411fec7c66SAlessandro Zummo #define X1205_REG_HR		0x32
421fec7c66SAlessandro Zummo #define X1205_REG_MN		0x31
431fec7c66SAlessandro Zummo #define X1205_REG_SC		0x30
441fec7c66SAlessandro Zummo #define X1205_REG_DTR		0x13
451fec7c66SAlessandro Zummo #define X1205_REG_ATR		0x12
461fec7c66SAlessandro Zummo #define X1205_REG_INT		0x11
471fec7c66SAlessandro Zummo #define X1205_REG_0		0x10
481fec7c66SAlessandro Zummo #define X1205_REG_Y2K1		0x0F
491fec7c66SAlessandro Zummo #define X1205_REG_DWA1		0x0E
501fec7c66SAlessandro Zummo #define X1205_REG_YRA1		0x0D
511fec7c66SAlessandro Zummo #define X1205_REG_MOA1		0x0C
521fec7c66SAlessandro Zummo #define X1205_REG_DTA1		0x0B
531fec7c66SAlessandro Zummo #define X1205_REG_HRA1		0x0A
541fec7c66SAlessandro Zummo #define X1205_REG_MNA1		0x09
551fec7c66SAlessandro Zummo #define X1205_REG_SCA1		0x08
561fec7c66SAlessandro Zummo #define X1205_REG_Y2K0		0x07
571fec7c66SAlessandro Zummo #define X1205_REG_DWA0		0x06
581fec7c66SAlessandro Zummo #define X1205_REG_YRA0		0x05
591fec7c66SAlessandro Zummo #define X1205_REG_MOA0		0x04
601fec7c66SAlessandro Zummo #define X1205_REG_DTA0		0x03
611fec7c66SAlessandro Zummo #define X1205_REG_HRA0		0x02
621fec7c66SAlessandro Zummo #define X1205_REG_MNA0		0x01
631fec7c66SAlessandro Zummo #define X1205_REG_SCA0		0x00
641fec7c66SAlessandro Zummo 
651fec7c66SAlessandro Zummo #define X1205_CCR_BASE		0x30	/* Base address of CCR */
661fec7c66SAlessandro Zummo #define X1205_ALM0_BASE		0x00	/* Base address of ALARM0 */
671fec7c66SAlessandro Zummo 
681fec7c66SAlessandro Zummo #define X1205_SR_RTCF		0x01	/* Clock failure */
691fec7c66SAlessandro Zummo #define X1205_SR_WEL		0x02	/* Write Enable Latch */
701fec7c66SAlessandro Zummo #define X1205_SR_RWEL		0x04	/* Register Write Enable */
71471d47e3SMichael Hamel #define X1205_SR_AL0		0x20	/* Alarm 0 match */
721fec7c66SAlessandro Zummo 
731fec7c66SAlessandro Zummo #define X1205_DTR_DTR0		0x01
741fec7c66SAlessandro Zummo #define X1205_DTR_DTR1		0x02
751fec7c66SAlessandro Zummo #define X1205_DTR_DTR2		0x04
761fec7c66SAlessandro Zummo 
771fec7c66SAlessandro Zummo #define X1205_HR_MIL		0x80	/* Set in ccr.hour for 24 hr mode */
781fec7c66SAlessandro Zummo 
79471d47e3SMichael Hamel #define X1205_INT_AL0E		0x20	/* Alarm 0 enable */
80471d47e3SMichael Hamel 
814edac2b4SAlessandro Zummo static struct i2c_driver x1205_driver;
821fec7c66SAlessandro Zummo 
831fec7c66SAlessandro Zummo /*
841fec7c66SAlessandro Zummo  * In the routines that deal directly with the x1205 hardware, we use
851fec7c66SAlessandro Zummo  * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
861fec7c66SAlessandro Zummo  * Epoch is initialized as 2000. Time is set to UTC.
871fec7c66SAlessandro Zummo  */
x1205_get_datetime(struct i2c_client * client,struct rtc_time * tm,unsigned char reg_base)881fec7c66SAlessandro Zummo static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
891fec7c66SAlessandro Zummo 				unsigned char reg_base)
901fec7c66SAlessandro Zummo {
911fec7c66SAlessandro Zummo 	unsigned char dt_addr[2] = { 0, reg_base };
921fec7c66SAlessandro Zummo 	unsigned char buf[8];
93471d47e3SMichael Hamel 	int i;
941fec7c66SAlessandro Zummo 
951fec7c66SAlessandro Zummo 	struct i2c_msg msgs[] = {
96c3fe92b7SShubhrajyoti D 		{/* setup read ptr */
97c3fe92b7SShubhrajyoti D 			.addr = client->addr,
98c3fe92b7SShubhrajyoti D 			.len = 2,
99c3fe92b7SShubhrajyoti D 			.buf = dt_addr
100c3fe92b7SShubhrajyoti D 		},
101c3fe92b7SShubhrajyoti D 		{/* read date */
102c3fe92b7SShubhrajyoti D 			.addr = client->addr,
103c3fe92b7SShubhrajyoti D 			.flags = I2C_M_RD,
104c3fe92b7SShubhrajyoti D 			.len = 8,
105c3fe92b7SShubhrajyoti D 			.buf = buf
106c3fe92b7SShubhrajyoti D 		},
1071fec7c66SAlessandro Zummo 	};
1081fec7c66SAlessandro Zummo 
1091fec7c66SAlessandro Zummo 	/* read date registers */
110471d47e3SMichael Hamel 	if (i2c_transfer(client->adapter, &msgs[0], 2) != 2) {
1112a4e2b87SHarvey Harrison 		dev_err(&client->dev, "%s: read error\n", __func__);
1121fec7c66SAlessandro Zummo 		return -EIO;
1131fec7c66SAlessandro Zummo 	}
1141fec7c66SAlessandro Zummo 
1151fec7c66SAlessandro Zummo 	dev_dbg(&client->dev,
1161fec7c66SAlessandro Zummo 		"%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
1171fec7c66SAlessandro Zummo 		"mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
1182a4e2b87SHarvey Harrison 		__func__,
1191fec7c66SAlessandro Zummo 		buf[0], buf[1], buf[2], buf[3],
1201fec7c66SAlessandro Zummo 		buf[4], buf[5], buf[6], buf[7]);
1211fec7c66SAlessandro Zummo 
122471d47e3SMichael Hamel 	/* Mask out the enable bits if these are alarm registers */
123471d47e3SMichael Hamel 	if (reg_base < X1205_CCR_BASE)
124471d47e3SMichael Hamel 		for (i = 0; i <= 4; i++)
125471d47e3SMichael Hamel 			buf[i] &= 0x7F;
126471d47e3SMichael Hamel 
127fe20ba70SAdrian Bunk 	tm->tm_sec = bcd2bin(buf[CCR_SEC]);
128fe20ba70SAdrian Bunk 	tm->tm_min = bcd2bin(buf[CCR_MIN]);
129fe20ba70SAdrian Bunk 	tm->tm_hour = bcd2bin(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
130fe20ba70SAdrian Bunk 	tm->tm_mday = bcd2bin(buf[CCR_MDAY]);
131fe20ba70SAdrian Bunk 	tm->tm_mon = bcd2bin(buf[CCR_MONTH]) - 1; /* mon is 0-11 */
132fe20ba70SAdrian Bunk 	tm->tm_year = bcd2bin(buf[CCR_YEAR])
133fe20ba70SAdrian Bunk 			+ (bcd2bin(buf[CCR_Y2K]) * 100) - 1900;
1341fec7c66SAlessandro Zummo 	tm->tm_wday = buf[CCR_WDAY];
1351fec7c66SAlessandro Zummo 
1361fec7c66SAlessandro Zummo 	dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
1371fec7c66SAlessandro Zummo 		"mday=%d, mon=%d, year=%d, wday=%d\n",
1382a4e2b87SHarvey Harrison 		__func__,
1391fec7c66SAlessandro Zummo 		tm->tm_sec, tm->tm_min, tm->tm_hour,
1401fec7c66SAlessandro Zummo 		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
1411fec7c66SAlessandro Zummo 
1421fec7c66SAlessandro Zummo 	return 0;
1431fec7c66SAlessandro Zummo }
1441fec7c66SAlessandro Zummo 
x1205_get_status(struct i2c_client * client,unsigned char * sr)1451fec7c66SAlessandro Zummo static int x1205_get_status(struct i2c_client *client, unsigned char *sr)
1461fec7c66SAlessandro Zummo {
1471fec7c66SAlessandro Zummo 	static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
1481fec7c66SAlessandro Zummo 
1491fec7c66SAlessandro Zummo 	struct i2c_msg msgs[] = {
150c3fe92b7SShubhrajyoti D 		{     /* setup read ptr */
151c3fe92b7SShubhrajyoti D 			.addr = client->addr,
152c3fe92b7SShubhrajyoti D 			.len = 2,
153c3fe92b7SShubhrajyoti D 			.buf = sr_addr
154c3fe92b7SShubhrajyoti D 		},
155c3fe92b7SShubhrajyoti D 		{    /* read status */
156c3fe92b7SShubhrajyoti D 			.addr = client->addr,
157c3fe92b7SShubhrajyoti D 			.flags = I2C_M_RD,
158c3fe92b7SShubhrajyoti D 			.len = 1,
159c3fe92b7SShubhrajyoti D 			.buf = sr
160c3fe92b7SShubhrajyoti D 		},
1611fec7c66SAlessandro Zummo 	};
1621fec7c66SAlessandro Zummo 
1631fec7c66SAlessandro Zummo 	/* read status register */
164471d47e3SMichael Hamel 	if (i2c_transfer(client->adapter, &msgs[0], 2) != 2) {
1652a4e2b87SHarvey Harrison 		dev_err(&client->dev, "%s: read error\n", __func__);
1661fec7c66SAlessandro Zummo 		return -EIO;
1671fec7c66SAlessandro Zummo 	}
1681fec7c66SAlessandro Zummo 
1691fec7c66SAlessandro Zummo 	return 0;
1701fec7c66SAlessandro Zummo }
1711fec7c66SAlessandro Zummo 
x1205_set_datetime(struct i2c_client * client,struct rtc_time * tm,u8 reg_base,unsigned char alm_enable)1721fec7c66SAlessandro Zummo static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
173d973b632SJohannes Weiner 			u8 reg_base, unsigned char alm_enable)
1741fec7c66SAlessandro Zummo {
175d973b632SJohannes Weiner 	int i, xfer;
176471d47e3SMichael Hamel 	unsigned char rdata[10] = { 0, reg_base };
177d973b632SJohannes Weiner 	unsigned char *buf = rdata + 2;
1781fec7c66SAlessandro Zummo 
1791fec7c66SAlessandro Zummo 	static const unsigned char wel[3] = { 0, X1205_REG_SR,
1801fec7c66SAlessandro Zummo 						X1205_SR_WEL };
1811fec7c66SAlessandro Zummo 
1821fec7c66SAlessandro Zummo 	static const unsigned char rwel[3] = { 0, X1205_REG_SR,
1831fec7c66SAlessandro Zummo 						X1205_SR_WEL | X1205_SR_RWEL };
1841fec7c66SAlessandro Zummo 
1851fec7c66SAlessandro Zummo 	static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };
1861fec7c66SAlessandro Zummo 
1871fec7c66SAlessandro Zummo 	dev_dbg(&client->dev,
188d973b632SJohannes Weiner 		"%s: sec=%d min=%d hour=%d mday=%d mon=%d year=%d wday=%d\n",
189d973b632SJohannes Weiner 		__func__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday,
190d973b632SJohannes Weiner 		tm->tm_mon, tm->tm_year, tm->tm_wday);
1911fec7c66SAlessandro Zummo 
192fe20ba70SAdrian Bunk 	buf[CCR_SEC] = bin2bcd(tm->tm_sec);
193fe20ba70SAdrian Bunk 	buf[CCR_MIN] = bin2bcd(tm->tm_min);
1941fec7c66SAlessandro Zummo 
1951fec7c66SAlessandro Zummo 	/* set hour and 24hr bit */
196fe20ba70SAdrian Bunk 	buf[CCR_HOUR] = bin2bcd(tm->tm_hour) | X1205_HR_MIL;
1971fec7c66SAlessandro Zummo 
198fe20ba70SAdrian Bunk 	buf[CCR_MDAY] = bin2bcd(tm->tm_mday);
1991fec7c66SAlessandro Zummo 
2001fec7c66SAlessandro Zummo 	/* month, 1 - 12 */
201fe20ba70SAdrian Bunk 	buf[CCR_MONTH] = bin2bcd(tm->tm_mon + 1);
2021fec7c66SAlessandro Zummo 
2031fec7c66SAlessandro Zummo 	/* year, since the rtc epoch*/
204fe20ba70SAdrian Bunk 	buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
2051fec7c66SAlessandro Zummo 	buf[CCR_WDAY] = tm->tm_wday & 0x07;
20648a7f774SJohannes Weiner 	buf[CCR_Y2K] = bin2bcd((tm->tm_year + 1900) / 100);
2071fec7c66SAlessandro Zummo 
208471d47e3SMichael Hamel 	/* If writing alarm registers, set compare bits on registers 0-4 */
209471d47e3SMichael Hamel 	if (reg_base < X1205_CCR_BASE)
210471d47e3SMichael Hamel 		for (i = 0; i <= 4; i++)
211471d47e3SMichael Hamel 			buf[i] |= 0x80;
212471d47e3SMichael Hamel 
2131fec7c66SAlessandro Zummo 	/* this sequence is required to unlock the chip */
21466e3f10cSSachin Kamat 	xfer = i2c_master_send(client, wel, 3);
21566e3f10cSSachin Kamat 	if (xfer != 3) {
2162a4e2b87SHarvey Harrison 		dev_err(&client->dev, "%s: wel - %d\n", __func__, xfer);
2171fec7c66SAlessandro Zummo 		return -EIO;
2181fec7c66SAlessandro Zummo 	}
2191fec7c66SAlessandro Zummo 
22066e3f10cSSachin Kamat 	xfer = i2c_master_send(client, rwel, 3);
22166e3f10cSSachin Kamat 	if (xfer != 3) {
2222a4e2b87SHarvey Harrison 		dev_err(&client->dev, "%s: rwel - %d\n", __func__, xfer);
2231fec7c66SAlessandro Zummo 		return -EIO;
2241fec7c66SAlessandro Zummo 	}
2251fec7c66SAlessandro Zummo 
226d973b632SJohannes Weiner 	xfer = i2c_master_send(client, rdata, sizeof(rdata));
227d973b632SJohannes Weiner 	if (xfer != sizeof(rdata)) {
2281fec7c66SAlessandro Zummo 		dev_err(&client->dev,
229471d47e3SMichael Hamel 			"%s: result=%d addr=%02x, data=%02x\n",
2302a4e2b87SHarvey Harrison 			__func__,
2311fec7c66SAlessandro Zummo 			 xfer, rdata[1], rdata[2]);
2321fec7c66SAlessandro Zummo 		return -EIO;
2331fec7c66SAlessandro Zummo 	}
234471d47e3SMichael Hamel 
235471d47e3SMichael Hamel 	/* If we wrote to the nonvolatile region, wait 10msec for write cycle*/
236471d47e3SMichael Hamel 	if (reg_base < X1205_CCR_BASE) {
237471d47e3SMichael Hamel 		unsigned char al0e[3] = { 0, X1205_REG_INT, 0 };
238471d47e3SMichael Hamel 
239471d47e3SMichael Hamel 		msleep(10);
240471d47e3SMichael Hamel 
241471d47e3SMichael Hamel 		/* ...and set or clear the AL0E bit in the INT register */
242471d47e3SMichael Hamel 
243471d47e3SMichael Hamel 		/* Need to set RWEL again as the write has cleared it */
244471d47e3SMichael Hamel 		xfer = i2c_master_send(client, rwel, 3);
245471d47e3SMichael Hamel 		if (xfer != 3) {
246471d47e3SMichael Hamel 			dev_err(&client->dev,
247471d47e3SMichael Hamel 				"%s: aloe rwel - %d\n",
248471d47e3SMichael Hamel 				__func__,
249471d47e3SMichael Hamel 				xfer);
250471d47e3SMichael Hamel 			return -EIO;
251471d47e3SMichael Hamel 		}
252471d47e3SMichael Hamel 
253471d47e3SMichael Hamel 		if (alm_enable)
254471d47e3SMichael Hamel 			al0e[2] = X1205_INT_AL0E;
255471d47e3SMichael Hamel 
256471d47e3SMichael Hamel 		xfer = i2c_master_send(client, al0e, 3);
257471d47e3SMichael Hamel 		if (xfer != 3) {
258471d47e3SMichael Hamel 			dev_err(&client->dev,
259471d47e3SMichael Hamel 				"%s: al0e - %d\n",
260471d47e3SMichael Hamel 				__func__,
261471d47e3SMichael Hamel 				xfer);
262471d47e3SMichael Hamel 			return -EIO;
263471d47e3SMichael Hamel 		}
264471d47e3SMichael Hamel 
265471d47e3SMichael Hamel 		/* and wait 10msec again for this write to complete */
266471d47e3SMichael Hamel 		msleep(10);
267471d47e3SMichael Hamel 	}
2681fec7c66SAlessandro Zummo 
2691fec7c66SAlessandro Zummo 	/* disable further writes */
27066e3f10cSSachin Kamat 	xfer = i2c_master_send(client, diswe, 3);
27166e3f10cSSachin Kamat 	if (xfer != 3) {
2722a4e2b87SHarvey Harrison 		dev_err(&client->dev, "%s: diswe - %d\n", __func__, xfer);
2731fec7c66SAlessandro Zummo 		return -EIO;
2741fec7c66SAlessandro Zummo 	}
2751fec7c66SAlessandro Zummo 
2761fec7c66SAlessandro Zummo 	return 0;
2771fec7c66SAlessandro Zummo }
2781fec7c66SAlessandro Zummo 
x1205_fix_osc(struct i2c_client * client)2791fec7c66SAlessandro Zummo static int x1205_fix_osc(struct i2c_client *client)
2801fec7c66SAlessandro Zummo {
2811fec7c66SAlessandro Zummo 	int err;
2821fec7c66SAlessandro Zummo 	struct rtc_time tm;
2831fec7c66SAlessandro Zummo 
284cb8799eeSJohannes Weiner 	memset(&tm, 0, sizeof(tm));
2851fec7c66SAlessandro Zummo 
286d973b632SJohannes Weiner 	err = x1205_set_datetime(client, &tm, X1205_CCR_BASE, 0);
287471d47e3SMichael Hamel 	if (err < 0)
288471d47e3SMichael Hamel 		dev_err(&client->dev, "unable to restart the oscillator\n");
2891fec7c66SAlessandro Zummo 
2901fec7c66SAlessandro Zummo 	return err;
2911fec7c66SAlessandro Zummo }
2921fec7c66SAlessandro Zummo 
x1205_get_dtrim(struct i2c_client * client,int * trim)2931fec7c66SAlessandro Zummo static int x1205_get_dtrim(struct i2c_client *client, int *trim)
2941fec7c66SAlessandro Zummo {
2951fec7c66SAlessandro Zummo 	unsigned char dtr;
2961fec7c66SAlessandro Zummo 	static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR };
2971fec7c66SAlessandro Zummo 
2981fec7c66SAlessandro Zummo 	struct i2c_msg msgs[] = {
299c3fe92b7SShubhrajyoti D 		{	/* setup read ptr */
300c3fe92b7SShubhrajyoti D 			.addr = client->addr,
301c3fe92b7SShubhrajyoti D 			.len = 2,
302c3fe92b7SShubhrajyoti D 			.buf = dtr_addr
303c3fe92b7SShubhrajyoti D 		},
304c3fe92b7SShubhrajyoti D 		{      /* read dtr */
305c3fe92b7SShubhrajyoti D 			.addr = client->addr,
306c3fe92b7SShubhrajyoti D 			.flags = I2C_M_RD,
307c3fe92b7SShubhrajyoti D 			.len = 1,
308c3fe92b7SShubhrajyoti D 			.buf = &dtr
309c3fe92b7SShubhrajyoti D 		},
3101fec7c66SAlessandro Zummo 	};
3111fec7c66SAlessandro Zummo 
3121fec7c66SAlessandro Zummo 	/* read dtr register */
313471d47e3SMichael Hamel 	if (i2c_transfer(client->adapter, &msgs[0], 2) != 2) {
3142a4e2b87SHarvey Harrison 		dev_err(&client->dev, "%s: read error\n", __func__);
3151fec7c66SAlessandro Zummo 		return -EIO;
3161fec7c66SAlessandro Zummo 	}
3171fec7c66SAlessandro Zummo 
3182a4e2b87SHarvey Harrison 	dev_dbg(&client->dev, "%s: raw dtr=%x\n", __func__, dtr);
3191fec7c66SAlessandro Zummo 
3201fec7c66SAlessandro Zummo 	*trim = 0;
3211fec7c66SAlessandro Zummo 
3221fec7c66SAlessandro Zummo 	if (dtr & X1205_DTR_DTR0)
3231fec7c66SAlessandro Zummo 		*trim += 20;
3241fec7c66SAlessandro Zummo 
3251fec7c66SAlessandro Zummo 	if (dtr & X1205_DTR_DTR1)
3261fec7c66SAlessandro Zummo 		*trim += 10;
3271fec7c66SAlessandro Zummo 
3281fec7c66SAlessandro Zummo 	if (dtr & X1205_DTR_DTR2)
3291fec7c66SAlessandro Zummo 		*trim = -*trim;
3301fec7c66SAlessandro Zummo 
3311fec7c66SAlessandro Zummo 	return 0;
3321fec7c66SAlessandro Zummo }
3331fec7c66SAlessandro Zummo 
x1205_get_atrim(struct i2c_client * client,int * trim)3341fec7c66SAlessandro Zummo static int x1205_get_atrim(struct i2c_client *client, int *trim)
3351fec7c66SAlessandro Zummo {
3361fec7c66SAlessandro Zummo 	s8 atr;
3371fec7c66SAlessandro Zummo 	static unsigned char atr_addr[2] = { 0, X1205_REG_ATR };
3381fec7c66SAlessandro Zummo 
3391fec7c66SAlessandro Zummo 	struct i2c_msg msgs[] = {
340c3fe92b7SShubhrajyoti D 		{/* setup read ptr */
341c3fe92b7SShubhrajyoti D 			.addr = client->addr,
342c3fe92b7SShubhrajyoti D 			.len = 2,
343c3fe92b7SShubhrajyoti D 			.buf = atr_addr
344c3fe92b7SShubhrajyoti D 		},
345c3fe92b7SShubhrajyoti D 		{/* read atr */
346c3fe92b7SShubhrajyoti D 			.addr = client->addr,
347c3fe92b7SShubhrajyoti D 			.flags = I2C_M_RD,
348c3fe92b7SShubhrajyoti D 			.len = 1,
349c3fe92b7SShubhrajyoti D 			.buf = &atr
350c3fe92b7SShubhrajyoti D 		},
3511fec7c66SAlessandro Zummo 	};
3521fec7c66SAlessandro Zummo 
3531fec7c66SAlessandro Zummo 	/* read atr register */
354471d47e3SMichael Hamel 	if (i2c_transfer(client->adapter, &msgs[0], 2) != 2) {
3552a4e2b87SHarvey Harrison 		dev_err(&client->dev, "%s: read error\n", __func__);
3561fec7c66SAlessandro Zummo 		return -EIO;
3571fec7c66SAlessandro Zummo 	}
3581fec7c66SAlessandro Zummo 
3592a4e2b87SHarvey Harrison 	dev_dbg(&client->dev, "%s: raw atr=%x\n", __func__, atr);
3601fec7c66SAlessandro Zummo 
3611fec7c66SAlessandro Zummo 	/* atr is a two's complement value on 6 bits,
3621fec7c66SAlessandro Zummo 	 * perform sign extension. The formula is
3631fec7c66SAlessandro Zummo 	 * Catr = (atr * 0.25pF) + 11.00pF.
3641fec7c66SAlessandro Zummo 	 */
36586e66604SMartin Kepplinger 	atr = sign_extend32(atr, 5);
3661fec7c66SAlessandro Zummo 
3672a4e2b87SHarvey Harrison 	dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __func__, atr, atr);
3681fec7c66SAlessandro Zummo 
3691fec7c66SAlessandro Zummo 	*trim = (atr * 250) + 11000;
3701fec7c66SAlessandro Zummo 
3712a4e2b87SHarvey Harrison 	dev_dbg(&client->dev, "%s: real=%d\n", __func__, *trim);
3721fec7c66SAlessandro Zummo 
3731fec7c66SAlessandro Zummo 	return 0;
3741fec7c66SAlessandro Zummo }
3751fec7c66SAlessandro Zummo 
37666e3f10cSSachin Kamat struct x1205_limit {
3771fec7c66SAlessandro Zummo 	unsigned char reg, mask, min, max;
3781fec7c66SAlessandro Zummo };
3791fec7c66SAlessandro Zummo 
x1205_validate_client(struct i2c_client * client)3801fec7c66SAlessandro Zummo static int x1205_validate_client(struct i2c_client *client)
3811fec7c66SAlessandro Zummo {
3821fec7c66SAlessandro Zummo 	int i, xfer;
3831fec7c66SAlessandro Zummo 
3841fec7c66SAlessandro Zummo 	/* Probe array. We will read the register at the specified
3851fec7c66SAlessandro Zummo 	 * address and check if the given bits are zero.
3861fec7c66SAlessandro Zummo 	 */
3871fec7c66SAlessandro Zummo 	static const unsigned char probe_zero_pattern[] = {
3881fec7c66SAlessandro Zummo 		/* register, mask */
3891fec7c66SAlessandro Zummo 		X1205_REG_SR,	0x18,
3901fec7c66SAlessandro Zummo 		X1205_REG_DTR,	0xF8,
3911fec7c66SAlessandro Zummo 		X1205_REG_ATR,	0xC0,
3921fec7c66SAlessandro Zummo 		X1205_REG_INT,	0x18,
3931fec7c66SAlessandro Zummo 		X1205_REG_0,	0xFF,
3941fec7c66SAlessandro Zummo 	};
3951fec7c66SAlessandro Zummo 
3961fec7c66SAlessandro Zummo 	static const struct x1205_limit probe_limits_pattern[] = {
3971fec7c66SAlessandro Zummo 		/* register, mask, min, max */
3981fec7c66SAlessandro Zummo 		{ X1205_REG_Y2K,	0xFF,	19,	20	},
3991fec7c66SAlessandro Zummo 		{ X1205_REG_DW,		0xFF,	0,	6	},
4001fec7c66SAlessandro Zummo 		{ X1205_REG_YR,		0xFF,	0,	99	},
4011fec7c66SAlessandro Zummo 		{ X1205_REG_MO,		0xFF,	0,	12	},
4021fec7c66SAlessandro Zummo 		{ X1205_REG_DT,		0xFF,	0,	31	},
4031fec7c66SAlessandro Zummo 		{ X1205_REG_HR,		0x7F,	0,	23	},
4041fec7c66SAlessandro Zummo 		{ X1205_REG_MN,		0xFF,	0,	59	},
4051fec7c66SAlessandro Zummo 		{ X1205_REG_SC,		0xFF,	0,	59	},
4061fec7c66SAlessandro Zummo 		{ X1205_REG_Y2K1,	0xFF,	19,	20	},
4071fec7c66SAlessandro Zummo 		{ X1205_REG_Y2K0,	0xFF,	19,	20	},
4081fec7c66SAlessandro Zummo 	};
4091fec7c66SAlessandro Zummo 
4101fec7c66SAlessandro Zummo 	/* check that registers have bits a 0 where expected */
4111fec7c66SAlessandro Zummo 	for (i = 0; i < ARRAY_SIZE(probe_zero_pattern); i += 2) {
4121fec7c66SAlessandro Zummo 		unsigned char buf;
4131fec7c66SAlessandro Zummo 
4141fec7c66SAlessandro Zummo 		unsigned char addr[2] = { 0, probe_zero_pattern[i] };
4151fec7c66SAlessandro Zummo 
4161fec7c66SAlessandro Zummo 		struct i2c_msg msgs[2] = {
417c3fe92b7SShubhrajyoti D 			{
418c3fe92b7SShubhrajyoti D 				.addr = client->addr,
419c3fe92b7SShubhrajyoti D 				.len = 2,
420c3fe92b7SShubhrajyoti D 				.buf = addr
421c3fe92b7SShubhrajyoti D 			},
422c3fe92b7SShubhrajyoti D 			{
423c3fe92b7SShubhrajyoti D 				.addr = client->addr,
424c3fe92b7SShubhrajyoti D 				.flags = I2C_M_RD,
425c3fe92b7SShubhrajyoti D 				.len = 1,
426c3fe92b7SShubhrajyoti D 				.buf = &buf
427c3fe92b7SShubhrajyoti D 			},
4281fec7c66SAlessandro Zummo 		};
4291fec7c66SAlessandro Zummo 
43066e3f10cSSachin Kamat 		xfer = i2c_transfer(client->adapter, msgs, 2);
43166e3f10cSSachin Kamat 		if (xfer != 2) {
432a14e1893SDavid Brownell 			dev_err(&client->dev,
4331fec7c66SAlessandro Zummo 				"%s: could not read register %x\n",
4342a4e2b87SHarvey Harrison 				__func__, probe_zero_pattern[i]);
4351fec7c66SAlessandro Zummo 
4361fec7c66SAlessandro Zummo 			return -EIO;
4371fec7c66SAlessandro Zummo 		}
4381fec7c66SAlessandro Zummo 
4391fec7c66SAlessandro Zummo 		if ((buf & probe_zero_pattern[i+1]) != 0) {
440a14e1893SDavid Brownell 			dev_err(&client->dev,
4411fec7c66SAlessandro Zummo 				"%s: register=%02x, zero pattern=%d, value=%x\n",
4422a4e2b87SHarvey Harrison 				__func__, probe_zero_pattern[i], i, buf);
4431fec7c66SAlessandro Zummo 
4441fec7c66SAlessandro Zummo 			return -ENODEV;
4451fec7c66SAlessandro Zummo 		}
4461fec7c66SAlessandro Zummo 	}
4471fec7c66SAlessandro Zummo 
4481fec7c66SAlessandro Zummo 	/* check limits (only registers with bcd values) */
4491fec7c66SAlessandro Zummo 	for (i = 0; i < ARRAY_SIZE(probe_limits_pattern); i++) {
4501fec7c66SAlessandro Zummo 		unsigned char reg, value;
4511fec7c66SAlessandro Zummo 
4521fec7c66SAlessandro Zummo 		unsigned char addr[2] = { 0, probe_limits_pattern[i].reg };
4531fec7c66SAlessandro Zummo 
4541fec7c66SAlessandro Zummo 		struct i2c_msg msgs[2] = {
455c3fe92b7SShubhrajyoti D 			{
456c3fe92b7SShubhrajyoti D 				.addr = client->addr,
457c3fe92b7SShubhrajyoti D 				.len = 2,
458c3fe92b7SShubhrajyoti D 				.buf = addr
459c3fe92b7SShubhrajyoti D 			},
460c3fe92b7SShubhrajyoti D 			{
461c3fe92b7SShubhrajyoti D 				.addr = client->addr,
462c3fe92b7SShubhrajyoti D 				.flags = I2C_M_RD,
463c3fe92b7SShubhrajyoti D 				.len = 1,
464c3fe92b7SShubhrajyoti D 				.buf = &reg
465c3fe92b7SShubhrajyoti D 			},
4661fec7c66SAlessandro Zummo 		};
4671fec7c66SAlessandro Zummo 
46866e3f10cSSachin Kamat 		xfer = i2c_transfer(client->adapter, msgs, 2);
46966e3f10cSSachin Kamat 		if (xfer != 2) {
470a14e1893SDavid Brownell 			dev_err(&client->dev,
4711fec7c66SAlessandro Zummo 				"%s: could not read register %x\n",
4722a4e2b87SHarvey Harrison 				__func__, probe_limits_pattern[i].reg);
4731fec7c66SAlessandro Zummo 
4741fec7c66SAlessandro Zummo 			return -EIO;
4751fec7c66SAlessandro Zummo 		}
4761fec7c66SAlessandro Zummo 
477fe20ba70SAdrian Bunk 		value = bcd2bin(reg & probe_limits_pattern[i].mask);
4781fec7c66SAlessandro Zummo 
4791fec7c66SAlessandro Zummo 		if (value > probe_limits_pattern[i].max ||
4801fec7c66SAlessandro Zummo 			value < probe_limits_pattern[i].min) {
481a14e1893SDavid Brownell 			dev_dbg(&client->dev,
4821fec7c66SAlessandro Zummo 				"%s: register=%x, lim pattern=%d, value=%d\n",
4832a4e2b87SHarvey Harrison 				__func__, probe_limits_pattern[i].reg,
4841fec7c66SAlessandro Zummo 				i, value);
4851fec7c66SAlessandro Zummo 
4861fec7c66SAlessandro Zummo 			return -ENODEV;
4871fec7c66SAlessandro Zummo 		}
4881fec7c66SAlessandro Zummo 	}
4891fec7c66SAlessandro Zummo 
4901fec7c66SAlessandro Zummo 	return 0;
4911fec7c66SAlessandro Zummo }
4921fec7c66SAlessandro Zummo 
x1205_rtc_read_alarm(struct device * dev,struct rtc_wkalrm * alrm)4931fec7c66SAlessandro Zummo static int x1205_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
4941fec7c66SAlessandro Zummo {
495471d47e3SMichael Hamel 	int err;
496471d47e3SMichael Hamel 	unsigned char intreg, status;
497471d47e3SMichael Hamel 	static unsigned char int_addr[2] = { 0, X1205_REG_INT };
498471d47e3SMichael Hamel 	struct i2c_client *client = to_i2c_client(dev);
499471d47e3SMichael Hamel 	struct i2c_msg msgs[] = {
500c3fe92b7SShubhrajyoti D 		{ /* setup read ptr */
501c3fe92b7SShubhrajyoti D 			.addr = client->addr,
502c3fe92b7SShubhrajyoti D 			.len = 2,
503c3fe92b7SShubhrajyoti D 			.buf = int_addr
504c3fe92b7SShubhrajyoti D 		},
505c3fe92b7SShubhrajyoti D 		{/* read INT register */
506c3fe92b7SShubhrajyoti D 
507c3fe92b7SShubhrajyoti D 			.addr = client->addr,
508c3fe92b7SShubhrajyoti D 			.flags = I2C_M_RD,
509c3fe92b7SShubhrajyoti D 			.len = 1,
510c3fe92b7SShubhrajyoti D 			.buf = &intreg
511c3fe92b7SShubhrajyoti D 		},
512471d47e3SMichael Hamel 	};
513471d47e3SMichael Hamel 
514471d47e3SMichael Hamel 	/* read interrupt register and status register */
515471d47e3SMichael Hamel 	if (i2c_transfer(client->adapter, &msgs[0], 2) != 2) {
516471d47e3SMichael Hamel 		dev_err(&client->dev, "%s: read error\n", __func__);
517471d47e3SMichael Hamel 		return -EIO;
518471d47e3SMichael Hamel 	}
519471d47e3SMichael Hamel 	err = x1205_get_status(client, &status);
520471d47e3SMichael Hamel 	if (err == 0) {
521471d47e3SMichael Hamel 		alrm->pending = (status & X1205_SR_AL0) ? 1 : 0;
522471d47e3SMichael Hamel 		alrm->enabled = (intreg & X1205_INT_AL0E) ? 1 : 0;
523471d47e3SMichael Hamel 		err = x1205_get_datetime(client, &alrm->time, X1205_ALM0_BASE);
524471d47e3SMichael Hamel 	}
525471d47e3SMichael Hamel 	return err;
5261fec7c66SAlessandro Zummo }
5271fec7c66SAlessandro Zummo 
x1205_rtc_set_alarm(struct device * dev,struct rtc_wkalrm * alrm)5281fec7c66SAlessandro Zummo static int x1205_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
5291fec7c66SAlessandro Zummo {
5301fec7c66SAlessandro Zummo 	return x1205_set_datetime(to_i2c_client(dev),
531d973b632SJohannes Weiner 		&alrm->time, X1205_ALM0_BASE, alrm->enabled);
5321fec7c66SAlessandro Zummo }
5331fec7c66SAlessandro Zummo 
x1205_rtc_read_time(struct device * dev,struct rtc_time * tm)5341fec7c66SAlessandro Zummo static int x1205_rtc_read_time(struct device *dev, struct rtc_time *tm)
5351fec7c66SAlessandro Zummo {
5361fec7c66SAlessandro Zummo 	return x1205_get_datetime(to_i2c_client(dev),
5371fec7c66SAlessandro Zummo 		tm, X1205_CCR_BASE);
5381fec7c66SAlessandro Zummo }
5391fec7c66SAlessandro Zummo 
x1205_rtc_set_time(struct device * dev,struct rtc_time * tm)5401fec7c66SAlessandro Zummo static int x1205_rtc_set_time(struct device *dev, struct rtc_time *tm)
5411fec7c66SAlessandro Zummo {
5421fec7c66SAlessandro Zummo 	return x1205_set_datetime(to_i2c_client(dev),
543d973b632SJohannes Weiner 		tm, X1205_CCR_BASE, 0);
5441fec7c66SAlessandro Zummo }
5451fec7c66SAlessandro Zummo 
x1205_rtc_proc(struct device * dev,struct seq_file * seq)5461fec7c66SAlessandro Zummo static int x1205_rtc_proc(struct device *dev, struct seq_file *seq)
5471fec7c66SAlessandro Zummo {
5481fec7c66SAlessandro Zummo 	int err, dtrim, atrim;
5491fec7c66SAlessandro Zummo 
55066e3f10cSSachin Kamat 	err = x1205_get_dtrim(to_i2c_client(dev), &dtrim);
55166e3f10cSSachin Kamat 	if (!err)
5521fec7c66SAlessandro Zummo 		seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim);
5531fec7c66SAlessandro Zummo 
55466e3f10cSSachin Kamat 	err = x1205_get_atrim(to_i2c_client(dev), &atrim);
55566e3f10cSSachin Kamat 	if (!err)
5561fec7c66SAlessandro Zummo 		seq_printf(seq, "analog_trim\t: %d.%02d pF\n",
5571fec7c66SAlessandro Zummo 			atrim / 1000, atrim % 1000);
5581fec7c66SAlessandro Zummo 	return 0;
5591fec7c66SAlessandro Zummo }
5601fec7c66SAlessandro Zummo 
561ff8371acSDavid Brownell static const struct rtc_class_ops x1205_rtc_ops = {
5621fec7c66SAlessandro Zummo 	.proc		= x1205_rtc_proc,
5631fec7c66SAlessandro Zummo 	.read_time	= x1205_rtc_read_time,
5641fec7c66SAlessandro Zummo 	.set_time	= x1205_rtc_set_time,
5651fec7c66SAlessandro Zummo 	.read_alarm	= x1205_rtc_read_alarm,
5661fec7c66SAlessandro Zummo 	.set_alarm	= x1205_rtc_set_alarm,
5671fec7c66SAlessandro Zummo };
5681fec7c66SAlessandro Zummo 
x1205_sysfs_show_atrim(struct device * dev,struct device_attribute * attr,char * buf)5691fec7c66SAlessandro Zummo static ssize_t x1205_sysfs_show_atrim(struct device *dev,
5701fec7c66SAlessandro Zummo 				struct device_attribute *attr, char *buf)
5711fec7c66SAlessandro Zummo {
572015aefbbSAlessandro Zummo 	int err, atrim;
5731fec7c66SAlessandro Zummo 
574015aefbbSAlessandro Zummo 	err = x1205_get_atrim(to_i2c_client(dev), &atrim);
575015aefbbSAlessandro Zummo 	if (err)
576015aefbbSAlessandro Zummo 		return err;
577015aefbbSAlessandro Zummo 
578015aefbbSAlessandro Zummo 	return sprintf(buf, "%d.%02d pF\n", atrim / 1000, atrim % 1000);
5791fec7c66SAlessandro Zummo }
5801fec7c66SAlessandro Zummo static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL);
5811fec7c66SAlessandro Zummo 
x1205_sysfs_show_dtrim(struct device * dev,struct device_attribute * attr,char * buf)5821fec7c66SAlessandro Zummo static ssize_t x1205_sysfs_show_dtrim(struct device *dev,
5831fec7c66SAlessandro Zummo 				struct device_attribute *attr, char *buf)
5841fec7c66SAlessandro Zummo {
585015aefbbSAlessandro Zummo 	int err, dtrim;
5861fec7c66SAlessandro Zummo 
587015aefbbSAlessandro Zummo 	err = x1205_get_dtrim(to_i2c_client(dev), &dtrim);
588015aefbbSAlessandro Zummo 	if (err)
589015aefbbSAlessandro Zummo 		return err;
590015aefbbSAlessandro Zummo 
5911fec7c66SAlessandro Zummo 	return sprintf(buf, "%d ppm\n", dtrim);
5921fec7c66SAlessandro Zummo }
5931fec7c66SAlessandro Zummo static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL);
5941fec7c66SAlessandro Zummo 
x1205_sysfs_register(struct device * dev)5954edac2b4SAlessandro Zummo static int x1205_sysfs_register(struct device *dev)
5961fec7c66SAlessandro Zummo {
5974edac2b4SAlessandro Zummo 	int err;
5984edac2b4SAlessandro Zummo 
5994edac2b4SAlessandro Zummo 	err = device_create_file(dev, &dev_attr_atrim);
6004edac2b4SAlessandro Zummo 	if (err)
6014edac2b4SAlessandro Zummo 		return err;
6024edac2b4SAlessandro Zummo 
6034edac2b4SAlessandro Zummo 	err = device_create_file(dev, &dev_attr_dtrim);
6044edac2b4SAlessandro Zummo 	if (err)
6054edac2b4SAlessandro Zummo 		device_remove_file(dev, &dev_attr_atrim);
6064edac2b4SAlessandro Zummo 
6074edac2b4SAlessandro Zummo 	return err;
6081fec7c66SAlessandro Zummo }
6091fec7c66SAlessandro Zummo 
x1205_sysfs_unregister(struct device * dev)6104edac2b4SAlessandro Zummo static void x1205_sysfs_unregister(struct device *dev)
6114edac2b4SAlessandro Zummo {
6124edac2b4SAlessandro Zummo 	device_remove_file(dev, &dev_attr_atrim);
6134edac2b4SAlessandro Zummo 	device_remove_file(dev, &dev_attr_dtrim);
6144edac2b4SAlessandro Zummo }
6154edac2b4SAlessandro Zummo 
6164edac2b4SAlessandro Zummo 
x1205_probe(struct i2c_client * client)6173f4a3322SStephen Kitt static int x1205_probe(struct i2c_client *client)
6181fec7c66SAlessandro Zummo {
6191fec7c66SAlessandro Zummo 	int err = 0;
6201fec7c66SAlessandro Zummo 	unsigned char sr;
6211fec7c66SAlessandro Zummo 	struct rtc_device *rtc;
6221fec7c66SAlessandro Zummo 
6234edac2b4SAlessandro Zummo 	dev_dbg(&client->dev, "%s\n", __func__);
6241fec7c66SAlessandro Zummo 
6254edac2b4SAlessandro Zummo 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
6264edac2b4SAlessandro Zummo 		return -ENODEV;
6271fec7c66SAlessandro Zummo 
6284edac2b4SAlessandro Zummo 	if (x1205_validate_client(client) < 0)
6294edac2b4SAlessandro Zummo 		return -ENODEV;
6301fec7c66SAlessandro Zummo 
63117581718SJingoo Han 	rtc = devm_rtc_device_register(&client->dev, x1205_driver.driver.name,
6321fec7c66SAlessandro Zummo 					&x1205_rtc_ops, THIS_MODULE);
6331fec7c66SAlessandro Zummo 
6344edac2b4SAlessandro Zummo 	if (IS_ERR(rtc))
6354edac2b4SAlessandro Zummo 		return PTR_ERR(rtc);
6361fec7c66SAlessandro Zummo 
6371fec7c66SAlessandro Zummo 	i2c_set_clientdata(client, rtc);
6381fec7c66SAlessandro Zummo 
63925985edcSLucas De Marchi 	/* Check for power failures and eventually enable the osc */
64066e3f10cSSachin Kamat 	err = x1205_get_status(client, &sr);
64166e3f10cSSachin Kamat 	if (!err) {
6421fec7c66SAlessandro Zummo 		if (sr & X1205_SR_RTCF) {
6431fec7c66SAlessandro Zummo 			dev_err(&client->dev,
6441fec7c66SAlessandro Zummo 				"power failure detected, "
6451fec7c66SAlessandro Zummo 				"please set the clock\n");
6461fec7c66SAlessandro Zummo 			udelay(50);
6471fec7c66SAlessandro Zummo 			x1205_fix_osc(client);
6481fec7c66SAlessandro Zummo 		}
64966e3f10cSSachin Kamat 	} else {
6501fec7c66SAlessandro Zummo 		dev_err(&client->dev, "couldn't read status\n");
65166e3f10cSSachin Kamat 	}
6521fec7c66SAlessandro Zummo 
6534edac2b4SAlessandro Zummo 	err = x1205_sysfs_register(&client->dev);
6544edac2b4SAlessandro Zummo 	if (err)
6554071ea25SAlessandro Zummo 		dev_err(&client->dev, "Unable to create sysfs entries\n");
6561fec7c66SAlessandro Zummo 
6571fec7c66SAlessandro Zummo 	return 0;
6581fec7c66SAlessandro Zummo }
6591fec7c66SAlessandro Zummo 
x1205_remove(struct i2c_client * client)660ed5c2f5fSUwe Kleine-König static void x1205_remove(struct i2c_client *client)
6611fec7c66SAlessandro Zummo {
6624edac2b4SAlessandro Zummo 	x1205_sysfs_unregister(&client->dev);
6631fec7c66SAlessandro Zummo }
6641fec7c66SAlessandro Zummo 
6653760f736SJean Delvare static const struct i2c_device_id x1205_id[] = {
666*a47d377eSUwe Kleine-König 	{ "x1205" },
6673760f736SJean Delvare 	{ }
6683760f736SJean Delvare };
6693760f736SJean Delvare MODULE_DEVICE_TABLE(i2c, x1205_id);
6703760f736SJean Delvare 
6716875404fSLinus Walleij static const struct of_device_id x1205_dt_ids[] = {
6726875404fSLinus Walleij 	{ .compatible = "xircom,x1205", },
6736875404fSLinus Walleij 	{},
6746875404fSLinus Walleij };
6756875404fSLinus Walleij MODULE_DEVICE_TABLE(of, x1205_dt_ids);
6766875404fSLinus Walleij 
6774edac2b4SAlessandro Zummo static struct i2c_driver x1205_driver = {
6784edac2b4SAlessandro Zummo 	.driver		= {
6794edac2b4SAlessandro Zummo 		.name	= "rtc-x1205",
6806875404fSLinus Walleij 		.of_match_table = x1205_dt_ids,
6814edac2b4SAlessandro Zummo 	},
68231b0cecbSUwe Kleine-König 	.probe		= x1205_probe,
6834edac2b4SAlessandro Zummo 	.remove		= x1205_remove,
6843760f736SJean Delvare 	.id_table	= x1205_id,
6854edac2b4SAlessandro Zummo };
6864edac2b4SAlessandro Zummo 
6870abc9201SAxel Lin module_i2c_driver(x1205_driver);
6881fec7c66SAlessandro Zummo 
6891fec7c66SAlessandro Zummo MODULE_AUTHOR(
6901fec7c66SAlessandro Zummo 	"Karen Spearel <kas111 at gmail dot com>, "
6911fec7c66SAlessandro Zummo 	"Alessandro Zummo <a.zummo@towertech.it>");
6921fec7c66SAlessandro Zummo MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver");
6931fec7c66SAlessandro Zummo MODULE_LICENSE("GPL");
694