2 * drivers/rtc/rtc-pcf8583.c
4 * Copyright (C) 2000 Russell King
5 * Copyright (C) 2008 Wolfram Sang & Juergen Beisert, Pengutronix
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Driver for PCF8583 RTC & RAM chip
13 * Converted to the generic RTC susbsystem by G. Liakhovetski (2006)
15 #include <linux/module.h>
16 #include <linux/i2c.h>
17 #include <linux/slab.h>
18 #include <linux/rtc.h>
19 #include <linux/init.h>
20 #include <linux/errno.h>
21 #include <linux/bcd.h>
30 struct rtc_device
*rtc
;
34 #define CTRL_STOP 0x80
35 #define CTRL_HOLD 0x40
36 #define CTRL_32KHZ 0x00
37 #define CTRL_MASK 0x08
38 #define CTRL_ALARMEN 0x04
39 #define CTRL_ALARM 0x02
40 #define CTRL_TIMER 0x01
43 static struct i2c_driver pcf8583_driver
;
45 #define get_ctrl(x) ((struct pcf8583 *)i2c_get_clientdata(x))->ctrl
46 #define set_ctrl(x, v) get_ctrl(x) = v
48 #define CMOS_YEAR (64 + 128)
49 #define CMOS_CHECKSUM (63)
51 static int pcf8583_get_datetime(struct i2c_client
*client
, struct rtc_time
*dt
)
53 unsigned char buf
[8], addr
[1] = { 1 };
54 struct i2c_msg msgs
[2] = {
69 memset(buf
, 0, sizeof(buf
));
71 ret
= i2c_transfer(client
->adapter
, msgs
, 2);
73 dt
->tm_year
= buf
[4] >> 6;
74 dt
->tm_wday
= buf
[5] >> 5;
79 dt
->tm_sec
= bcd2bin(buf
[1]);
80 dt
->tm_min
= bcd2bin(buf
[2]);
81 dt
->tm_hour
= bcd2bin(buf
[3]);
82 dt
->tm_mday
= bcd2bin(buf
[4]);
83 dt
->tm_mon
= bcd2bin(buf
[5]) - 1;
86 return ret
== 2 ? 0 : -EIO
;
89 static int pcf8583_set_datetime(struct i2c_client
*client
, struct rtc_time
*dt
, int datetoo
)
95 buf
[1] = get_ctrl(client
) | 0x80;
97 buf
[3] = bin2bcd(dt
->tm_sec
);
98 buf
[4] = bin2bcd(dt
->tm_min
);
99 buf
[5] = bin2bcd(dt
->tm_hour
);
103 buf
[6] = bin2bcd(dt
->tm_mday
) | (dt
->tm_year
<< 6);
104 buf
[7] = bin2bcd(dt
->tm_mon
+ 1) | (dt
->tm_wday
<< 5);
107 ret
= i2c_master_send(client
, (char *)buf
, len
);
111 buf
[1] = get_ctrl(client
);
112 ret
= i2c_master_send(client
, (char *)buf
, 2);
114 return ret
== 2 ? 0 : -EIO
;
117 static int pcf8583_get_ctrl(struct i2c_client
*client
, unsigned char *ctrl
)
119 *ctrl
= get_ctrl(client
);
123 static int pcf8583_set_ctrl(struct i2c_client
*client
, unsigned char *ctrl
)
125 unsigned char buf
[2];
129 set_ctrl(client
, *ctrl
);
131 return i2c_master_send(client
, (char *)buf
, 2);
134 static int pcf8583_read_mem(struct i2c_client
*client
, struct rtc_mem
*mem
)
136 unsigned char addr
[1];
137 struct i2c_msg msgs
[2] = {
139 .addr
= client
->addr
,
144 .addr
= client
->addr
,
156 return i2c_transfer(client
->adapter
, msgs
, 2) == 2 ? 0 : -EIO
;
159 static int pcf8583_write_mem(struct i2c_client
*client
, struct rtc_mem
*mem
)
161 unsigned char buf
[9];
164 if (mem
->loc
< 8 || mem
->nr
> 8)
168 memcpy(buf
+ 1, mem
->data
, mem
->nr
);
170 ret
= i2c_master_send(client
, buf
, mem
->nr
+ 1);
171 return ret
== mem
->nr
+ 1 ? 0 : -EIO
;
174 static int pcf8583_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
176 struct i2c_client
*client
= to_i2c_client(dev
);
177 unsigned char ctrl
, year
[2];
178 struct rtc_mem mem
= { CMOS_YEAR
, sizeof(year
), year
};
179 int real_year
, year_offset
, err
;
182 * Ensure that the RTC is running.
184 pcf8583_get_ctrl(client
, &ctrl
);
185 if (ctrl
& (CTRL_STOP
| CTRL_HOLD
)) {
186 unsigned char new_ctrl
= ctrl
& ~(CTRL_STOP
| CTRL_HOLD
);
188 printk(KERN_WARNING
"RTC: resetting control %02x -> %02x\n",
191 if ((err
= pcf8583_set_ctrl(client
, &new_ctrl
)) < 0)
195 if (pcf8583_get_datetime(client
, tm
) ||
196 pcf8583_read_mem(client
, &mem
))
202 * The RTC year holds the LSB two bits of the current
203 * year, which should reflect the LSB two bits of the
204 * CMOS copy of the year. Any difference indicates
205 * that we have to correct the CMOS version.
207 year_offset
= tm
->tm_year
- (real_year
& 3);
210 * RTC year wrapped. Adjust it appropriately.
214 tm
->tm_year
= (real_year
+ year_offset
+ year
[1] * 100) - 1900;
219 static int pcf8583_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
221 struct i2c_client
*client
= to_i2c_client(dev
);
222 unsigned char year
[2], chk
;
223 struct rtc_mem cmos_year
= { CMOS_YEAR
, sizeof(year
), year
};
224 struct rtc_mem cmos_check
= { CMOS_CHECKSUM
, 1, &chk
};
225 unsigned int proper_year
= tm
->tm_year
+ 1900;
229 * The RTC's own 2-bit year must reflect the least
230 * significant two bits of the CMOS year.
233 ret
= pcf8583_set_datetime(client
, tm
, 1);
237 ret
= pcf8583_read_mem(client
, &cmos_check
);
241 ret
= pcf8583_read_mem(client
, &cmos_year
);
245 chk
-= year
[1] + year
[0];
247 year
[1] = proper_year
/ 100;
248 year
[0] = proper_year
% 100;
250 chk
+= year
[1] + year
[0];
252 ret
= pcf8583_write_mem(client
, &cmos_year
);
257 ret
= pcf8583_write_mem(client
, &cmos_check
);
262 static const struct rtc_class_ops pcf8583_rtc_ops
= {
263 .read_time
= pcf8583_rtc_read_time
,
264 .set_time
= pcf8583_rtc_set_time
,
267 static int pcf8583_probe(struct i2c_client
*client
,
268 const struct i2c_device_id
*id
)
270 struct pcf8583
*pcf8583
;
273 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
))
276 pcf8583
= kzalloc(sizeof(struct pcf8583
), GFP_KERNEL
);
280 i2c_set_clientdata(client
, pcf8583
);
282 pcf8583
->rtc
= rtc_device_register(pcf8583_driver
.driver
.name
,
283 &client
->dev
, &pcf8583_rtc_ops
, THIS_MODULE
);
285 if (IS_ERR(pcf8583
->rtc
)) {
286 err
= PTR_ERR(pcf8583
->rtc
);
297 static int __devexit
pcf8583_remove(struct i2c_client
*client
)
299 struct pcf8583
*pcf8583
= i2c_get_clientdata(client
);
302 rtc_device_unregister(pcf8583
->rtc
);
307 static const struct i2c_device_id pcf8583_id
[] = {
311 MODULE_DEVICE_TABLE(i2c
, pcf8583_id
);
313 static struct i2c_driver pcf8583_driver
= {
316 .owner
= THIS_MODULE
,
318 .probe
= pcf8583_probe
,
319 .remove
= __devexit_p(pcf8583_remove
),
320 .id_table
= pcf8583_id
,
323 static __init
int pcf8583_init(void)
325 return i2c_add_driver(&pcf8583_driver
);
328 static __exit
void pcf8583_exit(void)
330 i2c_del_driver(&pcf8583_driver
);
333 module_init(pcf8583_init
);
334 module_exit(pcf8583_exit
);
336 MODULE_AUTHOR("Russell King");
337 MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
338 MODULE_LICENSE("GPL");