aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/chips/Kconfig18
-rw-r--r--drivers/i2c/chips/Makefile2
-rw-r--r--drivers/i2c/chips/rtc8564.c385
-rw-r--r--drivers/i2c/chips/rtc8564.h78
-rw-r--r--drivers/i2c/chips/x1205.c698
5 files changed, 0 insertions, 1181 deletions
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index f9fae28f5612..7aa5c38f0855 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -65,15 +65,6 @@ config SENSORS_PCF8591
65 This driver can also be built as a module. If so, the module 65 This driver can also be built as a module. If so, the module
66 will be called pcf8591. 66 will be called pcf8591.
67 67
68config SENSORS_RTC8564
69 tristate "Epson 8564 RTC chip"
70 depends on I2C && EXPERIMENTAL
71 help
72 If you say yes here you get support for the Epson 8564 RTC chip.
73
74 This driver can also be built as a module. If so, the module
75 will be called i2c-rtc8564.
76
77config ISP1301_OMAP 68config ISP1301_OMAP
78 tristate "Philips ISP1301 with OMAP OTG" 69 tristate "Philips ISP1301 with OMAP OTG"
79 depends on I2C && ARCH_OMAP_OTG 70 depends on I2C && ARCH_OMAP_OTG
@@ -126,13 +117,4 @@ config SENSORS_MAX6875
126 This driver can also be built as a module. If so, the module 117 This driver can also be built as a module. If so, the module
127 will be called max6875. 118 will be called max6875.
128 119
129config RTC_X1205_I2C
130 tristate "Xicor X1205 RTC chip"
131 depends on I2C && EXPERIMENTAL
132 help
133 If you say yes here you get support for the Xicor X1205 RTC chip.
134
135 This driver can also be built as a module. If so, the module
136 will be called x1205.
137
138endmenu 120endmenu
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 46178b57b1f1..779868ef2e26 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -10,10 +10,8 @@ obj-$(CONFIG_SENSORS_M41T00) += m41t00.o
10obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o 10obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
11obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o 11obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
12obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o 12obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
13obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o
14obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o 13obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
15obj-$(CONFIG_TPS65010) += tps65010.o 14obj-$(CONFIG_TPS65010) += tps65010.o
16obj-$(CONFIG_RTC_X1205_I2C) += x1205.o
17 15
18ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) 16ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
19EXTRA_CFLAGS += -DDEBUG 17EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c
deleted file mode 100644
index 0d8699b3f488..000000000000
--- a/drivers/i2c/chips/rtc8564.c
+++ /dev/null
@@ -1,385 +0,0 @@
1/*
2 * linux/drivers/i2c/chips/rtc8564.c
3 *
4 * Copyright (C) 2002-2004 Stefan Eletzhofer
5 *
6 * based on linux/drivers/acron/char/pcf8583.c
7 * Copyright (C) 2000 Russell King
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * Driver for system3's EPSON RTC 8564 chip
14 */
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/bcd.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20#include <linux/string.h>
21#include <linux/rtc.h> /* get the user-level API */
22#include <linux/init.h>
23
24#include "rtc8564.h"
25
26#ifdef DEBUG
27# define _DBG(x, fmt, args...) do{ if (debug>=x) printk(KERN_DEBUG"%s: " fmt "\n", __FUNCTION__, ##args); } while(0);
28#else
29# define _DBG(x, fmt, args...) do { } while(0);
30#endif
31
32#define _DBGRTCTM(x, rtctm) if (debug>=x) printk("%s: secs=%d, mins=%d, hours=%d, mday=%d, " \
33 "mon=%d, year=%d, wday=%d VL=%d\n", __FUNCTION__, \
34 (rtctm).secs, (rtctm).mins, (rtctm).hours, (rtctm).mday, \
35 (rtctm).mon, (rtctm).year, (rtctm).wday, (rtctm).vl);
36
37struct rtc8564_data {
38 struct i2c_client client;
39 u16 ctrl;
40};
41
42static inline u8 _rtc8564_ctrl1(struct i2c_client *client)
43{
44 struct rtc8564_data *data = i2c_get_clientdata(client);
45 return data->ctrl & 0xff;
46}
47static inline u8 _rtc8564_ctrl2(struct i2c_client *client)
48{
49 struct rtc8564_data *data = i2c_get_clientdata(client);
50 return (data->ctrl & 0xff00) >> 8;
51}
52
53#define CTRL1(c) _rtc8564_ctrl1(c)
54#define CTRL2(c) _rtc8564_ctrl2(c)
55
56static int debug;
57module_param(debug, int, S_IRUGO | S_IWUSR);
58
59static struct i2c_driver rtc8564_driver;
60
61static unsigned short ignore[] = { I2C_CLIENT_END };
62static unsigned short normal_addr[] = { 0x51, I2C_CLIENT_END };
63
64static struct i2c_client_address_data addr_data = {
65 .normal_i2c = normal_addr,
66 .probe = ignore,
67 .ignore = ignore,
68};
69
70static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem);
71static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem);
72
73static int rtc8564_read(struct i2c_client *client, unsigned char adr,
74 unsigned char *buf, unsigned char len)
75{
76 int ret = -EIO;
77 unsigned char addr[1] = { adr };
78 struct i2c_msg msgs[2] = {
79 {client->addr, 0, 1, addr},
80 {client->addr, I2C_M_RD, len, buf}
81 };
82
83 _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, buf, len);
84
85 if (!buf) {
86 ret = -EINVAL;
87 goto done;
88 }
89
90 ret = i2c_transfer(client->adapter, msgs, 2);
91 if (ret == 2) {
92 ret = 0;
93 }
94
95done:
96 return ret;
97}
98
99static int rtc8564_write(struct i2c_client *client, unsigned char adr,
100 unsigned char *data, unsigned char len)
101{
102 int ret = 0;
103 unsigned char _data[16];
104 struct i2c_msg wr;
105 int i;
106
107 if (!data || len > 15) {
108 ret = -EINVAL;
109 goto done;
110 }
111
112 _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, data, len);
113
114 _data[0] = adr;
115 for (i = 0; i < len; i++) {
116 _data[i + 1] = data[i];
117 _DBG(5, "data[%d] = 0x%02x (%d)", i, data[i], data[i]);
118 }
119
120 wr.addr = client->addr;
121 wr.flags = 0;
122 wr.len = len + 1;
123 wr.buf = _data;
124
125 ret = i2c_transfer(client->adapter, &wr, 1);
126 if (ret == 1) {
127 ret = 0;
128 }
129
130done:
131 return ret;
132}
133
134static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind)
135{
136 int ret;
137 struct i2c_client *new_client;
138 struct rtc8564_data *d;
139 unsigned char data[10];
140 unsigned char ad[1] = { 0 };
141 struct i2c_msg ctrl_wr[1] = {
142 {addr, 0, 2, data}
143 };
144 struct i2c_msg ctrl_rd[2] = {
145 {addr, 0, 1, ad},
146 {addr, I2C_M_RD, 2, data}
147 };
148
149 d = kzalloc(sizeof(struct rtc8564_data), GFP_KERNEL);
150 if (!d) {
151 ret = -ENOMEM;
152 goto done;
153 }
154 new_client = &d->client;
155
156 strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
157 i2c_set_clientdata(new_client, d);
158 new_client->addr = addr;
159 new_client->adapter = adap;
160 new_client->driver = &rtc8564_driver;
161
162 _DBG(1, "client=%p", new_client);
163
164 /* init ctrl1 reg */
165 data[0] = 0;
166 data[1] = 0;
167 ret = i2c_transfer(new_client->adapter, ctrl_wr, 1);
168 if (ret != 1) {
169 printk(KERN_INFO "rtc8564: cant init ctrl1\n");
170 ret = -ENODEV;
171 goto done;
172 }
173
174 /* read back ctrl1 and ctrl2 */
175 ret = i2c_transfer(new_client->adapter, ctrl_rd, 2);
176 if (ret != 2) {
177 printk(KERN_INFO "rtc8564: cant read ctrl\n");
178 ret = -ENODEV;
179 goto done;
180 }
181
182 d->ctrl = data[0] | (data[1] << 8);
183
184 _DBG(1, "RTC8564_REG_CTRL1=%02x, RTC8564_REG_CTRL2=%02x",
185 data[0], data[1]);
186
187 ret = i2c_attach_client(new_client);
188done:
189 if (ret) {
190 kfree(d);
191 }
192 return ret;
193}
194
195static int rtc8564_probe(struct i2c_adapter *adap)
196{
197 return i2c_probe(adap, &addr_data, rtc8564_attach);
198}
199
200static int rtc8564_detach(struct i2c_client *client)
201{
202 i2c_detach_client(client);
203 kfree(i2c_get_clientdata(client));
204 return 0;
205}
206
207static int rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
208{
209 int ret = -EIO;
210 unsigned char buf[15];
211
212 _DBG(1, "client=%p, dt=%p", client, dt);
213
214 if (!dt)
215 return -EINVAL;
216
217 memset(buf, 0, sizeof(buf));
218
219 ret = rtc8564_read(client, 0, buf, 15);
220 if (ret)
221 return ret;
222
223 /* century stored in minute alarm reg */
224 dt->year = BCD2BIN(buf[RTC8564_REG_YEAR]);
225 dt->year += 100 * BCD2BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
226 dt->mday = BCD2BIN(buf[RTC8564_REG_DAY] & 0x3f);
227 dt->wday = BCD2BIN(buf[RTC8564_REG_WDAY] & 7);
228 dt->mon = BCD2BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
229
230 dt->secs = BCD2BIN(buf[RTC8564_REG_SEC] & 0x7f);
231 dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80;
232 dt->mins = BCD2BIN(buf[RTC8564_REG_MIN] & 0x7f);
233 dt->hours = BCD2BIN(buf[RTC8564_REG_HR] & 0x3f);
234
235 _DBGRTCTM(2, *dt);
236
237 return 0;
238}
239
240static int
241rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
242{
243 int ret, len = 5;
244 unsigned char buf[15];
245
246 _DBG(1, "client=%p, dt=%p", client, dt);
247
248 if (!dt)
249 return -EINVAL;
250
251 _DBGRTCTM(2, *dt);
252
253 buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP;
254 buf[RTC8564_REG_CTRL2] = CTRL2(client);
255 buf[RTC8564_REG_SEC] = BIN2BCD(dt->secs);
256 buf[RTC8564_REG_MIN] = BIN2BCD(dt->mins);
257 buf[RTC8564_REG_HR] = BIN2BCD(dt->hours);
258
259 if (datetoo) {
260 len += 5;
261 buf[RTC8564_REG_DAY] = BIN2BCD(dt->mday);
262 buf[RTC8564_REG_WDAY] = BIN2BCD(dt->wday);
263 buf[RTC8564_REG_MON_CENT] = BIN2BCD(dt->mon) & 0x1f;
264 /* century stored in minute alarm reg */
265 buf[RTC8564_REG_YEAR] = BIN2BCD(dt->year % 100);
266 buf[RTC8564_REG_AL_MIN] = BIN2BCD(dt->year / 100);
267 }
268
269 ret = rtc8564_write(client, 0, buf, len);
270 if (ret) {
271 _DBG(1, "error writing data! %d", ret);
272 }
273
274 buf[RTC8564_REG_CTRL1] = CTRL1(client);
275 ret = rtc8564_write(client, 0, buf, 1);
276 if (ret) {
277 _DBG(1, "error writing data! %d", ret);
278 }
279
280 return ret;
281}
282
283static int rtc8564_get_ctrl(struct i2c_client *client, unsigned int *ctrl)
284{
285 struct rtc8564_data *data = i2c_get_clientdata(client);
286
287 if (!ctrl)
288 return -1;
289
290 *ctrl = data->ctrl;
291 return 0;
292}
293
294static int rtc8564_set_ctrl(struct i2c_client *client, unsigned int *ctrl)
295{
296 struct rtc8564_data *data = i2c_get_clientdata(client);
297 unsigned char buf[2];
298
299 if (!ctrl)
300 return -1;
301
302 buf[0] = *ctrl & 0xff;
303 buf[1] = (*ctrl & 0xff00) >> 8;
304 data->ctrl = *ctrl;
305
306 return rtc8564_write(client, 0, buf, 2);
307}
308
309static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem)
310{
311
312 if (!mem)
313 return -EINVAL;
314
315 return rtc8564_read(client, mem->loc, mem->data, mem->nr);
316}
317
318static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem)
319{
320
321 if (!mem)
322 return -EINVAL;
323
324 return rtc8564_write(client, mem->loc, mem->data, mem->nr);
325}
326
327static int
328rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg)
329{
330
331 _DBG(1, "cmd=%d", cmd);
332
333 switch (cmd) {
334 case RTC_GETDATETIME:
335 return rtc8564_get_datetime(client, arg);
336
337 case RTC_SETTIME:
338 return rtc8564_set_datetime(client, arg, 0);
339
340 case RTC_SETDATETIME:
341 return rtc8564_set_datetime(client, arg, 1);
342
343 case RTC_GETCTRL:
344 return rtc8564_get_ctrl(client, arg);
345
346 case RTC_SETCTRL:
347 return rtc8564_set_ctrl(client, arg);
348
349 case MEM_READ:
350 return rtc8564_read_mem(client, arg);
351
352 case MEM_WRITE:
353 return rtc8564_write_mem(client, arg);
354
355 default:
356 return -EINVAL;
357 }
358}
359
360static struct i2c_driver rtc8564_driver = {
361 .driver = {
362 .name = "RTC8564",
363 },
364 .id = I2C_DRIVERID_RTC8564,
365 .attach_adapter = rtc8564_probe,
366 .detach_client = rtc8564_detach,
367 .command = rtc8564_command
368};
369
370static __init int rtc8564_init(void)
371{
372 return i2c_add_driver(&rtc8564_driver);
373}
374
375static __exit void rtc8564_exit(void)
376{
377 i2c_del_driver(&rtc8564_driver);
378}
379
380MODULE_AUTHOR("Stefan Eletzhofer <Stefan.Eletzhofer@eletztrick.de>");
381MODULE_DESCRIPTION("EPSON RTC8564 Driver");
382MODULE_LICENSE("GPL");
383
384module_init(rtc8564_init);
385module_exit(rtc8564_exit);
diff --git a/drivers/i2c/chips/rtc8564.h b/drivers/i2c/chips/rtc8564.h
deleted file mode 100644
index e5342d10b8fa..000000000000
--- a/drivers/i2c/chips/rtc8564.h
+++ /dev/null
@@ -1,78 +0,0 @@
1/*
2 * linux/drivers/i2c/chips/rtc8564.h
3 *
4 * Copyright (C) 2002-2004 Stefan Eletzhofer
5 *
6 * based on linux/drivers/acron/char/pcf8583.h
7 * Copyright (C) 2000 Russell King
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13struct rtc_tm {
14 unsigned char secs;
15 unsigned char mins;
16 unsigned char hours;
17 unsigned char mday;
18 unsigned char mon;
19 unsigned short year; /* xxxx 4 digits :) */
20 unsigned char wday;
21 unsigned char vl;
22};
23
24struct mem {
25 unsigned int loc;
26 unsigned int nr;
27 unsigned char *data;
28};
29
30#define RTC_GETDATETIME 0
31#define RTC_SETTIME 1
32#define RTC_SETDATETIME 2
33#define RTC_GETCTRL 3
34#define RTC_SETCTRL 4
35#define MEM_READ 5
36#define MEM_WRITE 6
37
38#define RTC8564_REG_CTRL1 0x0 /* T 0 S 0 | T 0 0 0 */
39#define RTC8564_REG_CTRL2 0x1 /* 0 0 0 TI/TP | AF TF AIE TIE */
40#define RTC8564_REG_SEC 0x2 /* VL 4 2 1 | 8 4 2 1 */
41#define RTC8564_REG_MIN 0x3 /* x 4 2 1 | 8 4 2 1 */
42#define RTC8564_REG_HR 0x4 /* x x 2 1 | 8 4 2 1 */
43#define RTC8564_REG_DAY 0x5 /* x x 2 1 | 8 4 2 1 */
44#define RTC8564_REG_WDAY 0x6 /* x x x x | x 4 2 1 */
45#define RTC8564_REG_MON_CENT 0x7 /* C x x 1 | 8 4 2 1 */
46#define RTC8564_REG_YEAR 0x8 /* 8 4 2 1 | 8 4 2 1 */
47#define RTC8564_REG_AL_MIN 0x9 /* AE 4 2 1 | 8 4 2 1 */
48#define RTC8564_REG_AL_HR 0xa /* AE 4 2 1 | 8 4 2 1 */
49#define RTC8564_REG_AL_DAY 0xb /* AE x 2 1 | 8 4 2 1 */
50#define RTC8564_REG_AL_WDAY 0xc /* AE x x x | x 4 2 1 */
51#define RTC8564_REG_CLKOUT 0xd /* FE x x x | x x FD1 FD0 */
52#define RTC8564_REG_TCTL 0xe /* TE x x x | x x FD1 FD0 */
53#define RTC8564_REG_TIMER 0xf /* 8 bit binary */
54
55/* Control reg */
56#define RTC8564_CTRL1_TEST1 (1<<3)
57#define RTC8564_CTRL1_STOP (1<<5)
58#define RTC8564_CTRL1_TEST2 (1<<7)
59
60#define RTC8564_CTRL2_TIE (1<<0)
61#define RTC8564_CTRL2_AIE (1<<1)
62#define RTC8564_CTRL2_TF (1<<2)
63#define RTC8564_CTRL2_AF (1<<3)
64#define RTC8564_CTRL2_TI_TP (1<<4)
65
66/* CLKOUT frequencies */
67#define RTC8564_FD_32768HZ (0x0)
68#define RTC8564_FD_1024HZ (0x1)
69#define RTC8564_FD_32 (0x2)
70#define RTC8564_FD_1HZ (0x3)
71
72/* Timer CTRL */
73#define RTC8564_TD_4096HZ (0x0)
74#define RTC8564_TD_64HZ (0x1)
75#define RTC8564_TD_1HZ (0x2)
76#define RTC8564_TD_1_60HZ (0x3)
77
78#define I2C_DRIVERID_RTC8564 0xf000
diff --git a/drivers/i2c/chips/x1205.c b/drivers/i2c/chips/x1205.c
deleted file mode 100644
index 245fffa92dbd..000000000000
--- a/drivers/i2c/chips/x1205.c
+++ /dev/null
@@ -1,698 +0,0 @@
1/*
2 * x1205.c - An i2c driver for the Xicor X1205 RTC
3 * Copyright 2004 Karen Spearel
4 * Copyright 2005 Alessandro Zummo
5 *
6 * please send all reports to:
7 * kas11 at tampabay dot rr dot com
8 * a dot zummo at towertech dot it
9 *
10 * based on the other drivers in this same directory.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/slab.h>
21#include <linux/i2c.h>
22#include <linux/string.h>
23#include <linux/bcd.h>
24#include <linux/rtc.h>
25#include <linux/list.h>
26
27#include <linux/x1205.h>
28
29#define DRV_VERSION "0.9.9"
30
31/* Addresses to scan: none. This chip is located at
32 * 0x6f and uses a two bytes register addressing.
33 * Two bytes need to be written to read a single register,
34 * while most other chips just require one and take the second
35 * one as the data to be written. To prevent corrupting
36 * unknown chips, the user must explicitely set the probe parameter.
37 */
38
39static unsigned short normal_i2c[] = { I2C_CLIENT_END };
40
41/* Insmod parameters */
42I2C_CLIENT_INSMOD;
43I2C_CLIENT_MODULE_PARM(hctosys,
44 "Set the system time from the hardware clock upon initialization");
45
46/* offsets into CCR area */
47
48#define CCR_SEC 0
49#define CCR_MIN 1
50#define CCR_HOUR 2
51#define CCR_MDAY 3
52#define CCR_MONTH 4
53#define CCR_YEAR 5
54#define CCR_WDAY 6
55#define CCR_Y2K 7
56
57#define X1205_REG_SR 0x3F /* status register */
58#define X1205_REG_Y2K 0x37
59#define X1205_REG_DW 0x36
60#define X1205_REG_YR 0x35
61#define X1205_REG_MO 0x34
62#define X1205_REG_DT 0x33
63#define X1205_REG_HR 0x32
64#define X1205_REG_MN 0x31
65#define X1205_REG_SC 0x30
66#define X1205_REG_DTR 0x13
67#define X1205_REG_ATR 0x12
68#define X1205_REG_INT 0x11
69#define X1205_REG_0 0x10
70#define X1205_REG_Y2K1 0x0F
71#define X1205_REG_DWA1 0x0E
72#define X1205_REG_YRA1 0x0D
73#define X1205_REG_MOA1 0x0C
74#define X1205_REG_DTA1 0x0B
75#define X1205_REG_HRA1 0x0A
76#define X1205_REG_MNA1 0x09
77#define X1205_REG_SCA1 0x08
78#define X1205_REG_Y2K0 0x07
79#define X1205_REG_DWA0 0x06
80#define X1205_REG_YRA0 0x05
81#define X1205_REG_MOA0 0x04
82#define X1205_REG_DTA0 0x03
83#define X1205_REG_HRA0 0x02
84#define X1205_REG_MNA0 0x01
85#define X1205_REG_SCA0 0x00
86
87#define X1205_CCR_BASE 0x30 /* Base address of CCR */
88#define X1205_ALM0_BASE 0x00 /* Base address of ALARM0 */
89
90#define X1205_SR_RTCF 0x01 /* Clock failure */
91#define X1205_SR_WEL 0x02 /* Write Enable Latch */
92#define X1205_SR_RWEL 0x04 /* Register Write Enable */
93
94#define X1205_DTR_DTR0 0x01
95#define X1205_DTR_DTR1 0x02
96#define X1205_DTR_DTR2 0x04
97
98#define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */
99
100/* Prototypes */
101static int x1205_attach(struct i2c_adapter *adapter);
102static int x1205_detach(struct i2c_client *client);
103static int x1205_probe(struct i2c_adapter *adapter, int address, int kind);
104static int x1205_command(struct i2c_client *client, unsigned int cmd,
105 void *arg);
106
107static struct i2c_driver x1205_driver = {
108 .driver = {
109 .name = "x1205",
110 },
111 .attach_adapter = &x1205_attach,
112 .detach_client = &x1205_detach,
113};
114
115struct x1205_data {
116 struct i2c_client client;
117 struct list_head list;
118 unsigned int epoch;
119};
120
121static const unsigned char days_in_mo[] =
122 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
123
124static LIST_HEAD(x1205_clients);
125
126/* Workaround until the I2C subsytem will allow to send
127 * commands to a specific client. This function will send the command
128 * to the first client.
129 */
130int x1205_do_command(unsigned int cmd, void *arg)
131{
132 struct list_head *walk;
133 struct list_head *tmp;
134 struct x1205_data *data;
135
136 list_for_each_safe(walk, tmp, &x1205_clients) {
137 data = list_entry(walk, struct x1205_data, list);
138 return x1205_command(&data->client, cmd, arg);
139 }
140
141 return -ENODEV;
142}
143
144#define is_leap(year) \
145 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
146
147/* make sure the rtc_time values are in bounds */
148static int x1205_validate_tm(struct rtc_time *tm)
149{
150 int year = tm->tm_year + 1900;
151
152 if ((tm->tm_year < 70) || (tm->tm_year > 255))
153 return -EINVAL;
154
155 if ((tm->tm_mon > 11) || (tm->tm_mday == 0))
156 return -EINVAL;
157
158 if (tm->tm_mday > days_in_mo[tm->tm_mon]
159 + ((tm->tm_mon == 1) && is_leap(year)))
160 return -EINVAL;
161
162 if ((tm->tm_hour >= 24) || (tm->tm_min >= 60) || (tm->tm_sec >= 60))
163 return -EINVAL;
164
165 return 0;
166}
167
168/*
169 * In the routines that deal directly with the x1205 hardware, we use
170 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
171 * Epoch is initialized as 2000. Time is set to UTC.
172 */
173static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
174 u8 reg_base)
175{
176 unsigned char dt_addr[2] = { 0, reg_base };
177 static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
178
179 unsigned char buf[8], sr;
180
181 struct i2c_msg msgs[] = {
182 { client->addr, 0, 2, sr_addr }, /* setup read ptr */
183 { client->addr, I2C_M_RD, 1, &sr }, /* read status */
184 { client->addr, 0, 2, dt_addr }, /* setup read ptr */
185 { client->addr, I2C_M_RD, 8, buf }, /* read date */
186 };
187
188 struct x1205_data *data = i2c_get_clientdata(client);
189
190 /* read status register */
191 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
192 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
193 return -EIO;
194 }
195
196 /* check for battery failure */
197 if (sr & X1205_SR_RTCF) {
198 dev_warn(&client->dev,
199 "Clock had a power failure, you must set the date.\n");
200 return -EINVAL;
201 }
202
203 /* read date registers */
204 if ((i2c_transfer(client->adapter, &msgs[2], 2)) != 2) {
205 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
206 return -EIO;
207 }
208
209 dev_dbg(&client->dev,
210 "%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
211 "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
212 __FUNCTION__,
213 buf[0], buf[1], buf[2], buf[3],
214 buf[4], buf[5], buf[6], buf[7]);
215
216 tm->tm_sec = BCD2BIN(buf[CCR_SEC]);
217 tm->tm_min = BCD2BIN(buf[CCR_MIN]);
218 tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
219 tm->tm_mday = BCD2BIN(buf[CCR_MDAY]);
220 tm->tm_mon = BCD2BIN(buf[CCR_MONTH]);
221 data->epoch = BCD2BIN(buf[CCR_Y2K]) * 100;
222 tm->tm_year = BCD2BIN(buf[CCR_YEAR]) + data->epoch - 1900;
223 tm->tm_wday = buf[CCR_WDAY];
224
225 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
226 "mday=%d, mon=%d, year=%d, wday=%d\n",
227 __FUNCTION__,
228 tm->tm_sec, tm->tm_min, tm->tm_hour,
229 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
230
231 return 0;
232}
233
234static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
235 int datetoo, u8 reg_base)
236{
237 int i, err, xfer;
238
239 unsigned char buf[8];
240
241 static const unsigned char wel[3] = { 0, X1205_REG_SR,
242 X1205_SR_WEL };
243
244 static const unsigned char rwel[3] = { 0, X1205_REG_SR,
245 X1205_SR_WEL | X1205_SR_RWEL };
246
247 static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };
248
249 struct x1205_data *data = i2c_get_clientdata(client);
250
251 /* check if all values in the tm struct are correct */
252 if ((err = x1205_validate_tm(tm)) < 0)
253 return err;
254
255 dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
256 "mday=%d, mon=%d, year=%d, wday=%d\n",
257 __FUNCTION__,
258 tm->tm_sec, tm->tm_min, tm->tm_hour,
259 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
260
261 buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
262 buf[CCR_MIN] = BIN2BCD(tm->tm_min);
263
264 /* set hour and 24hr bit */
265 buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL;
266
267 /* should we also set the date? */
268 if (datetoo) {
269 buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
270
271 /* month, 0 - 11 */
272 buf[CCR_MONTH] = BIN2BCD(tm->tm_mon);
273
274 /* year, since 1900 */
275 buf[CCR_YEAR] = BIN2BCD(tm->tm_year + 1900 - data->epoch);
276 buf[CCR_WDAY] = tm->tm_wday & 0x07;
277 buf[CCR_Y2K] = BIN2BCD(data->epoch / 100);
278 }
279
280 /* this sequence is required to unlock the chip */
281 xfer = i2c_master_send(client, wel, 3);
282 if (xfer != 3) {
283 dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer);
284 return -EIO;
285 }
286
287 xfer = i2c_master_send(client, rwel, 3);
288 if (xfer != 3) {
289 dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer);
290 return -EIO;
291 }
292
293 /* write register's data */
294 for (i = 0; i < (datetoo ? 8 : 3); i++) {
295 unsigned char rdata[3] = { 0, reg_base + i, buf[i] };
296
297 xfer = i2c_master_send(client, rdata, 3);
298 if (xfer != 3) {
299 dev_err(&client->dev,
300 "%s: xfer=%d addr=%02x, data=%02x\n",
301 __FUNCTION__,
302 xfer, rdata[1], rdata[2]);
303 return -EIO;
304 }
305 };
306
307 /* disable further writes */
308 xfer = i2c_master_send(client, diswe, 3);
309 if (xfer != 3) {
310 dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer);
311 return -EIO;
312 }
313
314 return 0;
315}
316
317static int x1205_get_dtrim(struct i2c_client *client, int *trim)
318{
319 unsigned char dtr;
320 static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR };
321
322 struct i2c_msg msgs[] = {
323 { client->addr, 0, 2, dtr_addr }, /* setup read ptr */
324 { client->addr, I2C_M_RD, 1, &dtr }, /* read dtr */
325 };
326
327 /* read dtr register */
328 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
329 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
330 return -EIO;
331 }
332
333 dev_dbg(&client->dev, "%s: raw dtr=%x\n", __FUNCTION__, dtr);
334
335 *trim = 0;
336
337 if (dtr & X1205_DTR_DTR0)
338 *trim += 20;
339
340 if (dtr & X1205_DTR_DTR1)
341 *trim += 10;
342
343 if (dtr & X1205_DTR_DTR2)
344 *trim = -*trim;
345
346 return 0;
347}
348
349static int x1205_get_atrim(struct i2c_client *client, int *trim)
350{
351 s8 atr;
352 static unsigned char atr_addr[2] = { 0, X1205_REG_ATR };
353
354 struct i2c_msg msgs[] = {
355 { client->addr, 0, 2, atr_addr }, /* setup read ptr */
356 { client->addr, I2C_M_RD, 1, &atr }, /* read atr */
357 };
358
359 /* read atr register */
360 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
361 dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
362 return -EIO;
363 }
364
365 dev_dbg(&client->dev, "%s: raw atr=%x\n", __FUNCTION__, atr);
366
367 /* atr is a two's complement value on 6 bits,
368 * perform sign extension. The formula is
369 * Catr = (atr * 0.25pF) + 11.00pF.
370 */
371 if (atr & 0x20)
372 atr |= 0xC0;
373
374 dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __FUNCTION__, atr, atr);
375
376 *trim = (atr * 250) + 11000;
377
378 dev_dbg(&client->dev, "%s: real=%d\n", __FUNCTION__, *trim);
379
380 return 0;
381}
382
383static int x1205_hctosys(struct i2c_client *client)
384{
385 int err;
386
387 struct rtc_time tm;
388 struct timespec tv;
389
390 err = x1205_command(client, X1205_CMD_GETDATETIME, &tm);
391
392 if (err) {
393 dev_err(&client->dev,
394 "Unable to set the system clock\n");
395 return err;
396 }
397
398 /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
399 * whether it stores the most close value or the value with partial
400 * seconds truncated. However, it is important that we use it to store
401 * the truncated value. This is because otherwise it is necessary,
402 * in an rtc sync function, to read both xtime.tv_sec and
403 * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
404 * of >32bits is not possible. So storing the most close value would
405 * slow down the sync API. So here we have the truncated value and
406 * the best guess is to add 0.5s.
407 */
408
409 tv.tv_nsec = NSEC_PER_SEC >> 1;
410
411 /* WARNING: this is not the C library 'mktime' call, it is a built in
412 * inline function from include/linux/time.h. It expects (requires)
413 * the month to be in the range 1-12
414 */
415
416 tv.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1,
417 tm.tm_mday, tm.tm_hour,
418 tm.tm_min, tm.tm_sec);
419
420 do_settimeofday(&tv);
421
422 dev_info(&client->dev,
423 "setting the system clock to %d-%d-%d %d:%d:%d\n",
424 tm.tm_year + 1900, tm.tm_mon + 1,
425 tm.tm_mday, tm.tm_hour, tm.tm_min,
426 tm.tm_sec);
427
428 return 0;
429}
430
431struct x1205_limit
432{
433 unsigned char reg;
434 unsigned char mask;
435 unsigned char min;
436 unsigned char max;
437};
438
439static int x1205_validate_client(struct i2c_client *client)
440{
441 int i, xfer;
442
443 /* Probe array. We will read the register at the specified
444 * address and check if the given bits are zero.
445 */
446 static const unsigned char probe_zero_pattern[] = {
447 /* register, mask */
448 X1205_REG_SR, 0x18,
449 X1205_REG_DTR, 0xF8,
450 X1205_REG_ATR, 0xC0,
451 X1205_REG_INT, 0x18,
452 X1205_REG_0, 0xFF,
453 };
454
455 static const struct x1205_limit probe_limits_pattern[] = {
456 /* register, mask, min, max */
457 { X1205_REG_Y2K, 0xFF, 19, 20 },
458 { X1205_REG_DW, 0xFF, 0, 6 },
459 { X1205_REG_YR, 0xFF, 0, 99 },
460 { X1205_REG_MO, 0xFF, 0, 12 },
461 { X1205_REG_DT, 0xFF, 0, 31 },
462 { X1205_REG_HR, 0x7F, 0, 23 },
463 { X1205_REG_MN, 0xFF, 0, 59 },
464 { X1205_REG_SC, 0xFF, 0, 59 },
465 { X1205_REG_Y2K1, 0xFF, 19, 20 },
466 { X1205_REG_Y2K0, 0xFF, 19, 20 },
467 };
468
469 /* check that registers have bits a 0 where expected */
470 for (i = 0; i < ARRAY_SIZE(probe_zero_pattern); i += 2) {
471 unsigned char buf;
472
473 unsigned char addr[2] = { 0, probe_zero_pattern[i] };
474
475 struct i2c_msg msgs[2] = {
476 { client->addr, 0, 2, addr },
477 { client->addr, I2C_M_RD, 1, &buf },
478 };
479
480 xfer = i2c_transfer(client->adapter, msgs, 2);
481 if (xfer != 2) {
482 dev_err(&client->adapter->dev,
483 "%s: could not read register %x\n",
484 __FUNCTION__, addr[1]);
485
486 return -EIO;
487 }
488
489 if ((buf & probe_zero_pattern[i+1]) != 0) {
490 dev_err(&client->adapter->dev,
491 "%s: register=%02x, zero pattern=%d, value=%x\n",
492 __FUNCTION__, addr[1], i, buf);
493
494 return -ENODEV;
495 }
496 }
497
498 /* check limits (only registers with bcd values) */
499 for (i = 0; i < ARRAY_SIZE(probe_limits_pattern); i++) {
500 unsigned char reg, value;
501
502 unsigned char addr[2] = { 0, probe_limits_pattern[i].reg };
503
504 struct i2c_msg msgs[2] = {
505 { client->addr, 0, 2, addr },
506 { client->addr, I2C_M_RD, 1, &reg },
507 };
508
509 xfer = i2c_transfer(client->adapter, msgs, 2);
510
511 if (xfer != 2) {
512 dev_err(&client->adapter->dev,
513 "%s: could not read register %x\n",
514 __FUNCTION__, addr[1]);
515
516 return -EIO;
517 }
518
519 value = BCD2BIN(reg & probe_limits_pattern[i].mask);
520
521 if (value > probe_limits_pattern[i].max ||
522 value < probe_limits_pattern[i].min) {
523 dev_dbg(&client->adapter->dev,
524 "%s: register=%x, lim pattern=%d, value=%d\n",
525 __FUNCTION__, addr[1], i, value);
526
527 return -ENODEV;
528 }
529 }
530
531 return 0;
532}
533
534static int x1205_attach(struct i2c_adapter *adapter)
535{
536 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
537
538 return i2c_probe(adapter, &addr_data, x1205_probe);
539}
540
541int x1205_direct_attach(int adapter_id,
542 struct i2c_client_address_data *address_data)
543{
544 int err;
545 struct i2c_adapter *adapter = i2c_get_adapter(adapter_id);
546
547 if (adapter) {
548 err = i2c_probe(adapter,
549 address_data, x1205_probe);
550
551 i2c_put_adapter(adapter);
552
553 return err;
554 }
555
556 return -ENODEV;
557}
558
559static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
560{
561 struct i2c_client *client;
562 struct x1205_data *data;
563
564 int err = 0;
565
566 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
567
568 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
569 err = -ENODEV;
570 goto exit;
571 }
572
573 if (!(data = kzalloc(sizeof(struct x1205_data), GFP_KERNEL))) {
574 err = -ENOMEM;
575 goto exit;
576 }
577
578 /* Initialize our structures */
579 data->epoch = 2000;
580
581 client = &data->client;
582 client->addr = address;
583 client->driver = &x1205_driver;
584 client->adapter = adapter;
585
586 strlcpy(client->name, "x1205", I2C_NAME_SIZE);
587
588 i2c_set_clientdata(client, data);
589
590 /* Verify the chip is really an X1205 */
591 if (kind < 0) {
592 if (x1205_validate_client(client) < 0) {
593 err = -ENODEV;
594 goto exit_kfree;
595 }
596 }
597
598 /* Inform the i2c layer */
599 if ((err = i2c_attach_client(client)))
600 goto exit_kfree;
601
602 list_add(&data->list, &x1205_clients);
603
604 dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
605
606 /* If requested, set the system time */
607 if (hctosys)
608 x1205_hctosys(client);
609
610 return 0;
611
612exit_kfree:
613 kfree(data);
614
615exit:
616 return err;
617}
618
619static int x1205_detach(struct i2c_client *client)
620{
621 int err;
622 struct x1205_data *data = i2c_get_clientdata(client);
623
624 dev_dbg(&client->dev, "%s\n", __FUNCTION__);
625
626 if ((err = i2c_detach_client(client)))
627 return err;
628
629 list_del(&data->list);
630
631 kfree(data);
632
633 return 0;
634}
635
636static int x1205_command(struct i2c_client *client, unsigned int cmd,
637 void *param)
638{
639 if (param == NULL)
640 return -EINVAL;
641
642 if (!capable(CAP_SYS_TIME))
643 return -EACCES;
644
645 dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
646
647 switch (cmd) {
648 case X1205_CMD_GETDATETIME:
649 return x1205_get_datetime(client, param, X1205_CCR_BASE);
650
651 case X1205_CMD_SETTIME:
652 return x1205_set_datetime(client, param, 0,
653 X1205_CCR_BASE);
654
655 case X1205_CMD_SETDATETIME:
656 return x1205_set_datetime(client, param, 1,
657 X1205_CCR_BASE);
658
659 case X1205_CMD_GETALARM:
660 return x1205_get_datetime(client, param, X1205_ALM0_BASE);
661
662 case X1205_CMD_SETALARM:
663 return x1205_set_datetime(client, param, 1,
664 X1205_ALM0_BASE);
665
666 case X1205_CMD_GETDTRIM:
667 return x1205_get_dtrim(client, param);
668
669 case X1205_CMD_GETATRIM:
670 return x1205_get_atrim(client, param);
671
672 default:
673 return -EINVAL;
674 }
675}
676
677static int __init x1205_init(void)
678{
679 return i2c_add_driver(&x1205_driver);
680}
681
682static void __exit x1205_exit(void)
683{
684 i2c_del_driver(&x1205_driver);
685}
686
687MODULE_AUTHOR(
688 "Karen Spearel <kas11@tampabay.rr.com>, "
689 "Alessandro Zummo <a.zummo@towertech.it>");
690MODULE_DESCRIPTION("Xicor X1205 RTC driver");
691MODULE_LICENSE("GPL");
692MODULE_VERSION(DRV_VERSION);
693
694EXPORT_SYMBOL_GPL(x1205_do_command);
695EXPORT_SYMBOL_GPL(x1205_direct_attach);
696
697module_init(x1205_init);
698module_exit(x1205_exit);