2 * An rtc/i2c driver for the Dallas DS1672
3 * Copyright 2005 Alessandro Zummo
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 #include <linux/module.h>
11 #include <linux/i2c.h>
12 #include <linux/rtc.h>
14 #define DRV_VERSION "0.2"
16 /* Addresses to scan: none. This chip cannot be detected. */
17 static unsigned short normal_i2c
[] = { I2C_CLIENT_END
};
19 /* Insmod parameters */
24 #define DS1672_REG_CNT_BASE 0
25 #define DS1672_REG_CONTROL 4
26 #define DS1672_REG_TRICKLE 5
30 static int ds1672_probe(struct i2c_adapter
*adapter
, int address
, int kind
);
33 * In the routines that deal directly with the ds1672 hardware, we use
34 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
35 * Epoch is initialized as 2000. Time is set to UTC.
37 static int ds1672_get_datetime(struct i2c_client
*client
, struct rtc_time
*tm
)
40 unsigned char addr
= DS1672_REG_CNT_BASE
;
43 struct i2c_msg msgs
[] = {
44 { client
->addr
, 0, 1, &addr
}, /* setup read ptr */
45 { client
->addr
, I2C_M_RD
, 4, buf
}, /* read date */
48 /* read date registers */
49 if ((i2c_transfer(client
->adapter
, &msgs
[0], 2)) != 2) {
50 dev_err(&client
->dev
, "%s: read error\n", __FUNCTION__
);
55 "%s: raw read data - counters=%02x,%02x,%02x,%02x\n"
57 buf
[0], buf
[1], buf
[2], buf
[3]);
59 time
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
61 rtc_time_to_tm(time
, tm
);
63 dev_dbg(&client
->dev
, "%s: tm is secs=%d, mins=%d, hours=%d, "
64 "mday=%d, mon=%d, year=%d, wday=%d\n",
66 tm
->tm_sec
, tm
->tm_min
, tm
->tm_hour
,
67 tm
->tm_mday
, tm
->tm_mon
, tm
->tm_year
, tm
->tm_wday
);
72 static int ds1672_set_mmss(struct i2c_client
*client
, unsigned long secs
)
77 buf
[0] = DS1672_REG_CNT_BASE
;
78 buf
[1] = secs
& 0x000000FF;
79 buf
[2] = (secs
& 0x0000FF00) >> 8;
80 buf
[3] = (secs
& 0x00FF0000) >> 16;
81 buf
[4] = (secs
& 0xFF000000) >> 24;
83 xfer
= i2c_master_send(client
, buf
, 5);
85 dev_err(&client
->dev
, "%s: send: %d\n", __FUNCTION__
, xfer
);
92 static int ds1672_set_datetime(struct i2c_client
*client
, struct rtc_time
*tm
)
97 "%s: secs=%d, mins=%d, hours=%d, ",
98 "mday=%d, mon=%d, year=%d, wday=%d\n",
100 tm
->tm_sec
, tm
->tm_min
, tm
->tm_hour
,
101 tm
->tm_mday
, tm
->tm_mon
, tm
->tm_year
, tm
->tm_wday
);
103 rtc_tm_to_time(tm
, &secs
);
105 return ds1672_set_mmss(client
, secs
);
108 static int ds1672_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
110 return ds1672_get_datetime(to_i2c_client(dev
), tm
);
113 static int ds1672_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
115 return ds1672_set_datetime(to_i2c_client(dev
), tm
);
118 static int ds1672_rtc_set_mmss(struct device
*dev
, unsigned long secs
)
120 return ds1672_set_mmss(to_i2c_client(dev
), secs
);
123 static struct rtc_class_ops ds1672_rtc_ops
= {
124 .read_time
= ds1672_rtc_read_time
,
125 .set_time
= ds1672_rtc_set_time
,
126 .set_mmss
= ds1672_rtc_set_mmss
,
129 static int ds1672_attach(struct i2c_adapter
*adapter
)
131 dev_dbg(&adapter
->dev
, "%s\n", __FUNCTION__
);
132 return i2c_probe(adapter
, &addr_data
, ds1672_probe
);
135 static int ds1672_detach(struct i2c_client
*client
)
138 struct rtc_device
*rtc
= i2c_get_clientdata(client
);
140 dev_dbg(&client
->dev
, "%s\n", __FUNCTION__
);
143 rtc_device_unregister(rtc
);
145 if ((err
= i2c_detach_client(client
)))
153 static struct i2c_driver ds1672_driver
= {
157 .id
= I2C_DRIVERID_DS1672
,
158 .attach_adapter
= &ds1672_attach
,
159 .detach_client
= &ds1672_detach
,
162 static int ds1672_probe(struct i2c_adapter
*adapter
, int address
, int kind
)
165 struct i2c_client
*client
;
166 struct rtc_device
*rtc
;
168 dev_dbg(&adapter
->dev
, "%s\n", __FUNCTION__
);
170 if (!i2c_check_functionality(adapter
, I2C_FUNC_I2C
)) {
175 if (!(client
= kzalloc(sizeof(struct i2c_client
), GFP_KERNEL
))) {
181 client
->addr
= address
;
182 client
->driver
= &ds1672_driver
;
183 client
->adapter
= adapter
;
185 strlcpy(client
->name
, ds1672_driver
.driver
.name
, I2C_NAME_SIZE
);
187 /* Inform the i2c layer */
188 if ((err
= i2c_attach_client(client
)))
191 dev_info(&client
->dev
, "chip found, driver version " DRV_VERSION
"\n");
193 rtc
= rtc_device_register(ds1672_driver
.driver
.name
, &client
->dev
,
194 &ds1672_rtc_ops
, THIS_MODULE
);
198 dev_err(&client
->dev
,
199 "unable to register the class device\n");
203 i2c_set_clientdata(client
, rtc
);
208 i2c_detach_client(client
);
217 static int __init
ds1672_init(void)
219 return i2c_add_driver(&ds1672_driver
);
222 static void __exit
ds1672_exit(void)
224 i2c_del_driver(&ds1672_driver
);
227 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
228 MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
229 MODULE_LICENSE("GPL");
230 MODULE_VERSION(DRV_VERSION
);
232 module_init(ds1672_init
);
233 module_exit(ds1672_exit
);