xref: /openbmc/linux/drivers/rtc/rtc-ds3232.c (revision d0b73b48)
1 /*
2  * RTC client/driver for the Maxim/Dallas DS3232 Real-Time Clock over I2C
3  *
4  * Copyright (C) 2009-2011 Freescale Semiconductor.
5  * Author: Jack Lan <jack.lan@freescale.com>
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  */
12 /*
13  * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
14  * recommened in .../Documentation/i2c/writing-clients section
15  * "Sending and receiving", using SMBus level communication is preferred.
16  */
17 
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/interrupt.h>
21 #include <linux/i2c.h>
22 #include <linux/rtc.h>
23 #include <linux/bcd.h>
24 #include <linux/workqueue.h>
25 #include <linux/slab.h>
26 
27 #define DS3232_REG_SECONDS	0x00
28 #define DS3232_REG_MINUTES	0x01
29 #define DS3232_REG_HOURS	0x02
30 #define DS3232_REG_AMPM		0x02
31 #define DS3232_REG_DAY		0x03
32 #define DS3232_REG_DATE		0x04
33 #define DS3232_REG_MONTH	0x05
34 #define DS3232_REG_CENTURY	0x05
35 #define DS3232_REG_YEAR		0x06
36 #define DS3232_REG_ALARM1         0x07	/* Alarm 1 BASE */
37 #define DS3232_REG_ALARM2         0x0B	/* Alarm 2 BASE */
38 #define DS3232_REG_CR		0x0E	/* Control register */
39 #	define DS3232_REG_CR_nEOSC        0x80
40 #       define DS3232_REG_CR_INTCN        0x04
41 #       define DS3232_REG_CR_A2IE        0x02
42 #       define DS3232_REG_CR_A1IE        0x01
43 
44 #define DS3232_REG_SR	0x0F	/* control/status register */
45 #	define DS3232_REG_SR_OSF   0x80
46 #       define DS3232_REG_SR_BSY   0x04
47 #       define DS3232_REG_SR_A2F   0x02
48 #       define DS3232_REG_SR_A1F   0x01
49 
50 struct ds3232 {
51 	struct i2c_client *client;
52 	struct rtc_device *rtc;
53 	struct work_struct work;
54 
55 	/* The mutex protects alarm operations, and prevents a race
56 	 * between the enable_irq() in the workqueue and the free_irq()
57 	 * in the remove function.
58 	 */
59 	struct mutex mutex;
60 	int exiting;
61 };
62 
63 static struct i2c_driver ds3232_driver;
64 
65 static int ds3232_check_rtc_status(struct i2c_client *client)
66 {
67 	int ret = 0;
68 	int control, stat;
69 
70 	stat = i2c_smbus_read_byte_data(client, DS3232_REG_SR);
71 	if (stat < 0)
72 		return stat;
73 
74 	if (stat & DS3232_REG_SR_OSF)
75 		dev_warn(&client->dev,
76 				"oscillator discontinuity flagged, "
77 				"time unreliable\n");
78 
79 	stat &= ~(DS3232_REG_SR_OSF | DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
80 
81 	ret = i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat);
82 	if (ret < 0)
83 		return ret;
84 
85 	/* If the alarm is pending, clear it before requesting
86 	 * the interrupt, so an interrupt event isn't reported
87 	 * before everything is initialized.
88 	 */
89 
90 	control = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
91 	if (control < 0)
92 		return control;
93 
94 	control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
95 	control |= DS3232_REG_CR_INTCN;
96 
97 	return i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
98 }
99 
100 static int ds3232_read_time(struct device *dev, struct rtc_time *time)
101 {
102 	struct i2c_client *client = to_i2c_client(dev);
103 	int ret;
104 	u8 buf[7];
105 	unsigned int year, month, day, hour, minute, second;
106 	unsigned int week, twelve_hr, am_pm;
107 	unsigned int century, add_century = 0;
108 
109 	ret = i2c_smbus_read_i2c_block_data(client, DS3232_REG_SECONDS, 7, buf);
110 
111 	if (ret < 0)
112 		return ret;
113 	if (ret < 7)
114 		return -EIO;
115 
116 	second = buf[0];
117 	minute = buf[1];
118 	hour = buf[2];
119 	week = buf[3];
120 	day = buf[4];
121 	month = buf[5];
122 	year = buf[6];
123 
124 	/* Extract additional information for AM/PM and century */
125 
126 	twelve_hr = hour & 0x40;
127 	am_pm = hour & 0x20;
128 	century = month & 0x80;
129 
130 	/* Write to rtc_time structure */
131 
132 	time->tm_sec = bcd2bin(second);
133 	time->tm_min = bcd2bin(minute);
134 	if (twelve_hr) {
135 		/* Convert to 24 hr */
136 		if (am_pm)
137 			time->tm_hour = bcd2bin(hour & 0x1F) + 12;
138 		else
139 			time->tm_hour = bcd2bin(hour & 0x1F);
140 	} else {
141 		time->tm_hour = bcd2bin(hour);
142 	}
143 
144 	/* Day of the week in linux range is 0~6 while 1~7 in RTC chip */
145 	time->tm_wday = bcd2bin(week) - 1;
146 	time->tm_mday = bcd2bin(day);
147 	/* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */
148 	time->tm_mon = bcd2bin(month & 0x7F) - 1;
149 	if (century)
150 		add_century = 100;
151 
152 	time->tm_year = bcd2bin(year) + add_century;
153 
154 	return rtc_valid_tm(time);
155 }
156 
157 static int ds3232_set_time(struct device *dev, struct rtc_time *time)
158 {
159 	struct i2c_client *client = to_i2c_client(dev);
160 	u8 buf[7];
161 
162 	/* Extract time from rtc_time and load into ds3232*/
163 
164 	buf[0] = bin2bcd(time->tm_sec);
165 	buf[1] = bin2bcd(time->tm_min);
166 	buf[2] = bin2bcd(time->tm_hour);
167 	/* Day of the week in linux range is 0~6 while 1~7 in RTC chip */
168 	buf[3] = bin2bcd(time->tm_wday + 1);
169 	buf[4] = bin2bcd(time->tm_mday); /* Date */
170 	/* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */
171 	buf[5] = bin2bcd(time->tm_mon + 1);
172 	if (time->tm_year >= 100) {
173 		buf[5] |= 0x80;
174 		buf[6] = bin2bcd(time->tm_year - 100);
175 	} else {
176 		buf[6] = bin2bcd(time->tm_year);
177 	}
178 
179 	return i2c_smbus_write_i2c_block_data(client,
180 					      DS3232_REG_SECONDS, 7, buf);
181 }
182 
183 /*
184  * DS3232 has two alarm, we only use alarm1
185  * According to linux specification, only support one-shot alarm
186  * no periodic alarm mode
187  */
188 static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
189 {
190 	struct i2c_client *client = to_i2c_client(dev);
191 	struct ds3232 *ds3232 = i2c_get_clientdata(client);
192 	int control, stat;
193 	int ret;
194 	u8 buf[4];
195 
196 	mutex_lock(&ds3232->mutex);
197 
198 	ret = i2c_smbus_read_byte_data(client, DS3232_REG_SR);
199 	if (ret < 0)
200 		goto out;
201 	stat = ret;
202 	ret = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
203 	if (ret < 0)
204 		goto out;
205 	control = ret;
206 	ret = i2c_smbus_read_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf);
207 	if (ret < 0)
208 		goto out;
209 
210 	alarm->time.tm_sec = bcd2bin(buf[0] & 0x7F);
211 	alarm->time.tm_min = bcd2bin(buf[1] & 0x7F);
212 	alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F);
213 	alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F);
214 
215 	alarm->time.tm_mon = -1;
216 	alarm->time.tm_year = -1;
217 	alarm->time.tm_wday = -1;
218 	alarm->time.tm_yday = -1;
219 	alarm->time.tm_isdst = -1;
220 
221 	alarm->enabled = !!(control & DS3232_REG_CR_A1IE);
222 	alarm->pending = !!(stat & DS3232_REG_SR_A1F);
223 
224 	ret = 0;
225 out:
226 	mutex_unlock(&ds3232->mutex);
227 	return ret;
228 }
229 
230 /*
231  * linux rtc-module does not support wday alarm
232  * and only 24h time mode supported indeed
233  */
234 static int ds3232_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
235 {
236 	struct i2c_client *client = to_i2c_client(dev);
237 	struct ds3232 *ds3232 = i2c_get_clientdata(client);
238 	int control, stat;
239 	int ret;
240 	u8 buf[4];
241 
242 	if (client->irq <= 0)
243 		return -EINVAL;
244 
245 	mutex_lock(&ds3232->mutex);
246 
247 	buf[0] = bin2bcd(alarm->time.tm_sec);
248 	buf[1] = bin2bcd(alarm->time.tm_min);
249 	buf[2] = bin2bcd(alarm->time.tm_hour);
250 	buf[3] = bin2bcd(alarm->time.tm_mday);
251 
252 	/* clear alarm interrupt enable bit */
253 	ret = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
254 	if (ret < 0)
255 		goto out;
256 	control = ret;
257 	control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
258 	ret = i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
259 	if (ret < 0)
260 		goto out;
261 
262 	/* clear any pending alarm flag */
263 	ret = i2c_smbus_read_byte_data(client, DS3232_REG_SR);
264 	if (ret < 0)
265 		goto out;
266 	stat = ret;
267 	stat &= ~(DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
268 	ret = i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat);
269 	if (ret < 0)
270 		goto out;
271 
272 	ret = i2c_smbus_write_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf);
273 
274 	if (alarm->enabled) {
275 		control |= DS3232_REG_CR_A1IE;
276 		ret = i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
277 	}
278 out:
279 	mutex_unlock(&ds3232->mutex);
280 	return ret;
281 }
282 
283 static void ds3232_update_alarm(struct i2c_client *client)
284 {
285 	struct ds3232 *ds3232 = i2c_get_clientdata(client);
286 	int control;
287 	int ret;
288 	u8 buf[4];
289 
290 	mutex_lock(&ds3232->mutex);
291 
292 	ret = i2c_smbus_read_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf);
293 	if (ret < 0)
294 		goto unlock;
295 
296 	buf[0] = bcd2bin(buf[0]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ?
297 								0x80 : buf[0];
298 	buf[1] = bcd2bin(buf[1]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ?
299 								0x80 : buf[1];
300 	buf[2] = bcd2bin(buf[2]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ?
301 								0x80 : buf[2];
302 	buf[3] = bcd2bin(buf[3]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ?
303 								0x80 : buf[3];
304 
305 	ret = i2c_smbus_write_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf);
306 	if (ret < 0)
307 		goto unlock;
308 
309 	control = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
310 	if (control < 0)
311 		goto unlock;
312 
313 	if (ds3232->rtc->irq_data & (RTC_AF | RTC_UF))
314 		/* enable alarm1 interrupt */
315 		control |= DS3232_REG_CR_A1IE;
316 	else
317 		/* disable alarm1 interrupt */
318 		control &= ~(DS3232_REG_CR_A1IE);
319 	i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
320 
321 unlock:
322 	mutex_unlock(&ds3232->mutex);
323 }
324 
325 static int ds3232_alarm_irq_enable(struct device *dev, unsigned int enabled)
326 {
327 	struct i2c_client *client = to_i2c_client(dev);
328 	struct ds3232 *ds3232 = i2c_get_clientdata(client);
329 
330 	if (client->irq <= 0)
331 		return -EINVAL;
332 
333 	if (enabled)
334 		ds3232->rtc->irq_data |= RTC_AF;
335 	else
336 		ds3232->rtc->irq_data &= ~RTC_AF;
337 
338 	ds3232_update_alarm(client);
339 	return 0;
340 }
341 
342 static irqreturn_t ds3232_irq(int irq, void *dev_id)
343 {
344 	struct i2c_client *client = dev_id;
345 	struct ds3232 *ds3232 = i2c_get_clientdata(client);
346 
347 	disable_irq_nosync(irq);
348 	schedule_work(&ds3232->work);
349 	return IRQ_HANDLED;
350 }
351 
352 static void ds3232_work(struct work_struct *work)
353 {
354 	struct ds3232 *ds3232 = container_of(work, struct ds3232, work);
355 	struct i2c_client *client = ds3232->client;
356 	int stat, control;
357 
358 	mutex_lock(&ds3232->mutex);
359 
360 	stat = i2c_smbus_read_byte_data(client, DS3232_REG_SR);
361 	if (stat < 0)
362 		goto unlock;
363 
364 	if (stat & DS3232_REG_SR_A1F) {
365 		control = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
366 		if (control < 0)
367 			goto out;
368 		/* disable alarm1 interrupt */
369 		control &= ~(DS3232_REG_CR_A1IE);
370 		i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
371 
372 		/* clear the alarm pend flag */
373 		stat &= ~DS3232_REG_SR_A1F;
374 		i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat);
375 
376 		rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF);
377 	}
378 
379 out:
380 	if (!ds3232->exiting)
381 		enable_irq(client->irq);
382 unlock:
383 	mutex_unlock(&ds3232->mutex);
384 }
385 
386 static const struct rtc_class_ops ds3232_rtc_ops = {
387 	.read_time = ds3232_read_time,
388 	.set_time = ds3232_set_time,
389 	.read_alarm = ds3232_read_alarm,
390 	.set_alarm = ds3232_set_alarm,
391 	.alarm_irq_enable = ds3232_alarm_irq_enable,
392 };
393 
394 static int ds3232_probe(struct i2c_client *client,
395 			const struct i2c_device_id *id)
396 {
397 	struct ds3232 *ds3232;
398 	int ret;
399 
400 	ds3232 = kzalloc(sizeof(struct ds3232), GFP_KERNEL);
401 	if (!ds3232)
402 		return -ENOMEM;
403 
404 	ds3232->client = client;
405 	i2c_set_clientdata(client, ds3232);
406 
407 	INIT_WORK(&ds3232->work, ds3232_work);
408 	mutex_init(&ds3232->mutex);
409 
410 	ret = ds3232_check_rtc_status(client);
411 	if (ret)
412 		goto out_free;
413 
414 	ds3232->rtc = rtc_device_register(client->name, &client->dev,
415 					  &ds3232_rtc_ops, THIS_MODULE);
416 	if (IS_ERR(ds3232->rtc)) {
417 		ret = PTR_ERR(ds3232->rtc);
418 		dev_err(&client->dev, "unable to register the class device\n");
419 		goto out_irq;
420 	}
421 
422 	if (client->irq >= 0) {
423 		ret = request_irq(client->irq, ds3232_irq, 0,
424 				 "ds3232", client);
425 		if (ret) {
426 			dev_err(&client->dev, "unable to request IRQ\n");
427 			goto out_free;
428 		}
429 	}
430 
431 	return 0;
432 
433 out_irq:
434 	if (client->irq >= 0)
435 		free_irq(client->irq, client);
436 
437 out_free:
438 	kfree(ds3232);
439 	return ret;
440 }
441 
442 static int ds3232_remove(struct i2c_client *client)
443 {
444 	struct ds3232 *ds3232 = i2c_get_clientdata(client);
445 
446 	if (client->irq >= 0) {
447 		mutex_lock(&ds3232->mutex);
448 		ds3232->exiting = 1;
449 		mutex_unlock(&ds3232->mutex);
450 
451 		free_irq(client->irq, client);
452 		cancel_work_sync(&ds3232->work);
453 	}
454 
455 	rtc_device_unregister(ds3232->rtc);
456 	kfree(ds3232);
457 	return 0;
458 }
459 
460 static const struct i2c_device_id ds3232_id[] = {
461 	{ "ds3232", 0 },
462 	{ }
463 };
464 MODULE_DEVICE_TABLE(i2c, ds3232_id);
465 
466 static struct i2c_driver ds3232_driver = {
467 	.driver = {
468 		.name = "rtc-ds3232",
469 		.owner = THIS_MODULE,
470 	},
471 	.probe = ds3232_probe,
472 	.remove = ds3232_remove,
473 	.id_table = ds3232_id,
474 };
475 
476 module_i2c_driver(ds3232_driver);
477 
478 MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
479 MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver");
480 MODULE_LICENSE("GPL");
481