xref: /openbmc/linux/drivers/rtc/rtc-abx80x.c (revision 2eb5f31b)
1 /*
2  * A driver for the I2C members of the Abracon AB x8xx RTC family,
3  * and compatible: AB 1805 and AB 0805
4  *
5  * Copyright 2014-2015 Macq S.A.
6  *
7  * Author: Philippe De Muyter <phdm@macqel.be>
8  * Author: Alexandre Belloni <alexandre.belloni@free-electrons.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  */
15 
16 #include <linux/bcd.h>
17 #include <linux/i2c.h>
18 #include <linux/module.h>
19 #include <linux/rtc.h>
20 
21 #define ABX8XX_REG_HTH		0x00
22 #define ABX8XX_REG_SC		0x01
23 #define ABX8XX_REG_MN		0x02
24 #define ABX8XX_REG_HR		0x03
25 #define ABX8XX_REG_DA		0x04
26 #define ABX8XX_REG_MO		0x05
27 #define ABX8XX_REG_YR		0x06
28 #define ABX8XX_REG_WD		0x07
29 
30 #define ABX8XX_REG_CTRL1	0x10
31 #define ABX8XX_CTRL_WRITE	BIT(0)
32 #define ABX8XX_CTRL_12_24	BIT(6)
33 
34 #define ABX8XX_REG_CFG_KEY	0x1f
35 #define ABX8XX_CFG_KEY_MISC	0x9d
36 
37 #define ABX8XX_REG_ID0		0x28
38 
39 #define ABX8XX_REG_TRICKLE	0x20
40 #define ABX8XX_TRICKLE_CHARGE_ENABLE	0xa0
41 #define ABX8XX_TRICKLE_STANDARD_DIODE	0x8
42 #define ABX8XX_TRICKLE_SCHOTTKY_DIODE	0x4
43 
44 static u8 trickle_resistors[] = {0, 3, 6, 11};
45 
46 enum abx80x_chip {AB0801, AB0803, AB0804, AB0805,
47 	AB1801, AB1803, AB1804, AB1805, ABX80X};
48 
49 struct abx80x_cap {
50 	u16 pn;
51 	bool has_tc;
52 };
53 
54 static struct abx80x_cap abx80x_caps[] = {
55 	[AB0801] = {.pn = 0x0801},
56 	[AB0803] = {.pn = 0x0803},
57 	[AB0804] = {.pn = 0x0804, .has_tc = true},
58 	[AB0805] = {.pn = 0x0805, .has_tc = true},
59 	[AB1801] = {.pn = 0x1801},
60 	[AB1803] = {.pn = 0x1803},
61 	[AB1804] = {.pn = 0x1804, .has_tc = true},
62 	[AB1805] = {.pn = 0x1805, .has_tc = true},
63 	[ABX80X] = {.pn = 0}
64 };
65 
66 static struct i2c_driver abx80x_driver;
67 
68 static int abx80x_enable_trickle_charger(struct i2c_client *client,
69 					 u8 trickle_cfg)
70 {
71 	int err;
72 
73 	/*
74 	 * Write the configuration key register to enable access to the Trickle
75 	 * register
76 	 */
77 	err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY,
78 					ABX8XX_CFG_KEY_MISC);
79 	if (err < 0) {
80 		dev_err(&client->dev, "Unable to write configuration key\n");
81 		return -EIO;
82 	}
83 
84 	err = i2c_smbus_write_byte_data(client, ABX8XX_REG_TRICKLE,
85 					ABX8XX_TRICKLE_CHARGE_ENABLE |
86 					trickle_cfg);
87 	if (err < 0) {
88 		dev_err(&client->dev, "Unable to write trickle register\n");
89 		return -EIO;
90 	}
91 
92 	return 0;
93 }
94 
95 static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
96 {
97 	struct i2c_client *client = to_i2c_client(dev);
98 	unsigned char buf[8];
99 	int err;
100 
101 	err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH,
102 					    sizeof(buf), buf);
103 	if (err < 0) {
104 		dev_err(&client->dev, "Unable to read date\n");
105 		return -EIO;
106 	}
107 
108 	tm->tm_sec = bcd2bin(buf[ABX8XX_REG_SC] & 0x7F);
109 	tm->tm_min = bcd2bin(buf[ABX8XX_REG_MN] & 0x7F);
110 	tm->tm_hour = bcd2bin(buf[ABX8XX_REG_HR] & 0x3F);
111 	tm->tm_wday = buf[ABX8XX_REG_WD] & 0x7;
112 	tm->tm_mday = bcd2bin(buf[ABX8XX_REG_DA] & 0x3F);
113 	tm->tm_mon = bcd2bin(buf[ABX8XX_REG_MO] & 0x1F) - 1;
114 	tm->tm_year = bcd2bin(buf[ABX8XX_REG_YR]) + 100;
115 
116 	err = rtc_valid_tm(tm);
117 	if (err < 0)
118 		dev_err(&client->dev, "retrieved date/time is not valid.\n");
119 
120 	return err;
121 }
122 
123 static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
124 {
125 	struct i2c_client *client = to_i2c_client(dev);
126 	unsigned char buf[8];
127 	int err;
128 
129 	if (tm->tm_year < 100)
130 		return -EINVAL;
131 
132 	buf[ABX8XX_REG_HTH] = 0;
133 	buf[ABX8XX_REG_SC] = bin2bcd(tm->tm_sec);
134 	buf[ABX8XX_REG_MN] = bin2bcd(tm->tm_min);
135 	buf[ABX8XX_REG_HR] = bin2bcd(tm->tm_hour);
136 	buf[ABX8XX_REG_DA] = bin2bcd(tm->tm_mday);
137 	buf[ABX8XX_REG_MO] = bin2bcd(tm->tm_mon + 1);
138 	buf[ABX8XX_REG_YR] = bin2bcd(tm->tm_year - 100);
139 	buf[ABX8XX_REG_WD] = tm->tm_wday;
140 
141 	err = i2c_smbus_write_i2c_block_data(client, ABX8XX_REG_HTH,
142 					     sizeof(buf), buf);
143 	if (err < 0) {
144 		dev_err(&client->dev, "Unable to write to date registers\n");
145 		return -EIO;
146 	}
147 
148 	return 0;
149 }
150 
151 static const struct rtc_class_ops abx80x_rtc_ops = {
152 	.read_time	= abx80x_rtc_read_time,
153 	.set_time	= abx80x_rtc_set_time,
154 };
155 
156 static int abx80x_dt_trickle_cfg(struct device_node *np)
157 {
158 	const char *diode;
159 	int trickle_cfg = 0;
160 	int i, ret;
161 	u32 tmp;
162 
163 	ret = of_property_read_string(np, "abracon,tc-diode", &diode);
164 	if (ret)
165 		return ret;
166 
167 	if (!strcmp(diode, "standard"))
168 		trickle_cfg |= ABX8XX_TRICKLE_STANDARD_DIODE;
169 	else if (!strcmp(diode, "schottky"))
170 		trickle_cfg |= ABX8XX_TRICKLE_SCHOTTKY_DIODE;
171 	else
172 		return -EINVAL;
173 
174 	ret = of_property_read_u32(np, "abracon,tc-resistor", &tmp);
175 	if (ret)
176 		return ret;
177 
178 	for (i = 0; i < sizeof(trickle_resistors); i++)
179 		if (trickle_resistors[i] == tmp)
180 			break;
181 
182 	if (i == sizeof(trickle_resistors))
183 		return -EINVAL;
184 
185 	return (trickle_cfg | i);
186 }
187 
188 static int abx80x_probe(struct i2c_client *client,
189 			const struct i2c_device_id *id)
190 {
191 	struct device_node *np = client->dev.of_node;
192 	struct rtc_device *rtc;
193 	int i, data, err, trickle_cfg = -EINVAL;
194 	char buf[7];
195 	unsigned int part = id->driver_data;
196 	unsigned int partnumber;
197 	unsigned int majrev, minrev;
198 	unsigned int lot;
199 	unsigned int wafer;
200 	unsigned int uid;
201 
202 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
203 		return -ENODEV;
204 
205 	err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_ID0,
206 					    sizeof(buf), buf);
207 	if (err < 0) {
208 		dev_err(&client->dev, "Unable to read partnumber\n");
209 		return -EIO;
210 	}
211 
212 	partnumber = (buf[0] << 8) | buf[1];
213 	majrev = buf[2] >> 3;
214 	minrev = buf[2] & 0x7;
215 	lot = ((buf[4] & 0x80) << 2) | ((buf[6] & 0x80) << 1) | buf[3];
216 	uid = ((buf[4] & 0x7f) << 8) | buf[5];
217 	wafer = (buf[6] & 0x7c) >> 2;
218 	dev_info(&client->dev, "model %04x, revision %u.%u, lot %x, wafer %x, uid %x\n",
219 		 partnumber, majrev, minrev, lot, wafer, uid);
220 
221 	data = i2c_smbus_read_byte_data(client, ABX8XX_REG_CTRL1);
222 	if (data < 0) {
223 		dev_err(&client->dev, "Unable to read control register\n");
224 		return -EIO;
225 	}
226 
227 	err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CTRL1,
228 					((data & ~ABX8XX_CTRL_12_24) |
229 					 ABX8XX_CTRL_WRITE));
230 	if (err < 0) {
231 		dev_err(&client->dev, "Unable to write control register\n");
232 		return -EIO;
233 	}
234 
235 	/* part autodetection */
236 	if (part == ABX80X) {
237 		for (i = 0; abx80x_caps[i].pn; i++)
238 			if (partnumber == abx80x_caps[i].pn)
239 				break;
240 		if (abx80x_caps[i].pn == 0) {
241 			dev_err(&client->dev, "Unknown part: %04x\n",
242 				partnumber);
243 			return -EINVAL;
244 		}
245 		part = i;
246 	}
247 
248 	if (partnumber != abx80x_caps[part].pn) {
249 		dev_err(&client->dev, "partnumber mismatch %04x != %04x\n",
250 			partnumber, abx80x_caps[part].pn);
251 		return -EINVAL;
252 	}
253 
254 	if (np && abx80x_caps[part].has_tc)
255 		trickle_cfg = abx80x_dt_trickle_cfg(np);
256 
257 	if (trickle_cfg > 0) {
258 		dev_info(&client->dev, "Enabling trickle charger: %02x\n",
259 			 trickle_cfg);
260 		abx80x_enable_trickle_charger(client, trickle_cfg);
261 	}
262 
263 	rtc = devm_rtc_device_register(&client->dev, abx80x_driver.driver.name,
264 				       &abx80x_rtc_ops, THIS_MODULE);
265 
266 	if (IS_ERR(rtc))
267 		return PTR_ERR(rtc);
268 
269 	i2c_set_clientdata(client, rtc);
270 
271 	return 0;
272 }
273 
274 static int abx80x_remove(struct i2c_client *client)
275 {
276 	return 0;
277 }
278 
279 static const struct i2c_device_id abx80x_id[] = {
280 	{ "abx80x", ABX80X },
281 	{ "ab0801", AB0801 },
282 	{ "ab0803", AB0803 },
283 	{ "ab0804", AB0804 },
284 	{ "ab0805", AB0805 },
285 	{ "ab1801", AB1801 },
286 	{ "ab1803", AB1803 },
287 	{ "ab1804", AB1804 },
288 	{ "ab1805", AB1805 },
289 	{ }
290 };
291 MODULE_DEVICE_TABLE(i2c, abx80x_id);
292 
293 static struct i2c_driver abx80x_driver = {
294 	.driver		= {
295 		.name	= "rtc-abx80x",
296 	},
297 	.probe		= abx80x_probe,
298 	.remove		= abx80x_remove,
299 	.id_table	= abx80x_id,
300 };
301 
302 module_i2c_driver(abx80x_driver);
303 
304 MODULE_AUTHOR("Philippe De Muyter <phdm@macqel.be>");
305 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
306 MODULE_DESCRIPTION("Abracon ABX80X RTC driver");
307 MODULE_LICENSE("GPL v2");
308