xref: /linux/drivers/rtc/rtc-m48t59.c (revision 3eeebf17f31c583f83e081b17b3076477cb96886)
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 	},
364 	.read = m48t59_nvram_read,
365 	.write = m48t59_nvram_write,
366 };
367 
368 static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
369 {
370 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
371 	struct m48t59_private *m48t59 = NULL;
372 	struct resource *res;
373 	int ret = -ENOMEM;
374 	char *name;
375 	const struct rtc_class_ops *ops;
376 
377 	/* This chip could be memory-mapped or I/O-mapped */
378 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
379 	if (!res) {
380 		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
381 		if (!res)
382 			return -EINVAL;
383 	}
384 
385 	if (res->flags & IORESOURCE_IO) {
386 		/* If we are I/O-mapped, the platform should provide
387 		 * the operations accessing chip registers.
388 		 */
389 		if (!pdata || !pdata->write_byte || !pdata->read_byte)
390 			return -EINVAL;
391 	} else if (res->flags & IORESOURCE_MEM) {
392 		/* we are memory-mapped */
393 		if (!pdata) {
394 			pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
395 			if (!pdata)
396 				return -ENOMEM;
397 			/* Ensure we only kmalloc platform data once */
398 			pdev->dev.platform_data = pdata;
399 		}
400 		if (!pdata->type)
401 			pdata->type = M48T59RTC_TYPE_M48T59;
402 
403 		/* Try to use the generic memory read/write ops */
404 		if (!pdata->write_byte)
405 			pdata->write_byte = m48t59_mem_writeb;
406 		if (!pdata->read_byte)
407 			pdata->read_byte = m48t59_mem_readb;
408 	}
409 
410 	m48t59 = kzalloc(sizeof(*m48t59), GFP_KERNEL);
411 	if (!m48t59)
412 		return -ENOMEM;
413 
414 	m48t59->ioaddr = pdata->ioaddr;
415 
416 	if (!m48t59->ioaddr) {
417 		/* ioaddr not mapped externally */
418 		m48t59->ioaddr = ioremap(res->start, res->end - res->start + 1);
419 		if (!m48t59->ioaddr)
420 			goto out;
421 	}
422 
423 	/* Try to get irq number. We also can work in
424 	 * the mode without IRQ.
425 	 */
426 	m48t59->irq = platform_get_irq(pdev, 0);
427 	if (m48t59->irq < 0)
428 		m48t59->irq = NO_IRQ;
429 
430 	if (m48t59->irq != NO_IRQ) {
431 		ret = request_irq(m48t59->irq, m48t59_rtc_interrupt,
432 			IRQF_SHARED, "rtc-m48t59", &pdev->dev);
433 		if (ret)
434 			goto out;
435 	}
436 	switch (pdata->type) {
437 	case M48T59RTC_TYPE_M48T59:
438 		name = "m48t59";
439 		ops = &m48t59_rtc_ops;
440 		pdata->offset = 0x1ff0;
441 		break;
442 	case M48T59RTC_TYPE_M48T02:
443 		name = "m48t02";
444 		ops = &m48t02_rtc_ops;
445 		pdata->offset = 0x7f0;
446 		break;
447 	case M48T59RTC_TYPE_M48T08:
448 		name = "m48t08";
449 		ops = &m48t02_rtc_ops;
450 		pdata->offset = 0x1ff0;
451 		break;
452 	default:
453 		dev_err(&pdev->dev, "Unknown RTC type\n");
454 		ret = -ENODEV;
455 		goto out;
456 	}
457 
458 	m48t59->rtc = rtc_device_register(name, &pdev->dev, ops, THIS_MODULE);
459 	if (IS_ERR(m48t59->rtc)) {
460 		ret = PTR_ERR(m48t59->rtc);
461 		goto out;
462 	}
463 
464 	m48t59_nvram_attr.size = pdata->offset;
465 
466 	ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
467 	if (ret)
468 		goto out;
469 
470 	spin_lock_init(&m48t59->lock);
471 	platform_set_drvdata(pdev, m48t59);
472 	return 0;
473 
474 out:
475 	if (!IS_ERR(m48t59->rtc))
476 		rtc_device_unregister(m48t59->rtc);
477 	if (m48t59->irq != NO_IRQ)
478 		free_irq(m48t59->irq, &pdev->dev);
479 	if (m48t59->ioaddr)
480 		iounmap(m48t59->ioaddr);
481 	if (m48t59)
482 		kfree(m48t59);
483 	return ret;
484 }
485 
486 static int __devexit m48t59_rtc_remove(struct platform_device *pdev)
487 {
488 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
489 	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
490 
491 	sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
492 	if (!IS_ERR(m48t59->rtc))
493 		rtc_device_unregister(m48t59->rtc);
494 	if (m48t59->ioaddr && !pdata->ioaddr)
495 		iounmap(m48t59->ioaddr);
496 	if (m48t59->irq != NO_IRQ)
497 		free_irq(m48t59->irq, &pdev->dev);
498 	platform_set_drvdata(pdev, NULL);
499 	kfree(m48t59);
500 	return 0;
501 }
502 
503 /* work with hotplug and coldplug */
504 MODULE_ALIAS("platform:rtc-m48t59");
505 
506 static struct platform_driver m48t59_rtc_driver = {
507 	.driver		= {
508 		.name	= "rtc-m48t59",
509 		.owner	= THIS_MODULE,
510 	},
511 	.probe		= m48t59_rtc_probe,
512 	.remove		= __devexit_p(m48t59_rtc_remove),
513 };
514 
515 static int __init m48t59_rtc_init(void)
516 {
517 	return platform_driver_register(&m48t59_rtc_driver);
518 }
519 
520 static void __exit m48t59_rtc_exit(void)
521 {
522 	platform_driver_unregister(&m48t59_rtc_driver);
523 }
524 
525 module_init(m48t59_rtc_init);
526 module_exit(m48t59_rtc_exit);
527 
528 MODULE_AUTHOR("Mark Zhan <rongkai.zhan@windriver.com>");
529 MODULE_DESCRIPTION("M48T59/M48T02/M48T08 RTC driver");
530 MODULE_LICENSE("GPL");
531