xref: /linux/drivers/rtc/rtc-ds1374.c (revision c4ee0af3fa0dc65f690fc908f02b8355f9576ea0)
1 /*
2  * RTC client/driver for the Maxim/Dallas DS1374 Real-Time Clock over I2C
3  *
4  * Based on code by Randy Vinson <rvinson@mvista.com>,
5  * which was based on the m41t00.c by Mark Greer <mgreer@mvista.com>.
6  *
7  * Copyright (C) 2006-2007 Freescale Semiconductor
8  *
9  * 2005 (c) MontaVista Software, Inc. This file is licensed under
10  * the terms of the GNU General Public License version 2. This program
11  * is licensed "as is" without any warranty of any kind, whether express
12  * or implied.
13  */
14 /*
15  * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
16  * recommened in .../Documentation/i2c/writing-clients section
17  * "Sending and receiving", using SMBus level communication is preferred.
18  */
19 
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/interrupt.h>
23 #include <linux/i2c.h>
24 #include <linux/rtc.h>
25 #include <linux/bcd.h>
26 #include <linux/workqueue.h>
27 #include <linux/slab.h>
28 #include <linux/pm.h>
29 
30 #define DS1374_REG_TOD0		0x00 /* Time of Day */
31 #define DS1374_REG_TOD1		0x01
32 #define DS1374_REG_TOD2		0x02
33 #define DS1374_REG_TOD3		0x03
34 #define DS1374_REG_WDALM0	0x04 /* Watchdog/Alarm */
35 #define DS1374_REG_WDALM1	0x05
36 #define DS1374_REG_WDALM2	0x06
37 #define DS1374_REG_CR		0x07 /* Control */
38 #define DS1374_REG_CR_AIE	0x01 /* Alarm Int. Enable */
39 #define DS1374_REG_CR_WDALM	0x20 /* 1=Watchdog, 0=Alarm */
40 #define DS1374_REG_CR_WACE	0x40 /* WD/Alarm counter enable */
41 #define DS1374_REG_SR		0x08 /* Status */
42 #define DS1374_REG_SR_OSF	0x80 /* Oscillator Stop Flag */
43 #define DS1374_REG_SR_AF	0x01 /* Alarm Flag */
44 #define DS1374_REG_TCR		0x09 /* Trickle Charge */
45 
46 static const struct i2c_device_id ds1374_id[] = {
47 	{ "ds1374", 0 },
48 	{ }
49 };
50 MODULE_DEVICE_TABLE(i2c, ds1374_id);
51 
52 struct ds1374 {
53 	struct i2c_client *client;
54 	struct rtc_device *rtc;
55 	struct work_struct work;
56 
57 	/* The mutex protects alarm operations, and prevents a race
58 	 * between the enable_irq() in the workqueue and the free_irq()
59 	 * in the remove function.
60 	 */
61 	struct mutex mutex;
62 	int exiting;
63 };
64 
65 static struct i2c_driver ds1374_driver;
66 
67 static int ds1374_read_rtc(struct i2c_client *client, u32 *time,
68 			   int reg, int nbytes)
69 {
70 	u8 buf[4];
71 	int ret;
72 	int i;
73 
74 	if (nbytes > 4) {
75 		WARN_ON(1);
76 		return -EINVAL;
77 	}
78 
79 	ret = i2c_smbus_read_i2c_block_data(client, reg, nbytes, buf);
80 
81 	if (ret < 0)
82 		return ret;
83 	if (ret < nbytes)
84 		return -EIO;
85 
86 	for (i = nbytes - 1, *time = 0; i >= 0; i--)
87 		*time = (*time << 8) | buf[i];
88 
89 	return 0;
90 }
91 
92 static int ds1374_write_rtc(struct i2c_client *client, u32 time,
93 			    int reg, int nbytes)
94 {
95 	u8 buf[4];
96 	int i;
97 
98 	if (nbytes > 4) {
99 		WARN_ON(1);
100 		return -EINVAL;
101 	}
102 
103 	for (i = 0; i < nbytes; i++) {
104 		buf[i] = time & 0xff;
105 		time >>= 8;
106 	}
107 
108 	return i2c_smbus_write_i2c_block_data(client, reg, nbytes, buf);
109 }
110 
111 static int ds1374_check_rtc_status(struct i2c_client *client)
112 {
113 	int ret = 0;
114 	int control, stat;
115 
116 	stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
117 	if (stat < 0)
118 		return stat;
119 
120 	if (stat & DS1374_REG_SR_OSF)
121 		dev_warn(&client->dev,
122 			 "oscillator discontinuity flagged, time unreliable\n");
123 
124 	stat &= ~(DS1374_REG_SR_OSF | DS1374_REG_SR_AF);
125 
126 	ret = i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
127 	if (ret < 0)
128 		return ret;
129 
130 	/* If the alarm is pending, clear it before requesting
131 	 * the interrupt, so an interrupt event isn't reported
132 	 * before everything is initialized.
133 	 */
134 
135 	control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
136 	if (control < 0)
137 		return control;
138 
139 	control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
140 	return i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
141 }
142 
143 static int ds1374_read_time(struct device *dev, struct rtc_time *time)
144 {
145 	struct i2c_client *client = to_i2c_client(dev);
146 	u32 itime;
147 	int ret;
148 
149 	ret = ds1374_read_rtc(client, &itime, DS1374_REG_TOD0, 4);
150 	if (!ret)
151 		rtc_time_to_tm(itime, time);
152 
153 	return ret;
154 }
155 
156 static int ds1374_set_time(struct device *dev, struct rtc_time *time)
157 {
158 	struct i2c_client *client = to_i2c_client(dev);
159 	unsigned long itime;
160 
161 	rtc_tm_to_time(time, &itime);
162 	return ds1374_write_rtc(client, itime, DS1374_REG_TOD0, 4);
163 }
164 
165 /* The ds1374 has a decrementer for an alarm, rather than a comparator.
166  * If the time of day is changed, then the alarm will need to be
167  * reset.
168  */
169 static int ds1374_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
170 {
171 	struct i2c_client *client = to_i2c_client(dev);
172 	struct ds1374 *ds1374 = i2c_get_clientdata(client);
173 	u32 now, cur_alarm;
174 	int cr, sr;
175 	int ret = 0;
176 
177 	if (client->irq <= 0)
178 		return -EINVAL;
179 
180 	mutex_lock(&ds1374->mutex);
181 
182 	cr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
183 	if (ret < 0)
184 		goto out;
185 
186 	sr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
187 	if (ret < 0)
188 		goto out;
189 
190 	ret = ds1374_read_rtc(client, &now, DS1374_REG_TOD0, 4);
191 	if (ret)
192 		goto out;
193 
194 	ret = ds1374_read_rtc(client, &cur_alarm, DS1374_REG_WDALM0, 3);
195 	if (ret)
196 		goto out;
197 
198 	rtc_time_to_tm(now + cur_alarm, &alarm->time);
199 	alarm->enabled = !!(cr & DS1374_REG_CR_WACE);
200 	alarm->pending = !!(sr & DS1374_REG_SR_AF);
201 
202 out:
203 	mutex_unlock(&ds1374->mutex);
204 	return ret;
205 }
206 
207 static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
208 {
209 	struct i2c_client *client = to_i2c_client(dev);
210 	struct ds1374 *ds1374 = i2c_get_clientdata(client);
211 	struct rtc_time now;
212 	unsigned long new_alarm, itime;
213 	int cr;
214 	int ret = 0;
215 
216 	if (client->irq <= 0)
217 		return -EINVAL;
218 
219 	ret = ds1374_read_time(dev, &now);
220 	if (ret < 0)
221 		return ret;
222 
223 	rtc_tm_to_time(&alarm->time, &new_alarm);
224 	rtc_tm_to_time(&now, &itime);
225 
226 	/* This can happen due to races, in addition to dates that are
227 	 * truly in the past.  To avoid requiring the caller to check for
228 	 * races, dates in the past are assumed to be in the recent past
229 	 * (i.e. not something that we'd rather the caller know about via
230 	 * an error), and the alarm is set to go off as soon as possible.
231 	 */
232 	if (time_before_eq(new_alarm, itime))
233 		new_alarm = 1;
234 	else
235 		new_alarm -= itime;
236 
237 	mutex_lock(&ds1374->mutex);
238 
239 	ret = cr = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
240 	if (ret < 0)
241 		goto out;
242 
243 	/* Disable any existing alarm before setting the new one
244 	 * (or lack thereof). */
245 	cr &= ~DS1374_REG_CR_WACE;
246 
247 	ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
248 	if (ret < 0)
249 		goto out;
250 
251 	ret = ds1374_write_rtc(client, new_alarm, DS1374_REG_WDALM0, 3);
252 	if (ret)
253 		goto out;
254 
255 	if (alarm->enabled) {
256 		cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
257 		cr &= ~DS1374_REG_CR_WDALM;
258 
259 		ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
260 	}
261 
262 out:
263 	mutex_unlock(&ds1374->mutex);
264 	return ret;
265 }
266 
267 static irqreturn_t ds1374_irq(int irq, void *dev_id)
268 {
269 	struct i2c_client *client = dev_id;
270 	struct ds1374 *ds1374 = i2c_get_clientdata(client);
271 
272 	disable_irq_nosync(irq);
273 	schedule_work(&ds1374->work);
274 	return IRQ_HANDLED;
275 }
276 
277 static void ds1374_work(struct work_struct *work)
278 {
279 	struct ds1374 *ds1374 = container_of(work, struct ds1374, work);
280 	struct i2c_client *client = ds1374->client;
281 	int stat, control;
282 
283 	mutex_lock(&ds1374->mutex);
284 
285 	stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
286 	if (stat < 0)
287 		goto unlock;
288 
289 	if (stat & DS1374_REG_SR_AF) {
290 		stat &= ~DS1374_REG_SR_AF;
291 		i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
292 
293 		control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
294 		if (control < 0)
295 			goto out;
296 
297 		control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
298 		i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
299 
300 		rtc_update_irq(ds1374->rtc, 1, RTC_AF | RTC_IRQF);
301 	}
302 
303 out:
304 	if (!ds1374->exiting)
305 		enable_irq(client->irq);
306 unlock:
307 	mutex_unlock(&ds1374->mutex);
308 }
309 
310 static int ds1374_alarm_irq_enable(struct device *dev, unsigned int enabled)
311 {
312 	struct i2c_client *client = to_i2c_client(dev);
313 	struct ds1374 *ds1374 = i2c_get_clientdata(client);
314 	int ret;
315 
316 	mutex_lock(&ds1374->mutex);
317 
318 	ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
319 	if (ret < 0)
320 		goto out;
321 
322 	if (enabled) {
323 		ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
324 		ret &= ~DS1374_REG_CR_WDALM;
325 	} else {
326 		ret &= ~DS1374_REG_CR_WACE;
327 	}
328 	ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
329 
330 out:
331 	mutex_unlock(&ds1374->mutex);
332 	return ret;
333 }
334 
335 static const struct rtc_class_ops ds1374_rtc_ops = {
336 	.read_time = ds1374_read_time,
337 	.set_time = ds1374_set_time,
338 	.read_alarm = ds1374_read_alarm,
339 	.set_alarm = ds1374_set_alarm,
340 	.alarm_irq_enable = ds1374_alarm_irq_enable,
341 };
342 
343 static int ds1374_probe(struct i2c_client *client,
344 			const struct i2c_device_id *id)
345 {
346 	struct ds1374 *ds1374;
347 	int ret;
348 
349 	ds1374 = devm_kzalloc(&client->dev, sizeof(struct ds1374), GFP_KERNEL);
350 	if (!ds1374)
351 		return -ENOMEM;
352 
353 	ds1374->client = client;
354 	i2c_set_clientdata(client, ds1374);
355 
356 	INIT_WORK(&ds1374->work, ds1374_work);
357 	mutex_init(&ds1374->mutex);
358 
359 	ret = ds1374_check_rtc_status(client);
360 	if (ret)
361 		return ret;
362 
363 	if (client->irq > 0) {
364 		ret = devm_request_irq(&client->dev, client->irq, ds1374_irq, 0,
365 					"ds1374", client);
366 		if (ret) {
367 			dev_err(&client->dev, "unable to request IRQ\n");
368 			return ret;
369 		}
370 
371 		device_set_wakeup_capable(&client->dev, 1);
372 	}
373 
374 	ds1374->rtc = devm_rtc_device_register(&client->dev, client->name,
375 						&ds1374_rtc_ops, THIS_MODULE);
376 	if (IS_ERR(ds1374->rtc)) {
377 		dev_err(&client->dev, "unable to register the class device\n");
378 		return PTR_ERR(ds1374->rtc);
379 	}
380 
381 	return 0;
382 }
383 
384 static int ds1374_remove(struct i2c_client *client)
385 {
386 	struct ds1374 *ds1374 = i2c_get_clientdata(client);
387 
388 	if (client->irq > 0) {
389 		mutex_lock(&ds1374->mutex);
390 		ds1374->exiting = 1;
391 		mutex_unlock(&ds1374->mutex);
392 
393 		devm_free_irq(&client->dev, client->irq, client);
394 		cancel_work_sync(&ds1374->work);
395 	}
396 
397 	return 0;
398 }
399 
400 #ifdef CONFIG_PM_SLEEP
401 static int ds1374_suspend(struct device *dev)
402 {
403 	struct i2c_client *client = to_i2c_client(dev);
404 
405 	if (client->irq >= 0 && device_may_wakeup(&client->dev))
406 		enable_irq_wake(client->irq);
407 	return 0;
408 }
409 
410 static int ds1374_resume(struct device *dev)
411 {
412 	struct i2c_client *client = to_i2c_client(dev);
413 
414 	if (client->irq >= 0 && device_may_wakeup(&client->dev))
415 		disable_irq_wake(client->irq);
416 	return 0;
417 }
418 #endif
419 
420 static SIMPLE_DEV_PM_OPS(ds1374_pm, ds1374_suspend, ds1374_resume);
421 
422 static struct i2c_driver ds1374_driver = {
423 	.driver = {
424 		.name = "rtc-ds1374",
425 		.owner = THIS_MODULE,
426 		.pm = &ds1374_pm,
427 	},
428 	.probe = ds1374_probe,
429 	.remove = ds1374_remove,
430 	.id_table = ds1374_id,
431 };
432 
433 module_i2c_driver(ds1374_driver);
434 
435 MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>");
436 MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver");
437 MODULE_LICENSE("GPL");
438