1/*
2 * PCF8563 RTC
3 *
4 * From Phillips' datasheet:
5 *
6 * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
7 * consumption. A programmable clock output, interupt output and voltage
8 * low detector are also provided. All address and data are transferred
9 * serially via two-line bidirectional I2C-bus. Maximum bus speed is
10 * 400 kbits/s. The built-in word address register is incremented
11 * automatically after each written or read bute.
12 *
13 * Copyright (c) 2002, Axis Communications AB
14 * All rights reserved.
15 *
16 * Author: Tobias Anderberg <tobiasa@axis.com>.
17 *
18 * $Id: pcf8563.c,v 1.1.1.1 2007/08/03 18:51:41 Exp $
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/types.h>
24#include <linux/sched.h>
25#include <linux/init.h>
26#include <linux/fs.h>
27#include <linux/ioctl.h>
28#include <linux/delay.h>
29#include <linux/bcd.h>
30#include <linux/capability.h>
31
32#include <asm/uaccess.h>
33#include <asm/system.h>
34#include <asm/io.h>
35#include <asm/arch/svinto.h>
36#include <asm/rtc.h>
37#include "i2c.h"
38
39#define PCF8563_MAJOR 121		/* Local major number. */
40#define DEVICE_NAME "rtc"		/* Name which is registered in /proc/devices. */
41#define PCF8563_NAME "PCF8563"
42#define DRIVER_VERSION "$Revision: 1.1.1.1 $"
43
44/* I2C bus slave registers. */
45#define RTC_I2C_READ		0xa3
46#define RTC_I2C_WRITE		0xa2
47
48/* Two simple wrapper macros, saves a few keystrokes. */
49#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
50#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
51
52static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */
53
54static const unsigned char days_in_month[] =
55	{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
56
57int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
58
59static const struct file_operations pcf8563_fops = {
60	.owner = THIS_MODULE,
61	.ioctl = pcf8563_ioctl,
62};
63
64unsigned char
65pcf8563_readreg(int reg)
66{
67	unsigned char res = i2c_readreg(RTC_I2C_READ, reg);
68
69	/* The PCF8563 does not return 0 for unimplemented bits */
70	switch(reg)
71	{
72		case RTC_SECONDS:
73		case RTC_MINUTES:
74		     res &= 0x7f;
75		     break;
76		case RTC_HOURS:
77		case RTC_DAY_OF_MONTH:
78		     res &= 0x3f;
79		     break;
80		case RTC_MONTH:
81		     res = (res & 0x1f) - 1;  /* PCF8563 returns month in range 1-12 */
82		     break;
83	}
84	return res;
85}
86
87void
88pcf8563_writereg(int reg, unsigned char val)
89{
90#ifdef CONFIG_ETRAX_RTC_READONLY
91	if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
92		return;
93#endif
94
95	rtc_write(reg, val);
96}
97
98void
99get_rtc_time(struct rtc_time *tm)
100{
101	tm->tm_sec = rtc_read(RTC_SECONDS);
102	tm->tm_min = rtc_read(RTC_MINUTES);
103	tm->tm_hour = rtc_read(RTC_HOURS);
104	tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
105	tm->tm_mon = rtc_read(RTC_MONTH);
106	tm->tm_year = rtc_read(RTC_YEAR);
107
108	if (tm->tm_sec & 0x80)
109		printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
110
111	tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
112	tm->tm_sec &= 0x7f;
113	tm->tm_min &= 0x7f;
114	tm->tm_hour &= 0x3f;
115	tm->tm_mday &= 0x3f;
116	tm->tm_mon &= 0x1f;
117
118	BCD_TO_BIN(tm->tm_sec);
119	BCD_TO_BIN(tm->tm_min);
120	BCD_TO_BIN(tm->tm_hour);
121	BCD_TO_BIN(tm->tm_mday);
122	BCD_TO_BIN(tm->tm_mon);
123	tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */
124}
125
126int __init
127pcf8563_init(void)
128{
129	int ret;
130
131	if ((ret = i2c_init())) {
132		printk(KERN_CRIT "pcf8563_init: failed to init i2c\n");
133		return ret;
134	}
135
136	/*
137	 * First of all we need to reset the chip. This is done by
138	 * clearing control1, control2 and clk freq, clear the
139	 * Voltage Low bit, and resetting all alarms.
140	 */
141	if (rtc_write(RTC_CONTROL1, 0x00) < 0)
142		goto err;
143
144	if (rtc_write(RTC_CONTROL2, 0x00) < 0)
145		goto err;
146
147	if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
148		goto err;
149
150	/* Clear the VL bit in the seconds register. */
151	ret = rtc_read(RTC_SECONDS);
152
153	if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0)
154		goto err;
155
156	/* Reset the alarms. */
157	if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0)
158		goto err;
159
160	if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0)
161		goto err;
162
163	if (rtc_write(RTC_DAY_ALARM, 0x00) < 0)
164		goto err;
165
166	if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0)
167		goto err;
168
169	/* Check for low voltage, and warn about it.. */
170	if (rtc_read(RTC_SECONDS) & 0x80)
171		printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
172
173	return 0;
174
175err:
176	printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
177	return -1;
178}
179
180void __exit
181pcf8563_exit(void)
182{
183	if (unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME) < 0) {
184		printk(KERN_INFO "%s: Unable to unregister device.\n", PCF8563_NAME);
185	}
186}
187
188/*
189 * ioctl calls for this driver. Why return -ENOTTY upon error? Because
190 * POSIX says so!
191 */
192int
193pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
194{
195	/* Some sanity checks. */
196	if (_IOC_TYPE(cmd) != RTC_MAGIC)
197		return -ENOTTY;
198
199	if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
200		return -ENOTTY;
201
202	switch (cmd) {
203		case RTC_RD_TIME:
204			{
205				struct rtc_time tm;
206
207				spin_lock(&rtc_lock);
208				get_rtc_time(&tm);
209
210				if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
211					spin_unlock(&rtc_lock);
212					return -EFAULT;
213				}
214
215				spin_unlock(&rtc_lock);
216				return 0;
217			}
218			break;
219		case RTC_SET_TIME:
220			{
221#ifdef CONFIG_ETRAX_RTC_READONLY
222				return -EPERM;
223#else
224				int leap;
225				int century;
226				struct rtc_time tm;
227
228				memset(&tm, 0, sizeof (struct rtc_time));
229				if (!capable(CAP_SYS_TIME))
230					return -EPERM;
231
232				if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
233					return -EFAULT;
234
235				/* Convert from struct tm to struct rtc_time. */
236				tm.tm_year += 1900;
237				tm.tm_mon += 1;
238
239				leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0;
240
241				/* Perform some sanity checks. */
242				if ((tm.tm_year < 1970) ||
243				    (tm.tm_mon > 12) ||
244				    (tm.tm_mday == 0) ||
245				    (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
246				    (tm.tm_hour >= 24) ||
247				    (tm.tm_min >= 60) ||
248				    (tm.tm_sec >= 60))
249					return -EINVAL;
250
251				century = (tm.tm_year >= 2000) ? 0x80 : 0;
252				tm.tm_year = tm.tm_year % 100;
253
254				BIN_TO_BCD(tm.tm_year);
255				BIN_TO_BCD(tm.tm_mday);
256				BIN_TO_BCD(tm.tm_hour);
257				BIN_TO_BCD(tm.tm_min);
258				BIN_TO_BCD(tm.tm_sec);
259				tm.tm_mon |= century;
260
261				spin_lock(&rtc_lock);
262
263				rtc_write(RTC_YEAR, tm.tm_year);
264				rtc_write(RTC_MONTH, tm.tm_mon);
265				rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
266				rtc_write(RTC_HOURS, tm.tm_hour);
267				rtc_write(RTC_MINUTES, tm.tm_min);
268				rtc_write(RTC_SECONDS, tm.tm_sec);
269
270				spin_unlock(&rtc_lock);
271
272				return 0;
273#endif /* !CONFIG_ETRAX_RTC_READONLY */
274			}
275
276		case RTC_VLOW_RD:
277		{
278			int vl_bit = 0;
279
280			if (rtc_read(RTC_SECONDS) & 0x80) {
281				vl_bit = 1;
282				printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
283				       "date/time information is no longer guaranteed!\n",
284				       PCF8563_NAME);
285			}
286			if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
287				return -EFAULT;
288
289			return 0;
290		}
291
292		case RTC_VLOW_SET:
293		{
294			/* Clear the VL bit in the seconds register */
295			int ret = rtc_read(RTC_SECONDS);
296
297			rtc_write(RTC_SECONDS, (ret & 0x7F));
298
299			return 0;
300		}
301
302		default:
303				return -ENOTTY;
304	}
305
306	return 0;
307}
308
309static int __init
310pcf8563_register(void)
311{
312	pcf8563_init();
313	if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
314		printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n",
315		       PCF8563_NAME, PCF8563_MAJOR);
316		return -1;
317	}
318
319	printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
320        return 0;
321}
322
323module_init(pcf8563_register);
324module_exit(pcf8563_exit);
325