aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/chips
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@kernel.org>2008-01-27 12:14:45 -0500
committerJean Delvare <khali@hyperion.delvare>2008-01-27 12:14:45 -0500
commiteee87d3196c9a7ac3422f4298e2250ca68d791c1 (patch)
tree754fb40d3684b55cc4a30729511e2fa8a59bab25 /drivers/i2c/chips
parent569be443e3c1329fc6725988004f5d8a32fe3be5 (diff)
i2c: the scheduled I2C RTC driver removal
This patch contains the scheduled removal of legacy I2C RTC drivers with replacement drivers. Signed-off-by: Adrian Bunk <bunk@kernel.org> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/chips')
-rw-r--r--drivers/i2c/chips/Kconfig38
-rw-r--r--drivers/i2c/chips/Makefile3
-rw-r--r--drivers/i2c/chips/ds1337.c410
-rw-r--r--drivers/i2c/chips/ds1374.c267
-rw-r--r--drivers/i2c/chips/m41t00.c413
5 files changed, 0 insertions, 1131 deletions
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index 17702b32eab0..fe3008e59467 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -4,32 +4,6 @@
4 4
5menu "Miscellaneous I2C Chip support" 5menu "Miscellaneous I2C Chip support"
6 6
7config SENSORS_DS1337
8 tristate "Dallas DS1337 and DS1339 Real Time Clock (DEPRECATED)"
9 depends on EXPERIMENTAL
10 help
11 If you say yes here you get support for Dallas Semiconductor
12 DS1337 and DS1339 real-time clock chips.
13
14 This driver can also be built as a module. If so, the module
15 will be called ds1337.
16
17 This driver is deprecated and will be dropped soon. Use
18 rtc-ds1307 instead.
19
20config SENSORS_DS1374
21 tristate "Dallas DS1374 Real Time Clock (DEPRECATED)"
22 depends on EXPERIMENTAL
23 help
24 If you say yes here you get support for Dallas Semiconductor
25 DS1374 real-time clock chips.
26
27 This driver can also be built as a module. If so, the module
28 will be called ds1374.
29
30 This driver is deprecated and will be dropped soon. Use
31 rtc-ds1374 instead.
32
33config DS1682 7config DS1682
34 tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm" 8 tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
35 depends on EXPERIMENTAL 9 depends on EXPERIMENTAL
@@ -130,18 +104,6 @@ config TPS65010
130 This driver can also be built as a module. If so, the module 104 This driver can also be built as a module. If so, the module
131 will be called tps65010. 105 will be called tps65010.
132 106
133config SENSORS_M41T00
134 tristate "ST M41T00 RTC chip (DEPRECATED)"
135 depends on PPC32
136 help
137 If you say yes here you get support for the ST M41T00 RTC chip.
138
139 This driver can also be built as a module. If so, the module
140 will be called m41t00.
141
142 This driver is deprecated and will be dropped soon. Use
143 rtc-ds1307 or rtc-m41t80 instead.
144
145config SENSORS_MAX6875 107config SENSORS_MAX6875
146 tristate "Maxim MAX6875 Power supply supervisor" 108 tristate "Maxim MAX6875 Power supply supervisor"
147 depends on EXPERIMENTAL 109 depends on EXPERIMENTAL
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 50d4734b5038..501f00cea782 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -2,12 +2,9 @@
2# Makefile for miscellaneous I2C chip drivers. 2# Makefile for miscellaneous I2C chip drivers.
3# 3#
4 4
5obj-$(CONFIG_SENSORS_DS1337) += ds1337.o
6obj-$(CONFIG_SENSORS_DS1374) += ds1374.o
7obj-$(CONFIG_DS1682) += ds1682.o 5obj-$(CONFIG_DS1682) += ds1682.o
8obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o 6obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
9obj-$(CONFIG_SENSORS_MAX6875) += max6875.o 7obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
10obj-$(CONFIG_SENSORS_M41T00) += m41t00.o
11obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o 8obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
12obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o 9obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
13obj-$(CONFIG_PCF8575) += pcf8575.o 10obj-$(CONFIG_PCF8575) += pcf8575.o
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
deleted file mode 100644
index ec17d6b684a2..000000000000
--- a/drivers/i2c/chips/ds1337.c
+++ /dev/null
@@ -1,410 +0,0 @@
1/*
2 * linux/drivers/i2c/chips/ds1337.c
3 *
4 * Copyright (C) 2005 James Chapman <jchapman@katalix.com>
5 *
6 * based on linux/drivers/acorn/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 Dallas Semiconductor DS1337 and DS1339 real time clock chip
14 */
15
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/i2c.h>
20#include <linux/string.h>
21#include <linux/rtc.h> /* get the user-level API */
22#include <linux/bcd.h>
23#include <linux/list.h>
24
25/* Device registers */
26#define DS1337_REG_HOUR 2
27#define DS1337_REG_DAY 3
28#define DS1337_REG_DATE 4
29#define DS1337_REG_MONTH 5
30#define DS1337_REG_CONTROL 14
31#define DS1337_REG_STATUS 15
32
33/* FIXME - how do we export these interface constants? */
34#define DS1337_GET_DATE 0
35#define DS1337_SET_DATE 1
36
37/*
38 * Functions declaration
39 */
40static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END };
41
42I2C_CLIENT_INSMOD_1(ds1337);
43
44static int ds1337_attach_adapter(struct i2c_adapter *adapter);
45static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind);
46static void ds1337_init_client(struct i2c_client *client);
47static int ds1337_detach_client(struct i2c_client *client);
48static int ds1337_command(struct i2c_client *client, unsigned int cmd,
49 void *arg);
50
51/*
52 * Driver data (common to all clients)
53 */
54static struct i2c_driver ds1337_driver = {
55 .driver = {
56 .name = "ds1337",
57 },
58 .attach_adapter = ds1337_attach_adapter,
59 .detach_client = ds1337_detach_client,
60 .command = ds1337_command,
61};
62
63/*
64 * Client data (each client gets its own)
65 */
66struct ds1337_data {
67 struct i2c_client client;
68 struct list_head list;
69};
70
71/*
72 * Internal variables
73 */
74static LIST_HEAD(ds1337_clients);
75
76static inline int ds1337_read(struct i2c_client *client, u8 reg, u8 *value)
77{
78 s32 tmp = i2c_smbus_read_byte_data(client, reg);
79
80 if (tmp < 0)
81 return -EIO;
82
83 *value = tmp;
84
85 return 0;
86}
87
88/*
89 * Chip access functions
90 */
91static int ds1337_get_datetime(struct i2c_client *client, struct rtc_time *dt)
92{
93 int result;
94 u8 buf[7];
95 u8 val;
96 struct i2c_msg msg[2];
97 u8 offs = 0;
98
99 if (!dt) {
100 dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__);
101 return -EINVAL;
102 }
103
104 msg[0].addr = client->addr;
105 msg[0].flags = 0;
106 msg[0].len = 1;
107 msg[0].buf = &offs;
108
109 msg[1].addr = client->addr;
110 msg[1].flags = I2C_M_RD;
111 msg[1].len = sizeof(buf);
112 msg[1].buf = &buf[0];
113
114 result = i2c_transfer(client->adapter, msg, 2);
115
116 dev_dbg(&client->dev, "%s: [%d] %02x %02x %02x %02x %02x %02x %02x\n",
117 __FUNCTION__, result, buf[0], buf[1], buf[2], buf[3],
118 buf[4], buf[5], buf[6]);
119
120 if (result == 2) {
121 dt->tm_sec = BCD2BIN(buf[0]);
122 dt->tm_min = BCD2BIN(buf[1]);
123 val = buf[2] & 0x3f;
124 dt->tm_hour = BCD2BIN(val);
125 dt->tm_wday = BCD2BIN(buf[3]) - 1;
126 dt->tm_mday = BCD2BIN(buf[4]);
127 val = buf[5] & 0x7f;
128 dt->tm_mon = BCD2BIN(val) - 1;
129 dt->tm_year = BCD2BIN(buf[6]);
130 if (buf[5] & 0x80)
131 dt->tm_year += 100;
132
133 dev_dbg(&client->dev, "%s: secs=%d, mins=%d, "
134 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
135 __FUNCTION__, dt->tm_sec, dt->tm_min,
136 dt->tm_hour, dt->tm_mday,
137 dt->tm_mon, dt->tm_year, dt->tm_wday);
138
139 return 0;
140 }
141
142 dev_err(&client->dev, "error reading data! %d\n", result);
143 return -EIO;
144}
145
146static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
147{
148 int result;
149 u8 buf[8];
150 u8 val;
151 struct i2c_msg msg[1];
152
153 if (!dt) {
154 dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__);
155 return -EINVAL;
156 }
157
158 dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
159 "mday=%d, mon=%d, year=%d, wday=%d\n", __FUNCTION__,
160 dt->tm_sec, dt->tm_min, dt->tm_hour,
161 dt->tm_mday, dt->tm_mon, dt->tm_year, dt->tm_wday);
162
163 buf[0] = 0; /* reg offset */
164 buf[1] = BIN2BCD(dt->tm_sec);
165 buf[2] = BIN2BCD(dt->tm_min);
166 buf[3] = BIN2BCD(dt->tm_hour);
167 buf[4] = BIN2BCD(dt->tm_wday + 1);
168 buf[5] = BIN2BCD(dt->tm_mday);
169 buf[6] = BIN2BCD(dt->tm_mon + 1);
170 val = dt->tm_year;
171 if (val >= 100) {
172 val -= 100;
173 buf[6] |= (1 << 7);
174 }
175 buf[7] = BIN2BCD(val);
176
177 msg[0].addr = client->addr;
178 msg[0].flags = 0;
179 msg[0].len = sizeof(buf);
180 msg[0].buf = &buf[0];
181
182 result = i2c_transfer(client->adapter, msg, 1);
183 if (result == 1)
184 return 0;
185
186 dev_err(&client->dev, "error writing data! %d\n", result);
187 return -EIO;
188}
189
190static int ds1337_command(struct i2c_client *client, unsigned int cmd,
191 void *arg)
192{
193 dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
194
195 switch (cmd) {
196 case DS1337_GET_DATE:
197 return ds1337_get_datetime(client, arg);
198
199 case DS1337_SET_DATE:
200 return ds1337_set_datetime(client, arg);
201
202 default:
203 return -EINVAL;
204 }
205}
206
207/*
208 * Public API for access to specific device. Useful for low-level
209 * RTC access from kernel code.
210 */
211int ds1337_do_command(int bus, int cmd, void *arg)
212{
213 struct list_head *walk;
214 struct list_head *tmp;
215 struct ds1337_data *data;
216
217 list_for_each_safe(walk, tmp, &ds1337_clients) {
218 data = list_entry(walk, struct ds1337_data, list);
219 if (data->client.adapter->nr == bus)
220 return ds1337_command(&data->client, cmd, arg);
221 }
222
223 return -ENODEV;
224}
225
226static int ds1337_attach_adapter(struct i2c_adapter *adapter)
227{
228 return i2c_probe(adapter, &addr_data, ds1337_detect);
229}
230
231/*
232 * The following function does more than just detection. If detection
233 * succeeds, it also registers the new chip.
234 */
235static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind)
236{
237 struct i2c_client *new_client;
238 struct ds1337_data *data;
239 int err = 0;
240 const char *name = "";
241
242 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
243 I2C_FUNC_I2C))
244 goto exit;
245
246 if (!(data = kzalloc(sizeof(struct ds1337_data), GFP_KERNEL))) {
247 err = -ENOMEM;
248 goto exit;
249 }
250 INIT_LIST_HEAD(&data->list);
251
252 /* The common I2C client data is placed right before the
253 * DS1337-specific data.
254 */
255 new_client = &data->client;
256 i2c_set_clientdata(new_client, data);
257 new_client->addr = address;
258 new_client->adapter = adapter;
259 new_client->driver = &ds1337_driver;
260 new_client->flags = 0;
261
262 /*
263 * Now we do the remaining detection. A negative kind means that
264 * the driver was loaded with no force parameter (default), so we
265 * must both detect and identify the chip. A zero kind means that
266 * the driver was loaded with the force parameter, the detection
267 * step shall be skipped. A positive kind means that the driver
268 * was loaded with the force parameter and a given kind of chip is
269 * requested, so both the detection and the identification steps
270 * are skipped.
271 *
272 * For detection, we read registers that are most likely to cause
273 * detection failure, i.e. those that have more bits with fixed
274 * or reserved values.
275 */
276
277 /* Default to an DS1337 if forced */
278 if (kind == 0)
279 kind = ds1337;
280
281 if (kind < 0) { /* detection and identification */
282 u8 data;
283
284 /* Check that status register bits 6-2 are zero */
285 if ((ds1337_read(new_client, DS1337_REG_STATUS, &data) < 0) ||
286 (data & 0x7c))
287 goto exit_free;
288
289 /* Check for a valid day register value */
290 if ((ds1337_read(new_client, DS1337_REG_DAY, &data) < 0) ||
291 (data == 0) || (data & 0xf8))
292 goto exit_free;
293
294 /* Check for a valid date register value */
295 if ((ds1337_read(new_client, DS1337_REG_DATE, &data) < 0) ||
296 (data == 0) || (data & 0xc0) || ((data & 0x0f) > 9) ||
297 (data >= 0x32))
298 goto exit_free;
299
300 /* Check for a valid month register value */
301 if ((ds1337_read(new_client, DS1337_REG_MONTH, &data) < 0) ||
302 (data == 0) || (data & 0x60) || ((data & 0x0f) > 9) ||
303 ((data >= 0x13) && (data <= 0x19)))
304 goto exit_free;
305
306 /* Check that control register bits 6-5 are zero */
307 if ((ds1337_read(new_client, DS1337_REG_CONTROL, &data) < 0) ||
308 (data & 0x60))
309 goto exit_free;
310
311 kind = ds1337;
312 }
313
314 if (kind == ds1337)
315 name = "ds1337";
316
317 /* We can fill in the remaining client fields */
318 strlcpy(new_client->name, name, I2C_NAME_SIZE);
319
320 /* Tell the I2C layer a new client has arrived */
321 if ((err = i2c_attach_client(new_client)))
322 goto exit_free;
323
324 /* Initialize the DS1337 chip */
325 ds1337_init_client(new_client);
326
327 /* Add client to local list */
328 list_add(&data->list, &ds1337_clients);
329
330 return 0;
331
332exit_free:
333 kfree(data);
334exit:
335 return err;
336}
337
338static void ds1337_init_client(struct i2c_client *client)
339{
340 u8 status, control;
341
342 /* On some boards, the RTC isn't configured by boot firmware.
343 * Handle that case by starting/configuring the RTC now.
344 */
345 status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);
346 control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
347
348 if ((status & 0x80) || (control & 0x80)) {
349 /* RTC not running */
350 u8 buf[1+16]; /* First byte is interpreted as address */
351 struct i2c_msg msg[1];
352
353 dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
354
355 /* Initialize all, including STATUS and CONTROL to zero */
356 memset(buf, 0, sizeof(buf));
357
358 /* Write valid values in the date/time registers */
359 buf[1+DS1337_REG_DAY] = 1;
360 buf[1+DS1337_REG_DATE] = 1;
361 buf[1+DS1337_REG_MONTH] = 1;
362
363 msg[0].addr = client->addr;
364 msg[0].flags = 0;
365 msg[0].len = sizeof(buf);
366 msg[0].buf = &buf[0];
367
368 i2c_transfer(client->adapter, msg, 1);
369 } else {
370 /* Running: ensure that device is set in 24-hour mode */
371 s32 val;
372
373 val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
374 if ((val >= 0) && (val & (1 << 6)))
375 i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
376 val & 0x3f);
377 }
378}
379
380static int ds1337_detach_client(struct i2c_client *client)
381{
382 int err;
383 struct ds1337_data *data = i2c_get_clientdata(client);
384
385 if ((err = i2c_detach_client(client)))
386 return err;
387
388 list_del(&data->list);
389 kfree(data);
390 return 0;
391}
392
393static int __init ds1337_init(void)
394{
395 return i2c_add_driver(&ds1337_driver);
396}
397
398static void __exit ds1337_exit(void)
399{
400 i2c_del_driver(&ds1337_driver);
401}
402
403MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
404MODULE_DESCRIPTION("DS1337 RTC driver");
405MODULE_LICENSE("GPL");
406
407EXPORT_SYMBOL_GPL(ds1337_do_command);
408
409module_init(ds1337_init);
410module_exit(ds1337_exit);
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c
deleted file mode 100644
index 8a2ff0c114d9..000000000000
--- a/drivers/i2c/chips/ds1374.c
+++ /dev/null
@@ -1,267 +0,0 @@
1/*
2 * drivers/i2c/chips/ds1374.c
3 *
4 * I2C client/driver for the Maxim/Dallas DS1374 Real-Time Clock
5 *
6 * Author: Randy Vinson <rvinson@mvista.com>
7 *
8 * Based on the m41t00.c by Mark Greer <mgreer@mvista.com>
9 *
10 * 2005 (c) MontaVista Software, Inc. This file is licensed under
11 * the terms of the GNU General Public License version 2. This program
12 * is licensed "as is" without any warranty of any kind, whether express
13 * or implied.
14 */
15/*
16 * This i2c client/driver wedges between the drivers/char/genrtc.c RTC
17 * interface and the SMBus interface of the i2c subsystem.
18 * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
19 * recommened in .../Documentation/i2c/writing-clients section
20 * "Sending and receiving", using SMBus level communication is preferred.
21 */
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/interrupt.h>
26#include <linux/i2c.h>
27#include <linux/rtc.h>
28#include <linux/bcd.h>
29#include <linux/mutex.h>
30#include <linux/workqueue.h>
31
32#define DS1374_REG_TOD0 0x00
33#define DS1374_REG_TOD1 0x01
34#define DS1374_REG_TOD2 0x02
35#define DS1374_REG_TOD3 0x03
36#define DS1374_REG_WDALM0 0x04
37#define DS1374_REG_WDALM1 0x05
38#define DS1374_REG_WDALM2 0x06
39#define DS1374_REG_CR 0x07
40#define DS1374_REG_SR 0x08
41#define DS1374_REG_SR_OSF 0x80
42#define DS1374_REG_TCR 0x09
43
44#define DS1374_DRV_NAME "ds1374"
45
46static DEFINE_MUTEX(ds1374_mutex);
47
48static struct i2c_driver ds1374_driver;
49static struct i2c_client *save_client;
50
51static unsigned short ignore[] = { I2C_CLIENT_END };
52static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END };
53
54static struct i2c_client_address_data addr_data = {
55 .normal_i2c = normal_addr,
56 .probe = ignore,
57 .ignore = ignore,
58};
59
60static ulong ds1374_read_rtc(void)
61{
62 ulong time = 0;
63 int reg = DS1374_REG_WDALM0;
64
65 while (reg--) {
66 s32 tmp;
67 if ((tmp = i2c_smbus_read_byte_data(save_client, reg)) < 0) {
68 dev_warn(&save_client->dev,
69 "can't read from rtc chip\n");
70 return 0;
71 }
72 time = (time << 8) | (tmp & 0xff);
73 }
74 return time;
75}
76
77static void ds1374_write_rtc(ulong time)
78{
79 int reg;
80
81 for (reg = DS1374_REG_TOD0; reg < DS1374_REG_WDALM0; reg++) {
82 if (i2c_smbus_write_byte_data(save_client, reg, time & 0xff)
83 < 0) {
84 dev_warn(&save_client->dev,
85 "can't write to rtc chip\n");
86 break;
87 }
88 time = time >> 8;
89 }
90}
91
92static void ds1374_check_rtc_status(void)
93{
94 s32 tmp;
95
96 tmp = i2c_smbus_read_byte_data(save_client, DS1374_REG_SR);
97 if (tmp < 0) {
98 dev_warn(&save_client->dev,
99 "can't read status from rtc chip\n");
100 return;
101 }
102 if (tmp & DS1374_REG_SR_OSF) {
103 dev_warn(&save_client->dev,
104 "oscillator discontinuity flagged, time unreliable\n");
105 tmp &= ~DS1374_REG_SR_OSF;
106 tmp = i2c_smbus_write_byte_data(save_client, DS1374_REG_SR,
107 tmp & 0xff);
108 if (tmp < 0)
109 dev_warn(&save_client->dev,
110 "can't clear discontinuity notification\n");
111 }
112}
113
114ulong ds1374_get_rtc_time(void)
115{
116 ulong t1, t2;
117 int limit = 10; /* arbitrary retry limit */
118
119 mutex_lock(&ds1374_mutex);
120
121 /*
122 * Since the reads are being performed one byte at a time using
123 * the SMBus vs a 4-byte i2c transfer, there is a chance that a
124 * carry will occur during the read. To detect this, 2 reads are
125 * performed and compared.
126 */
127 do {
128 t1 = ds1374_read_rtc();
129 t2 = ds1374_read_rtc();
130 } while (t1 != t2 && limit--);
131
132 mutex_unlock(&ds1374_mutex);
133
134 if (t1 != t2) {
135 dev_warn(&save_client->dev,
136 "can't get consistent time from rtc chip\n");
137 t1 = 0;
138 }
139
140 return t1;
141}
142
143static ulong new_time;
144
145static void ds1374_set_work(struct work_struct *work)
146{
147 ulong t1, t2;
148 int limit = 10; /* arbitrary retry limit */
149
150 t1 = new_time;
151
152 mutex_lock(&ds1374_mutex);
153
154 /*
155 * Since the writes are being performed one byte at a time using
156 * the SMBus vs a 4-byte i2c transfer, there is a chance that a
157 * carry will occur during the write. To detect this, the write
158 * value is read back and compared.
159 */
160 do {
161 ds1374_write_rtc(t1);
162 t2 = ds1374_read_rtc();
163 } while (t1 != t2 && limit--);
164
165 mutex_unlock(&ds1374_mutex);
166
167 if (t1 != t2)
168 dev_warn(&save_client->dev,
169 "can't confirm time set from rtc chip\n");
170}
171
172static struct workqueue_struct *ds1374_workqueue;
173
174static DECLARE_WORK(ds1374_work, ds1374_set_work);
175
176int ds1374_set_rtc_time(ulong nowtime)
177{
178 new_time = nowtime;
179
180 if (in_interrupt())
181 queue_work(ds1374_workqueue, &ds1374_work);
182 else
183 ds1374_set_work(NULL);
184
185 return 0;
186}
187
188/*
189 *****************************************************************************
190 *
191 * Driver Interface
192 *
193 *****************************************************************************
194 */
195static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind)
196{
197 struct i2c_client *client;
198 int rc;
199
200 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
201 if (!client)
202 return -ENOMEM;
203
204 strncpy(client->name, DS1374_DRV_NAME, I2C_NAME_SIZE);
205 client->addr = addr;
206 client->adapter = adap;
207 client->driver = &ds1374_driver;
208
209 ds1374_workqueue = create_singlethread_workqueue("ds1374");
210 if (!ds1374_workqueue) {
211 kfree(client);
212 return -ENOMEM; /* most expected reason */
213 }
214
215 if ((rc = i2c_attach_client(client)) != 0) {
216 kfree(client);
217 return rc;
218 }
219
220 save_client = client;
221
222 ds1374_check_rtc_status();
223
224 return 0;
225}
226
227static int ds1374_attach(struct i2c_adapter *adap)
228{
229 return i2c_probe(adap, &addr_data, ds1374_probe);
230}
231
232static int ds1374_detach(struct i2c_client *client)
233{
234 int rc;
235
236 if ((rc = i2c_detach_client(client)) == 0) {
237 kfree(i2c_get_clientdata(client));
238 destroy_workqueue(ds1374_workqueue);
239 }
240 return rc;
241}
242
243static struct i2c_driver ds1374_driver = {
244 .driver = {
245 .name = DS1374_DRV_NAME,
246 },
247 .id = I2C_DRIVERID_DS1374,
248 .attach_adapter = ds1374_attach,
249 .detach_client = ds1374_detach,
250};
251
252static int __init ds1374_init(void)
253{
254 return i2c_add_driver(&ds1374_driver);
255}
256
257static void __exit ds1374_exit(void)
258{
259 i2c_del_driver(&ds1374_driver);
260}
261
262module_init(ds1374_init);
263module_exit(ds1374_exit);
264
265MODULE_AUTHOR("Randy Vinson <rvinson@mvista.com>");
266MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC I2C Client Driver");
267MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
deleted file mode 100644
index 3fcb646e2073..000000000000
--- a/drivers/i2c/chips/m41t00.c
+++ /dev/null
@@ -1,413 +0,0 @@
1/*
2 * I2C client/driver for the ST M41T00 family of i2c rtc chips.
3 *
4 * Author: Mark A. Greer <mgreer@mvista.com>
5 *
6 * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11/*
12 * This i2c client/driver wedges between the drivers/char/genrtc.c RTC
13 * interface and the SMBus interface of the i2c subsystem.
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/interrupt.h>
19#include <linux/i2c.h>
20#include <linux/rtc.h>
21#include <linux/bcd.h>
22#include <linux/workqueue.h>
23#include <linux/platform_device.h>
24#include <linux/m41t00.h>
25#include <asm/time.h>
26#include <asm/rtc.h>
27
28static struct i2c_driver m41t00_driver;
29static struct i2c_client *save_client;
30
31static unsigned short ignore[] = { I2C_CLIENT_END };
32static unsigned short normal_addr[] = { I2C_CLIENT_END, I2C_CLIENT_END };
33
34static struct i2c_client_address_data addr_data = {
35 .normal_i2c = normal_addr,
36 .probe = ignore,
37 .ignore = ignore,
38};
39
40struct m41t00_chip_info {
41 u8 type;
42 char *name;
43 u8 read_limit;
44 u8 sec; /* Offsets for chip regs */
45 u8 min;
46 u8 hour;
47 u8 day;
48 u8 mon;
49 u8 year;
50 u8 alarm_mon;
51 u8 alarm_hour;
52 u8 sqw;
53 u8 sqw_freq;
54};
55
56static struct m41t00_chip_info m41t00_chip_info_tbl[] = {
57 {
58 .type = M41T00_TYPE_M41T00,
59 .name = "m41t00",
60 .read_limit = 5,
61 .sec = 0,
62 .min = 1,
63 .hour = 2,
64 .day = 4,
65 .mon = 5,
66 .year = 6,
67 },
68 {
69 .type = M41T00_TYPE_M41T81,
70 .name = "m41t81",
71 .read_limit = 1,
72 .sec = 1,
73 .min = 2,
74 .hour = 3,
75 .day = 5,
76 .mon = 6,
77 .year = 7,
78 .alarm_mon = 0xa,
79 .alarm_hour = 0xc,
80 .sqw = 0x13,
81 },
82 {
83 .type = M41T00_TYPE_M41T85,
84 .name = "m41t85",
85 .read_limit = 1,
86 .sec = 1,
87 .min = 2,
88 .hour = 3,
89 .day = 5,
90 .mon = 6,
91 .year = 7,
92 .alarm_mon = 0xa,
93 .alarm_hour = 0xc,
94 .sqw = 0x13,
95 },
96};
97static struct m41t00_chip_info *m41t00_chip;
98
99ulong
100m41t00_get_rtc_time(void)
101{
102 s32 sec, min, hour, day, mon, year;
103 s32 sec1, min1, hour1, day1, mon1, year1;
104 u8 reads = 0;
105 u8 buf[8], msgbuf[1] = { 0 }; /* offset into rtc's regs */
106 struct i2c_msg msgs[] = {
107 {
108 .addr = save_client->addr,
109 .flags = 0,
110 .len = 1,
111 .buf = msgbuf,
112 },
113 {
114 .addr = save_client->addr,
115 .flags = I2C_M_RD,
116 .len = 8,
117 .buf = buf,
118 },
119 };
120
121 sec = min = hour = day = mon = year = 0;
122
123 do {
124 if (i2c_transfer(save_client->adapter, msgs, 2) < 0)
125 goto read_err;
126
127 sec1 = sec;
128 min1 = min;
129 hour1 = hour;
130 day1 = day;
131 mon1 = mon;
132 year1 = year;
133
134 sec = buf[m41t00_chip->sec] & 0x7f;
135 min = buf[m41t00_chip->min] & 0x7f;
136 hour = buf[m41t00_chip->hour] & 0x3f;
137 day = buf[m41t00_chip->day] & 0x3f;
138 mon = buf[m41t00_chip->mon] & 0x1f;
139 year = buf[m41t00_chip->year];
140 } while ((++reads < m41t00_chip->read_limit) && ((sec != sec1)
141 || (min != min1) || (hour != hour1) || (day != day1)
142 || (mon != mon1) || (year != year1)));
143
144 if ((m41t00_chip->read_limit > 1) && ((sec != sec1) || (min != min1)
145 || (hour != hour1) || (day != day1) || (mon != mon1)
146 || (year != year1)))
147 goto read_err;
148
149 sec = BCD2BIN(sec);
150 min = BCD2BIN(min);
151 hour = BCD2BIN(hour);
152 day = BCD2BIN(day);
153 mon = BCD2BIN(mon);
154 year = BCD2BIN(year);
155
156 year += 1900;
157 if (year < 1970)
158 year += 100;
159
160 return mktime(year, mon, day, hour, min, sec);
161
162read_err:
163 dev_err(&save_client->dev, "m41t00_get_rtc_time: Read error\n");
164 return 0;
165}
166EXPORT_SYMBOL_GPL(m41t00_get_rtc_time);
167
168static void
169m41t00_set(void *arg)
170{
171 struct rtc_time tm;
172 int nowtime = *(int *)arg;
173 s32 sec, min, hour, day, mon, year;
174 u8 wbuf[9], *buf = &wbuf[1], msgbuf[1] = { 0 };
175 struct i2c_msg msgs[] = {
176 {
177 .addr = save_client->addr,
178 .flags = 0,
179 .len = 1,
180 .buf = msgbuf,
181 },
182 {
183 .addr = save_client->addr,
184 .flags = I2C_M_RD,
185 .len = 8,
186 .buf = buf,
187 },
188 };
189
190 to_tm(nowtime, &tm);
191 tm.tm_year = (tm.tm_year - 1900) % 100;
192
193 sec = BIN2BCD(tm.tm_sec);
194 min = BIN2BCD(tm.tm_min);
195 hour = BIN2BCD(tm.tm_hour);
196 day = BIN2BCD(tm.tm_mday);
197 mon = BIN2BCD(tm.tm_mon);
198 year = BIN2BCD(tm.tm_year);
199
200 /* Read reg values into buf[0..7]/wbuf[1..8] */
201 if (i2c_transfer(save_client->adapter, msgs, 2) < 0) {
202 dev_err(&save_client->dev, "m41t00_set: Read error\n");
203 return;
204 }
205
206 wbuf[0] = 0; /* offset into rtc's regs */
207 buf[m41t00_chip->sec] = (buf[m41t00_chip->sec] & ~0x7f) | (sec & 0x7f);
208 buf[m41t00_chip->min] = (buf[m41t00_chip->min] & ~0x7f) | (min & 0x7f);
209 buf[m41t00_chip->hour] = (buf[m41t00_chip->hour] & ~0x3f) | (hour& 0x3f);
210 buf[m41t00_chip->day] = (buf[m41t00_chip->day] & ~0x3f) | (day & 0x3f);
211 buf[m41t00_chip->mon] = (buf[m41t00_chip->mon] & ~0x1f) | (mon & 0x1f);
212 buf[m41t00_chip->year] = year;
213
214 if (i2c_master_send(save_client, wbuf, 9) < 0)
215 dev_err(&save_client->dev, "m41t00_set: Write error\n");
216}
217
218static ulong new_time;
219/* well, isn't this API just _lovely_? */
220static void
221m41t00_barf(struct work_struct *unusable)
222{
223 m41t00_set(&new_time);
224}
225
226static struct workqueue_struct *m41t00_wq;
227static DECLARE_WORK(m41t00_work, m41t00_barf);
228
229int
230m41t00_set_rtc_time(ulong nowtime)
231{
232 new_time = nowtime;
233
234 if (in_interrupt())
235 queue_work(m41t00_wq, &m41t00_work);
236 else
237 m41t00_set(&new_time);
238
239 return 0;
240}
241EXPORT_SYMBOL_GPL(m41t00_set_rtc_time);
242
243/*
244 *****************************************************************************
245 *
246 * platform_data Driver Interface
247 *
248 *****************************************************************************
249 */
250static int __init
251m41t00_platform_probe(struct platform_device *pdev)
252{
253 struct m41t00_platform_data *pdata;
254 int i;
255
256 if (pdev && (pdata = pdev->dev.platform_data)) {
257 normal_addr[0] = pdata->i2c_addr;
258
259 for (i=0; i<ARRAY_SIZE(m41t00_chip_info_tbl); i++)
260 if (m41t00_chip_info_tbl[i].type == pdata->type) {
261 m41t00_chip = &m41t00_chip_info_tbl[i];
262 m41t00_chip->sqw_freq = pdata->sqw_freq;
263 return 0;
264 }
265 }
266 return -ENODEV;
267}
268
269static int __exit
270m41t00_platform_remove(struct platform_device *pdev)
271{
272 return 0;
273}
274
275static struct platform_driver m41t00_platform_driver = {
276 .probe = m41t00_platform_probe,
277 .remove = m41t00_platform_remove,
278 .driver = {
279 .owner = THIS_MODULE,
280 .name = M41T00_DRV_NAME,
281 },
282};
283
284/*
285 *****************************************************************************
286 *
287 * Driver Interface
288 *
289 *****************************************************************************
290 */
291static int
292m41t00_probe(struct i2c_adapter *adap, int addr, int kind)
293{
294 struct i2c_client *client;
295 int rc;
296
297 if (!i2c_check_functionality(adap, I2C_FUNC_I2C
298 | I2C_FUNC_SMBUS_BYTE_DATA))
299 return 0;
300
301 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
302 if (!client)
303 return -ENOMEM;
304
305 strlcpy(client->name, m41t00_chip->name, I2C_NAME_SIZE);
306 client->addr = addr;
307 client->adapter = adap;
308 client->driver = &m41t00_driver;
309
310 if ((rc = i2c_attach_client(client)))
311 goto attach_err;
312
313 if (m41t00_chip->type != M41T00_TYPE_M41T00) {
314 /* If asked, disable SQW, set SQW frequency & re-enable */
315 if (m41t00_chip->sqw_freq)
316 if (((rc = i2c_smbus_read_byte_data(client,
317 m41t00_chip->alarm_mon)) < 0)
318 || ((rc = i2c_smbus_write_byte_data(client,
319 m41t00_chip->alarm_mon, rc & ~0x40)) <0)
320 || ((rc = i2c_smbus_write_byte_data(client,
321 m41t00_chip->sqw,
322 m41t00_chip->sqw_freq)) < 0)
323 || ((rc = i2c_smbus_write_byte_data(client,
324 m41t00_chip->alarm_mon, rc | 0x40)) <0))
325 goto sqw_err;
326
327 /* Make sure HT (Halt Update) bit is cleared */
328 if ((rc = i2c_smbus_read_byte_data(client,
329 m41t00_chip->alarm_hour)) < 0)
330 goto ht_err;
331
332 if (rc & 0x40)
333 if ((rc = i2c_smbus_write_byte_data(client,
334 m41t00_chip->alarm_hour, rc & ~0x40))<0)
335 goto ht_err;
336 }
337
338 /* Make sure ST (stop) bit is cleared */
339 if ((rc = i2c_smbus_read_byte_data(client, m41t00_chip->sec)) < 0)
340 goto st_err;
341
342 if (rc & 0x80)
343 if ((rc = i2c_smbus_write_byte_data(client, m41t00_chip->sec,
344 rc & ~0x80)) < 0)
345 goto st_err;
346
347 m41t00_wq = create_singlethread_workqueue(m41t00_chip->name);
348 save_client = client;
349 return 0;
350
351st_err:
352 dev_err(&client->dev, "m41t00_probe: Can't clear ST bit\n");
353 goto attach_err;
354ht_err:
355 dev_err(&client->dev, "m41t00_probe: Can't clear HT bit\n");
356 goto attach_err;
357sqw_err:
358 dev_err(&client->dev, "m41t00_probe: Can't set SQW Frequency\n");
359attach_err:
360 kfree(client);
361 return rc;
362}
363
364static int
365m41t00_attach(struct i2c_adapter *adap)
366{
367 return i2c_probe(adap, &addr_data, m41t00_probe);
368}
369
370static int
371m41t00_detach(struct i2c_client *client)
372{
373 int rc;
374
375 if ((rc = i2c_detach_client(client)) == 0) {
376 kfree(client);
377 destroy_workqueue(m41t00_wq);
378 }
379 return rc;
380}
381
382static struct i2c_driver m41t00_driver = {
383 .driver = {
384 .name = M41T00_DRV_NAME,
385 },
386 .id = I2C_DRIVERID_STM41T00,
387 .attach_adapter = m41t00_attach,
388 .detach_client = m41t00_detach,
389};
390
391static int __init
392m41t00_init(void)
393{
394 int rc;
395
396 if (!(rc = platform_driver_register(&m41t00_platform_driver)))
397 rc = i2c_add_driver(&m41t00_driver);
398 return rc;
399}
400
401static void __exit
402m41t00_exit(void)
403{
404 i2c_del_driver(&m41t00_driver);
405 platform_driver_unregister(&m41t00_platform_driver);
406}
407
408module_init(m41t00_init);
409module_exit(m41t00_exit);
410
411MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>");
412MODULE_DESCRIPTION("ST Microelectronics M41T00 RTC I2C Client Driver");
413MODULE_LICENSE("GPL");