xref: /linux/drivers/rtc/rtc-m48t59.c (revision a5766f11cfd3a0c03450d99c8fe548c2940be884)
1 /*
2  * ST M48T59 RTC driver
3  *
4  * Copyright (c) 2007 Wind River Systems, Inc.
5  *
6  * Author: Mark Zhan <rongkai.zhan@windriver.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/io.h>
17 #include <linux/device.h>
18 #include <linux/platform_device.h>
19 #include <linux/rtc.h>
20 #include <linux/rtc/m48t59.h>
21 #include <linux/bcd.h>
22 
23 #ifndef NO_IRQ
24 #define NO_IRQ	(-1)
25 #endif
26 
27 #define M48T59_READ(reg) (pdata->read_byte(dev, pdata->offset + reg))
28 #define M48T59_WRITE(val, reg) \
29 	(pdata->write_byte(dev, pdata->offset + reg, val))
30 
31 #define M48T59_SET_BITS(mask, reg)	\
32 	M48T59_WRITE((M48T59_READ(reg) | (mask)), (reg))
33 #define M48T59_CLEAR_BITS(mask, reg)	\
34 	M48T59_WRITE((M48T59_READ(reg) & ~(mask)), (reg))
35 
36 struct m48t59_private {
37 	void __iomem *ioaddr;
38 	int irq;
39 	struct rtc_device *rtc;
40 	spinlock_t lock; /* serialize the NVRAM and RTC access */
41 };
42 
43 /*
44  * This is the generic access method when the chip is memory-mapped
45  */
46 static void
47 m48t59_mem_writeb(struct device *dev, u32 ofs, u8 val)
48 {
49 	struct platform_device *pdev = to_platform_device(dev);
50 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
51 
52 	writeb(val, m48t59->ioaddr+ofs);
53 }
54 
55 static u8
56 m48t59_mem_readb(struct device *dev, u32 ofs)
57 {
58 	struct platform_device *pdev = to_platform_device(dev);
59 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
60 
61 	return readb(m48t59->ioaddr+ofs);
62 }
63 
64 /*
65  * NOTE: M48T59 only uses BCD mode
66  */
67 static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
68 {
69 	struct platform_device *pdev = to_platform_device(dev);
70 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
71 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
72 	unsigned long flags;
73 	u8 val;
74 
75 	spin_lock_irqsave(&m48t59->lock, flags);
76 	/* Issue the READ command */
77 	M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL);
78 
79 	tm->tm_year	= BCD2BIN(M48T59_READ(M48T59_YEAR));
80 	/* tm_mon is 0-11 */
81 	tm->tm_mon	= BCD2BIN(M48T59_READ(M48T59_MONTH)) - 1;
82 	tm->tm_mday	= BCD2BIN(M48T59_READ(M48T59_MDAY));
83 
84 	val = M48T59_READ(M48T59_WDAY);
85 	if ((pdata->type == M48T59RTC_TYPE_M48T59) &&
86 	    (val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB)) {
87 		dev_dbg(dev, "Century bit is enabled\n");
88 		tm->tm_year += 100;	/* one century */
89 	}
90 
91 	tm->tm_wday	= BCD2BIN(val & 0x07);
92 	tm->tm_hour	= BCD2BIN(M48T59_READ(M48T59_HOUR) & 0x3F);
93 	tm->tm_min	= BCD2BIN(M48T59_READ(M48T59_MIN) & 0x7F);
94 	tm->tm_sec	= BCD2BIN(M48T59_READ(M48T59_SEC) & 0x7F);
95 
96 	/* Clear the READ bit */
97 	M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
98 	spin_unlock_irqrestore(&m48t59->lock, flags);
99 
100 	dev_dbg(dev, "RTC read time %04d-%02d-%02d %02d/%02d/%02d\n",
101 		tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
102 		tm->tm_hour, tm->tm_min, tm->tm_sec);
103 	return 0;
104 }
105 
106 static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm)
107 {
108 	struct platform_device *pdev = to_platform_device(dev);
109 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
110 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
111 	unsigned long flags;
112 	u8 val = 0;
113 
114 	dev_dbg(dev, "RTC set time %04d-%02d-%02d %02d/%02d/%02d\n",
115 		tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
116 		tm->tm_hour, tm->tm_min, tm->tm_sec);
117 
118 	spin_lock_irqsave(&m48t59->lock, flags);
119 	/* Issue the WRITE command */
120 	M48T59_SET_BITS(M48T59_CNTL_WRITE, M48T59_CNTL);
121 
122 	M48T59_WRITE((BIN2BCD(tm->tm_sec) & 0x7F), M48T59_SEC);
123 	M48T59_WRITE((BIN2BCD(tm->tm_min) & 0x7F), M48T59_MIN);
124 	M48T59_WRITE((BIN2BCD(tm->tm_hour) & 0x3F), M48T59_HOUR);
125 	M48T59_WRITE((BIN2BCD(tm->tm_mday) & 0x3F), M48T59_MDAY);
126 	/* tm_mon is 0-11 */
127 	M48T59_WRITE((BIN2BCD(tm->tm_mon + 1) & 0x1F), M48T59_MONTH);
128 	M48T59_WRITE(BIN2BCD(tm->tm_year % 100), M48T59_YEAR);
129 
130 	if (pdata->type == M48T59RTC_TYPE_M48T59 && (tm->tm_year / 100))
131 		val = (M48T59_WDAY_CEB | M48T59_WDAY_CB);
132 	val |= (BIN2BCD(tm->tm_wday) & 0x07);
133 	M48T59_WRITE(val, M48T59_WDAY);
134 
135 	/* Clear the WRITE bit */
136 	M48T59_CLEAR_BITS(M48T59_CNTL_WRITE, M48T59_CNTL);
137 	spin_unlock_irqrestore(&m48t59->lock, flags);
138 	return 0;
139 }
140 
141 /*
142  * Read alarm time and date in RTC
143  */
144 static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
145 {
146 	struct platform_device *pdev = to_platform_device(dev);
147 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
148 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
149 	struct rtc_time *tm = &alrm->time;
150 	unsigned long flags;
151 	u8 val;
152 
153 	/* If no irq, we don't support ALARM */
154 	if (m48t59->irq == NO_IRQ)
155 		return -EIO;
156 
157 	spin_lock_irqsave(&m48t59->lock, flags);
158 	/* Issue the READ command */
159 	M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL);
160 
161 	tm->tm_year = BCD2BIN(M48T59_READ(M48T59_YEAR));
162 	/* tm_mon is 0-11 */
163 	tm->tm_mon = BCD2BIN(M48T59_READ(M48T59_MONTH)) - 1;
164 
165 	val = M48T59_READ(M48T59_WDAY);
166 	if ((val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB))
167 		tm->tm_year += 100;	/* one century */
168 
169 	tm->tm_mday = BCD2BIN(M48T59_READ(M48T59_ALARM_DATE));
170 	tm->tm_hour = BCD2BIN(M48T59_READ(M48T59_ALARM_HOUR));
171 	tm->tm_min = BCD2BIN(M48T59_READ(M48T59_ALARM_MIN));
172 	tm->tm_sec = BCD2BIN(M48T59_READ(M48T59_ALARM_SEC));
173 
174 	/* Clear the READ bit */
175 	M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
176 	spin_unlock_irqrestore(&m48t59->lock, flags);
177 
178 	dev_dbg(dev, "RTC read alarm time %04d-%02d-%02d %02d/%02d/%02d\n",
179 		tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
180 		tm->tm_hour, tm->tm_min, tm->tm_sec);
181 	return 0;
182 }
183 
184 /*
185  * Set alarm time and date in RTC
186  */
187 static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
188 {
189 	struct platform_device *pdev = to_platform_device(dev);
190 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
191 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
192 	struct rtc_time *tm = &alrm->time;
193 	u8 mday, hour, min, sec;
194 	unsigned long flags;
195 
196 	/* If no irq, we don't support ALARM */
197 	if (m48t59->irq == NO_IRQ)
198 		return -EIO;
199 
200 	/*
201 	 * 0xff means "always match"
202 	 */
203 	mday = tm->tm_mday;
204 	mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff;
205 	if (mday == 0xff)
206 		mday = M48T59_READ(M48T59_MDAY);
207 
208 	hour = tm->tm_hour;
209 	hour = (hour < 24) ? BIN2BCD(hour) : 0x00;
210 
211 	min = tm->tm_min;
212 	min = (min < 60) ? BIN2BCD(min) : 0x00;
213 
214 	sec = tm->tm_sec;
215 	sec = (sec < 60) ? BIN2BCD(sec) : 0x00;
216 
217 	spin_lock_irqsave(&m48t59->lock, flags);
218 	/* Issue the WRITE command */
219 	M48T59_SET_BITS(M48T59_CNTL_WRITE, M48T59_CNTL);
220 
221 	M48T59_WRITE(mday, M48T59_ALARM_DATE);
222 	M48T59_WRITE(hour, M48T59_ALARM_HOUR);
223 	M48T59_WRITE(min, M48T59_ALARM_MIN);
224 	M48T59_WRITE(sec, M48T59_ALARM_SEC);
225 
226 	/* Clear the WRITE bit */
227 	M48T59_CLEAR_BITS(M48T59_CNTL_WRITE, M48T59_CNTL);
228 	spin_unlock_irqrestore(&m48t59->lock, flags);
229 
230 	dev_dbg(dev, "RTC set alarm time %04d-%02d-%02d %02d/%02d/%02d\n",
231 		tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
232 		tm->tm_hour, tm->tm_min, tm->tm_sec);
233 	return 0;
234 }
235 
236 /*
237  * Handle commands from user-space
238  */
239 static int m48t59_rtc_ioctl(struct device *dev, unsigned int cmd,
240 			unsigned long arg)
241 {
242 	struct platform_device *pdev = to_platform_device(dev);
243 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
244 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
245 	unsigned long flags;
246 	int ret = 0;
247 
248 	spin_lock_irqsave(&m48t59->lock, flags);
249 	switch (cmd) {
250 	case RTC_AIE_OFF:	/* alarm interrupt off */
251 		M48T59_WRITE(0x00, M48T59_INTR);
252 		break;
253 	case RTC_AIE_ON:	/* alarm interrupt on */
254 		M48T59_WRITE(M48T59_INTR_AFE, M48T59_INTR);
255 		break;
256 	default:
257 		ret = -ENOIOCTLCMD;
258 		break;
259 	}
260 	spin_unlock_irqrestore(&m48t59->lock, flags);
261 
262 	return ret;
263 }
264 
265 static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq)
266 {
267 	struct platform_device *pdev = to_platform_device(dev);
268 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
269 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
270 	unsigned long flags;
271 	u8 val;
272 
273 	spin_lock_irqsave(&m48t59->lock, flags);
274 	val = M48T59_READ(M48T59_FLAGS);
275 	spin_unlock_irqrestore(&m48t59->lock, flags);
276 
277 	seq_printf(seq, "battery\t\t: %s\n",
278 		 (val & M48T59_FLAGS_BF) ? "low" : "normal");
279 	return 0;
280 }
281 
282 /*
283  * IRQ handler for the RTC
284  */
285 static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id)
286 {
287 	struct device *dev = (struct device *)dev_id;
288 	struct platform_device *pdev = to_platform_device(dev);
289 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
290 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
291 	u8 event;
292 
293 	spin_lock(&m48t59->lock);
294 	event = M48T59_READ(M48T59_FLAGS);
295 	spin_unlock(&m48t59->lock);
296 
297 	if (event & M48T59_FLAGS_AF) {
298 		rtc_update_irq(m48t59->rtc, 1, (RTC_AF | RTC_IRQF));
299 		return IRQ_HANDLED;
300 	}
301 
302 	return IRQ_NONE;
303 }
304 
305 static const struct rtc_class_ops m48t59_rtc_ops = {
306 	.ioctl		= m48t59_rtc_ioctl,
307 	.read_time	= m48t59_rtc_read_time,
308 	.set_time	= m48t59_rtc_set_time,
309 	.read_alarm	= m48t59_rtc_readalarm,
310 	.set_alarm	= m48t59_rtc_setalarm,
311 	.proc		= m48t59_rtc_proc,
312 };
313 
314 static const struct rtc_class_ops m48t02_rtc_ops = {
315 	.read_time	= m48t59_rtc_read_time,
316 	.set_time	= m48t59_rtc_set_time,
317 };
318 
319 static ssize_t m48t59_nvram_read(struct kobject *kobj,
320 				struct bin_attribute *bin_attr,
321 				char *buf, loff_t pos, size_t size)
322 {
323 	struct device *dev = container_of(kobj, struct device, kobj);
324 	struct platform_device *pdev = to_platform_device(dev);
325 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
326 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
327 	ssize_t cnt = 0;
328 	unsigned long flags;
329 
330 	for (; size > 0 && pos < pdata->offset; cnt++, size--) {
331 		spin_lock_irqsave(&m48t59->lock, flags);
332 		*buf++ = M48T59_READ(cnt);
333 		spin_unlock_irqrestore(&m48t59->lock, flags);
334 	}
335 
336 	return cnt;
337 }
338 
339 static ssize_t m48t59_nvram_write(struct kobject *kobj,
340 				struct bin_attribute *bin_attr,
341 				char *buf, loff_t pos, size_t size)
342 {
343 	struct device *dev = container_of(kobj, struct device, kobj);
344 	struct platform_device *pdev = to_platform_device(dev);
345 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
346 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
347 	ssize_t cnt = 0;
348 	unsigned long flags;
349 
350 	for (; size > 0 && pos < pdata->offset; cnt++, size--) {
351 		spin_lock_irqsave(&m48t59->lock, flags);
352 		M48T59_WRITE(*buf++, cnt);
353 		spin_unlock_irqrestore(&m48t59->lock, flags);
354 	}
355 
356 	return cnt;
357 }
358 
359 static struct bin_attribute m48t59_nvram_attr = {
360 	.attr = {
361 		.name = "nvram",
362 		.mode = S_IRUGO | S_IWUSR,
363 		.owner = THIS_MODULE,
364 	},
365 	.read = m48t59_nvram_read,
366 	.write = m48t59_nvram_write,
367 };
368 
369 static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
370 {
371 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
372 	struct m48t59_private *m48t59 = NULL;
373 	struct resource *res;
374 	int ret = -ENOMEM;
375 	char *name;
376 	const struct rtc_class_ops *ops;
377 
378 	/* This chip could be memory-mapped or I/O-mapped */
379 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
380 	if (!res) {
381 		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
382 		if (!res)
383 			return -EINVAL;
384 	}
385 
386 	if (res->flags & IORESOURCE_IO) {
387 		/* If we are I/O-mapped, the platform should provide
388 		 * the operations accessing chip registers.
389 		 */
390 		if (!pdata || !pdata->write_byte || !pdata->read_byte)
391 			return -EINVAL;
392 	} else if (res->flags & IORESOURCE_MEM) {
393 		/* we are memory-mapped */
394 		if (!pdata) {
395 			pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
396 			if (!pdata)
397 				return -ENOMEM;
398 			/* Ensure we only kmalloc platform data once */
399 			pdev->dev.platform_data = pdata;
400 		}
401 		if (!pdata->type)
402 			pdata->type = M48T59RTC_TYPE_M48T59;
403 
404 		/* Try to use the generic memory read/write ops */
405 		if (!pdata->write_byte)
406 			pdata->write_byte = m48t59_mem_writeb;
407 		if (!pdata->read_byte)
408 			pdata->read_byte = m48t59_mem_readb;
409 	}
410 
411 	m48t59 = kzalloc(sizeof(*m48t59), GFP_KERNEL);
412 	if (!m48t59)
413 		return -ENOMEM;
414 
415 	m48t59->ioaddr = pdata->ioaddr;
416 
417 	if (!m48t59->ioaddr) {
418 		/* ioaddr not mapped externally */
419 		m48t59->ioaddr = ioremap(res->start, res->end - res->start + 1);
420 		if (!m48t59->ioaddr)
421 			goto out;
422 	}
423 
424 	/* Try to get irq number. We also can work in
425 	 * the mode without IRQ.
426 	 */
427 	m48t59->irq = platform_get_irq(pdev, 0);
428 	if (m48t59->irq < 0)
429 		m48t59->irq = NO_IRQ;
430 
431 	if (m48t59->irq != NO_IRQ) {
432 		ret = request_irq(m48t59->irq, m48t59_rtc_interrupt,
433 			IRQF_SHARED, "rtc-m48t59", &pdev->dev);
434 		if (ret)
435 			goto out;
436 	}
437 	switch (pdata->type) {
438 	case M48T59RTC_TYPE_M48T59:
439 		name = "m48t59";
440 		ops = &m48t59_rtc_ops;
441 		pdata->offset = 0x1ff0;
442 		break;
443 	case M48T59RTC_TYPE_M48T02:
444 		name = "m48t02";
445 		ops = &m48t02_rtc_ops;
446 		pdata->offset = 0x7f0;
447 		break;
448 	case M48T59RTC_TYPE_M48T08:
449 		name = "m48t08";
450 		ops = &m48t02_rtc_ops;
451 		pdata->offset = 0x1ff0;
452 		break;
453 	default:
454 		dev_err(&pdev->dev, "Unknown RTC type\n");
455 		ret = -ENODEV;
456 		goto out;
457 	}
458 
459 	m48t59->rtc = rtc_device_register(name, &pdev->dev, ops, THIS_MODULE);
460 	if (IS_ERR(m48t59->rtc)) {
461 		ret = PTR_ERR(m48t59->rtc);
462 		goto out;
463 	}
464 
465 	m48t59_nvram_attr.size = pdata->offset;
466 
467 	ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
468 	if (ret)
469 		goto out;
470 
471 	spin_lock_init(&m48t59->lock);
472 	platform_set_drvdata(pdev, m48t59);
473 	return 0;
474 
475 out:
476 	if (!IS_ERR(m48t59->rtc))
477 		rtc_device_unregister(m48t59->rtc);
478 	if (m48t59->irq != NO_IRQ)
479 		free_irq(m48t59->irq, &pdev->dev);
480 	if (m48t59->ioaddr)
481 		iounmap(m48t59->ioaddr);
482 	if (m48t59)
483 		kfree(m48t59);
484 	return ret;
485 }
486 
487 static int __devexit m48t59_rtc_remove(struct platform_device *pdev)
488 {
489 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
490 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
491 
492 	sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
493 	if (!IS_ERR(m48t59->rtc))
494 		rtc_device_unregister(m48t59->rtc);
495 	if (m48t59->ioaddr && !pdata->ioaddr)
496 		iounmap(m48t59->ioaddr);
497 	if (m48t59->irq != NO_IRQ)
498 		free_irq(m48t59->irq, &pdev->dev);
499 	platform_set_drvdata(pdev, NULL);
500 	kfree(m48t59);
501 	return 0;
502 }
503 
504 /* work with hotplug and coldplug */
505 MODULE_ALIAS("platform:rtc-m48t59");
506 
507 static struct platform_driver m48t59_rtc_driver = {
508 	.driver		= {
509 		.name	= "rtc-m48t59",
510 		.owner	= THIS_MODULE,
511 	},
512 	.probe		= m48t59_rtc_probe,
513 	.remove		= __devexit_p(m48t59_rtc_remove),
514 };
515 
516 static int __init m48t59_rtc_init(void)
517 {
518 	return platform_driver_register(&m48t59_rtc_driver);
519 }
520 
521 static void __exit m48t59_rtc_exit(void)
522 {
523 	platform_driver_unregister(&m48t59_rtc_driver);
524 }
525 
526 module_init(m48t59_rtc_init);
527 module_exit(m48t59_rtc_exit);
528 
529 MODULE_AUTHOR("Mark Zhan <rongkai.zhan@windriver.com>");
530 MODULE_DESCRIPTION("M48T59/M48T02/M48T08 RTC driver");
531 MODULE_LICENSE("GPL");
532