xref: /linux/drivers/rtc/rtc-pcf8523.c (revision 0d456bad36d42d16022be045c8a53ddbb59ee478)
1 /*
2  * Copyright (C) 2012 Avionic Design GmbH
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8 
9 #include <linux/bcd.h>
10 #include <linux/i2c.h>
11 #include <linux/module.h>
12 #include <linux/rtc.h>
13 #include <linux/of.h>
14 
15 #define DRIVER_NAME "rtc-pcf8523"
16 
17 #define REG_CONTROL1 0x00
18 #define REG_CONTROL1_CAP_SEL (1 << 7)
19 #define REG_CONTROL1_STOP    (1 << 5)
20 
21 #define REG_CONTROL3 0x02
22 #define REG_CONTROL3_PM_BLD (1 << 7) /* battery low detection disabled */
23 #define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */
24 #define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */
25 #define REG_CONTROL3_PM_MASK 0xe0
26 
27 #define REG_SECONDS  0x03
28 #define REG_SECONDS_OS (1 << 7)
29 
30 #define REG_MINUTES  0x04
31 #define REG_HOURS    0x05
32 #define REG_DAYS     0x06
33 #define REG_WEEKDAYS 0x07
34 #define REG_MONTHS   0x08
35 #define REG_YEARS    0x09
36 
37 struct pcf8523 {
38 	struct rtc_device *rtc;
39 };
40 
41 static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep)
42 {
43 	struct i2c_msg msgs[2];
44 	u8 value = 0;
45 	int err;
46 
47 	msgs[0].addr = client->addr;
48 	msgs[0].flags = 0;
49 	msgs[0].len = sizeof(reg);
50 	msgs[0].buf = &reg;
51 
52 	msgs[1].addr = client->addr;
53 	msgs[1].flags = I2C_M_RD;
54 	msgs[1].len = sizeof(value);
55 	msgs[1].buf = &value;
56 
57 	err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
58 	if (err < 0)
59 		return err;
60 
61 	*valuep = value;
62 
63 	return 0;
64 }
65 
66 static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value)
67 {
68 	u8 buffer[2] = { reg, value };
69 	struct i2c_msg msg;
70 	int err;
71 
72 	msg.addr = client->addr;
73 	msg.flags = 0;
74 	msg.len = sizeof(buffer);
75 	msg.buf = buffer;
76 
77 	err = i2c_transfer(client->adapter, &msg, 1);
78 	if (err < 0)
79 		return err;
80 
81 	return 0;
82 }
83 
84 static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
85 {
86 	u8 value;
87 	int err;
88 
89 	err = pcf8523_read(client, REG_CONTROL1, &value);
90 	if (err < 0)
91 		return err;
92 
93 	if (!high)
94 		value &= ~REG_CONTROL1_CAP_SEL;
95 	else
96 		value |= REG_CONTROL1_CAP_SEL;
97 
98 	err = pcf8523_write(client, REG_CONTROL1, value);
99 	if (err < 0)
100 		return err;
101 
102 	return err;
103 }
104 
105 static int pcf8523_set_pm(struct i2c_client *client, u8 pm)
106 {
107 	u8 value;
108 	int err;
109 
110 	err = pcf8523_read(client, REG_CONTROL3, &value);
111 	if (err < 0)
112 		return err;
113 
114 	value = (value & ~REG_CONTROL3_PM_MASK) | pm;
115 
116 	err = pcf8523_write(client, REG_CONTROL3, value);
117 	if (err < 0)
118 		return err;
119 
120 	return 0;
121 }
122 
123 static int pcf8523_stop_rtc(struct i2c_client *client)
124 {
125 	u8 value;
126 	int err;
127 
128 	err = pcf8523_read(client, REG_CONTROL1, &value);
129 	if (err < 0)
130 		return err;
131 
132 	value |= REG_CONTROL1_STOP;
133 
134 	err = pcf8523_write(client, REG_CONTROL1, value);
135 	if (err < 0)
136 		return err;
137 
138 	return 0;
139 }
140 
141 static int pcf8523_start_rtc(struct i2c_client *client)
142 {
143 	u8 value;
144 	int err;
145 
146 	err = pcf8523_read(client, REG_CONTROL1, &value);
147 	if (err < 0)
148 		return err;
149 
150 	value &= ~REG_CONTROL1_STOP;
151 
152 	err = pcf8523_write(client, REG_CONTROL1, value);
153 	if (err < 0)
154 		return err;
155 
156 	return 0;
157 }
158 
159 static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
160 {
161 	struct i2c_client *client = to_i2c_client(dev);
162 	u8 start = REG_SECONDS, regs[7];
163 	struct i2c_msg msgs[2];
164 	int err;
165 
166 	msgs[0].addr = client->addr;
167 	msgs[0].flags = 0;
168 	msgs[0].len = 1;
169 	msgs[0].buf = &start;
170 
171 	msgs[1].addr = client->addr;
172 	msgs[1].flags = I2C_M_RD;
173 	msgs[1].len = sizeof(regs);
174 	msgs[1].buf = regs;
175 
176 	err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
177 	if (err < 0)
178 		return err;
179 
180 	if (regs[0] & REG_SECONDS_OS) {
181 		/*
182 		 * If the oscillator was stopped, try to clear the flag. Upon
183 		 * power-up the flag is always set, but if we cannot clear it
184 		 * the oscillator isn't running properly for some reason. The
185 		 * sensible thing therefore is to return an error, signalling
186 		 * that the clock cannot be assumed to be correct.
187 		 */
188 
189 		regs[0] &= ~REG_SECONDS_OS;
190 
191 		err = pcf8523_write(client, REG_SECONDS, regs[0]);
192 		if (err < 0)
193 			return err;
194 
195 		err = pcf8523_read(client, REG_SECONDS, &regs[0]);
196 		if (err < 0)
197 			return err;
198 
199 		if (regs[0] & REG_SECONDS_OS)
200 			return -EAGAIN;
201 	}
202 
203 	tm->tm_sec = bcd2bin(regs[0] & 0x7f);
204 	tm->tm_min = bcd2bin(regs[1] & 0x7f);
205 	tm->tm_hour = bcd2bin(regs[2] & 0x3f);
206 	tm->tm_mday = bcd2bin(regs[3] & 0x3f);
207 	tm->tm_wday = regs[4] & 0x7;
208 	tm->tm_mon = bcd2bin(regs[5] & 0x1f);
209 	tm->tm_year = bcd2bin(regs[6]) + 100;
210 
211 	return rtc_valid_tm(tm);
212 }
213 
214 static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
215 {
216 	struct i2c_client *client = to_i2c_client(dev);
217 	struct i2c_msg msg;
218 	u8 regs[8];
219 	int err;
220 
221 	err = pcf8523_stop_rtc(client);
222 	if (err < 0)
223 		return err;
224 
225 	regs[0] = REG_SECONDS;
226 	regs[1] = bin2bcd(tm->tm_sec);
227 	regs[2] = bin2bcd(tm->tm_min);
228 	regs[3] = bin2bcd(tm->tm_hour);
229 	regs[4] = bin2bcd(tm->tm_mday);
230 	regs[5] = tm->tm_wday;
231 	regs[6] = bin2bcd(tm->tm_mon);
232 	regs[7] = bin2bcd(tm->tm_year - 100);
233 
234 	msg.addr = client->addr;
235 	msg.flags = 0;
236 	msg.len = sizeof(regs);
237 	msg.buf = regs;
238 
239 	err = i2c_transfer(client->adapter, &msg, 1);
240 	if (err < 0) {
241 		/*
242 		 * If the time cannot be set, restart the RTC anyway. Note
243 		 * that errors are ignored if the RTC cannot be started so
244 		 * that we have a chance to propagate the original error.
245 		 */
246 		pcf8523_start_rtc(client);
247 		return err;
248 	}
249 
250 	return pcf8523_start_rtc(client);
251 }
252 
253 static const struct rtc_class_ops pcf8523_rtc_ops = {
254 	.read_time = pcf8523_rtc_read_time,
255 	.set_time = pcf8523_rtc_set_time,
256 };
257 
258 static int pcf8523_probe(struct i2c_client *client,
259 			 const struct i2c_device_id *id)
260 {
261 	struct pcf8523 *pcf;
262 	int err;
263 
264 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
265 		return -ENODEV;
266 
267 	pcf = devm_kzalloc(&client->dev, sizeof(*pcf), GFP_KERNEL);
268 	if (!pcf)
269 		return -ENOMEM;
270 
271 	err = pcf8523_select_capacitance(client, true);
272 	if (err < 0)
273 		return err;
274 
275 	err = pcf8523_set_pm(client, 0);
276 	if (err < 0)
277 		return err;
278 
279 	pcf->rtc = rtc_device_register(DRIVER_NAME, &client->dev,
280 				       &pcf8523_rtc_ops, THIS_MODULE);
281 	if (IS_ERR(pcf->rtc))
282 		return PTR_ERR(pcf->rtc);
283 
284 	i2c_set_clientdata(client, pcf);
285 
286 	return 0;
287 }
288 
289 static int pcf8523_remove(struct i2c_client *client)
290 {
291 	struct pcf8523 *pcf = i2c_get_clientdata(client);
292 
293 	rtc_device_unregister(pcf->rtc);
294 
295 	return 0;
296 }
297 
298 static const struct i2c_device_id pcf8523_id[] = {
299 	{ "pcf8523", 0 },
300 	{ }
301 };
302 MODULE_DEVICE_TABLE(i2c, pcf8523_id);
303 
304 #ifdef CONFIG_OF
305 static const struct of_device_id pcf8523_of_match[] = {
306 	{ .compatible = "nxp,pcf8523" },
307 	{ }
308 };
309 MODULE_DEVICE_TABLE(of, pcf8523_of_match);
310 #endif
311 
312 static struct i2c_driver pcf8523_driver = {
313 	.driver = {
314 		.name = DRIVER_NAME,
315 		.owner = THIS_MODULE,
316 		.of_match_table = of_match_ptr(pcf8523_of_match),
317 	},
318 	.probe = pcf8523_probe,
319 	.remove = pcf8523_remove,
320 	.id_table = pcf8523_id,
321 };
322 module_i2c_driver(pcf8523_driver);
323 
324 MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
325 MODULE_DESCRIPTION("NXP PCF8523 RTC driver");
326 MODULE_LICENSE("GPL v2");
327