aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/chips/rtc8564.c
diff options
context:
space:
mode:
authorAlessandro Zummo <a.zummo@towertech.it>2006-03-27 04:16:37 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 11:44:51 -0500
commit6fc7f10cee28c7fa190920fefda8c696d5bf3074 (patch)
tree549dd6be7fb058bf404deae6f72cd01f9ec177b3 /drivers/i2c/chips/rtc8564.c
parent0c86edc0d4970649f39748c4ce4f2895f728468f (diff)
[PATCH] RTC subsystem: I2C cleanup
This patch, completely optional, removes from drivers/i2c/chips all the drivers that are implemented in the new RTC subsystem. It should be noted that none of the current driver is actually integrated, i.e. usable without further patches. Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/i2c/chips/rtc8564.c')
-rw-r--r--drivers/i2c/chips/rtc8564.c385
1 files changed, 0 insertions, 385 deletions
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);