xref: /openbmc/linux/drivers/rtc/rtc-ds1302.c (revision a09d2831)
1 /*
2  * Dallas DS1302 RTC Support
3  *
4  *  Copyright (C) 2002 David McCullough
5  *  Copyright (C) 2003 - 2007 Paul Mundt
6  *
7  * This file is subject to the terms and conditions of the GNU General Public
8  * License version 2. See the file "COPYING" in the main directory of
9  * this archive for more details.
10  */
11 
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/platform_device.h>
16 #include <linux/rtc.h>
17 #include <linux/io.h>
18 #include <linux/bcd.h>
19 #include <asm/rtc.h>
20 
21 #define DRV_NAME	"rtc-ds1302"
22 #define DRV_VERSION	"0.1.1"
23 
24 #define	RTC_CMD_READ	0x81		/* Read command */
25 #define	RTC_CMD_WRITE	0x80		/* Write command */
26 
27 #define RTC_ADDR_RAM0	0x20		/* Address of RAM0 */
28 #define RTC_ADDR_TCR	0x08		/* Address of trickle charge register */
29 #define	RTC_ADDR_YEAR	0x06		/* Address of year register */
30 #define	RTC_ADDR_DAY	0x05		/* Address of day of week register */
31 #define	RTC_ADDR_MON	0x04		/* Address of month register */
32 #define	RTC_ADDR_DATE	0x03		/* Address of day of month register */
33 #define	RTC_ADDR_HOUR	0x02		/* Address of hour register */
34 #define	RTC_ADDR_MIN	0x01		/* Address of minute register */
35 #define	RTC_ADDR_SEC	0x00		/* Address of second register */
36 
37 #define	RTC_RESET	0x1000
38 #define	RTC_IODATA	0x0800
39 #define	RTC_SCLK	0x0400
40 
41 #ifdef CONFIG_SH_SECUREEDGE5410
42 #include <mach/snapgear.h>
43 #define set_dp(x)	SECUREEDGE_WRITE_IOPORT(x, 0x1c00)
44 #define get_dp()	SECUREEDGE_READ_IOPORT()
45 #else
46 #error "Add support for your platform"
47 #endif
48 
49 static void ds1302_sendbits(unsigned int val)
50 {
51 	int i;
52 
53 	for (i = 8; (i); i--, val >>= 1) {
54 		set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ?
55 			RTC_IODATA : 0));
56 		set_dp(get_dp() | RTC_SCLK);	/* clock high */
57 		set_dp(get_dp() & ~RTC_SCLK);	/* clock low */
58 	}
59 }
60 
61 static unsigned int ds1302_recvbits(void)
62 {
63 	unsigned int val;
64 	int i;
65 
66 	for (i = 0, val = 0; (i < 8); i++) {
67 		val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i);
68 		set_dp(get_dp() | RTC_SCLK);	/* clock high */
69 		set_dp(get_dp() & ~RTC_SCLK);	/* clock low */
70 	}
71 
72 	return val;
73 }
74 
75 static unsigned int ds1302_readbyte(unsigned int addr)
76 {
77 	unsigned int val;
78 
79 	set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
80 
81 	set_dp(get_dp() | RTC_RESET);
82 	ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ);
83 	val = ds1302_recvbits();
84 	set_dp(get_dp() & ~RTC_RESET);
85 
86 	return val;
87 }
88 
89 static void ds1302_writebyte(unsigned int addr, unsigned int val)
90 {
91 	set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
92 	set_dp(get_dp() | RTC_RESET);
93 	ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE);
94 	ds1302_sendbits(val);
95 	set_dp(get_dp() & ~RTC_RESET);
96 }
97 
98 static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
99 {
100 	tm->tm_sec	= bcd2bin(ds1302_readbyte(RTC_ADDR_SEC));
101 	tm->tm_min	= bcd2bin(ds1302_readbyte(RTC_ADDR_MIN));
102 	tm->tm_hour	= bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR));
103 	tm->tm_wday	= bcd2bin(ds1302_readbyte(RTC_ADDR_DAY));
104 	tm->tm_mday	= bcd2bin(ds1302_readbyte(RTC_ADDR_DATE));
105 	tm->tm_mon	= bcd2bin(ds1302_readbyte(RTC_ADDR_MON)) - 1;
106 	tm->tm_year	= bcd2bin(ds1302_readbyte(RTC_ADDR_YEAR));
107 
108 	if (tm->tm_year < 70)
109 		tm->tm_year += 100;
110 
111 	dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
112 		"mday=%d, mon=%d, year=%d, wday=%d\n",
113 		__func__,
114 		tm->tm_sec, tm->tm_min, tm->tm_hour,
115 		tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
116 
117 	return rtc_valid_tm(tm);
118 }
119 
120 static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
121 {
122 	/* Stop RTC */
123 	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
124 
125 	ds1302_writebyte(RTC_ADDR_SEC, bin2bcd(tm->tm_sec));
126 	ds1302_writebyte(RTC_ADDR_MIN, bin2bcd(tm->tm_min));
127 	ds1302_writebyte(RTC_ADDR_HOUR, bin2bcd(tm->tm_hour));
128 	ds1302_writebyte(RTC_ADDR_DAY, bin2bcd(tm->tm_wday));
129 	ds1302_writebyte(RTC_ADDR_DATE, bin2bcd(tm->tm_mday));
130 	ds1302_writebyte(RTC_ADDR_MON, bin2bcd(tm->tm_mon + 1));
131 	ds1302_writebyte(RTC_ADDR_YEAR, bin2bcd(tm->tm_year % 100));
132 
133 	/* Start RTC */
134 	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
135 
136 	return 0;
137 }
138 
139 static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd,
140 			    unsigned long arg)
141 {
142 	switch (cmd) {
143 #ifdef RTC_SET_CHARGE
144 	case RTC_SET_CHARGE:
145 	{
146 		int tcs_val;
147 
148 		if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)))
149 			return -EFAULT;
150 
151 		ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf));
152 		return 0;
153 	}
154 #endif
155 	}
156 
157 	return -ENOIOCTLCMD;
158 }
159 
160 static struct rtc_class_ops ds1302_rtc_ops = {
161 	.read_time	= ds1302_rtc_read_time,
162 	.set_time	= ds1302_rtc_set_time,
163 	.ioctl		= ds1302_rtc_ioctl,
164 };
165 
166 static int __init ds1302_rtc_probe(struct platform_device *pdev)
167 {
168 	struct rtc_device *rtc;
169 
170 	/* Reset */
171 	set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
172 
173 	/* Write a magic value to the DS1302 RAM, and see if it sticks. */
174 	ds1302_writebyte(RTC_ADDR_RAM0, 0x42);
175 	if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42)
176 		return -ENODEV;
177 
178 	rtc = rtc_device_register("ds1302", &pdev->dev,
179 					   &ds1302_rtc_ops, THIS_MODULE);
180 	if (IS_ERR(rtc))
181 		return PTR_ERR(rtc);
182 
183 	platform_set_drvdata(pdev, rtc);
184 
185 	return 0;
186 }
187 
188 static int __devexit ds1302_rtc_remove(struct platform_device *pdev)
189 {
190 	struct rtc_device *rtc = platform_get_drvdata(pdev);
191 
192 	rtc_device_unregister(rtc);
193 	platform_set_drvdata(pdev, NULL);
194 
195 	return 0;
196 }
197 
198 static struct platform_driver ds1302_platform_driver = {
199 	.driver		= {
200 		.name	= DRV_NAME,
201 		.owner	= THIS_MODULE,
202 	},
203 	.remove		= __devexit_p(ds1302_rtc_remove),
204 };
205 
206 static int __init ds1302_rtc_init(void)
207 {
208 	return platform_driver_probe(&ds1302_platform_driver, ds1302_rtc_probe);
209 }
210 
211 static void __exit ds1302_rtc_exit(void)
212 {
213 	platform_driver_unregister(&ds1302_platform_driver);
214 }
215 
216 module_init(ds1302_rtc_init);
217 module_exit(ds1302_rtc_exit);
218 
219 MODULE_DESCRIPTION("Dallas DS1302 RTC driver");
220 MODULE_VERSION(DRV_VERSION);
221 MODULE_AUTHOR("Paul Mundt, David McCullough");
222 MODULE_LICENSE("GPL v2");
223