aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeniy Polyakov <johnpol@2ka.mipt.ru>2005-12-06 05:38:28 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-23 20:28:12 -0500
commitbaf12ae29ab4cc6381e21b2e1a3af75a6a8f7566 (patch)
tree43658918e7221e94e40a62de48f04b2b23d75b3a
parentbd529cfb40c427d5b5aae0d315afb9f0a1da5e76 (diff)
[PATCH] W1: Add the DS2482 I2C-to-w1 bridge driver.
Signed-off-by: Ben Gardner <bgardner@wabtec.com> Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--Documentation/w1/masters/ds248231
-rw-r--r--drivers/w1/masters/Kconfig10
-rw-r--r--drivers/w1/masters/Makefile2
-rw-r--r--drivers/w1/masters/ds2482.c564
4 files changed, 607 insertions, 0 deletions
diff --git a/Documentation/w1/masters/ds2482 b/Documentation/w1/masters/ds2482
new file mode 100644
index 000000000000..c5d5478d90b2
--- /dev/null
+++ b/Documentation/w1/masters/ds2482
@@ -0,0 +1,31 @@
1Kernel driver ds2482
2====================
3
4Supported chips:
5 * Maxim DS2482-100, Maxim DS2482-800
6 Prefix: 'ds2482'
7 Addresses scanned: None
8 Datasheets:
9 http://pdfserv.maxim-ic.com/en/ds/DS2482-100-DS2482S-100.pdf
10 http://pdfserv.maxim-ic.com/en/ds/DS2482-800-DS2482S-800.pdf
11
12Author: Ben Gardner <bgardner@wabtec.com>
13
14
15Description
16-----------
17
18The Maixm/Dallas Semiconductor DS2482 is a I2C device that provides
19one (DS2482-100) or eight (DS2482-800) 1-wire busses.
20
21
22General Remarks
23---------------
24
25Valid addresses are 0x18, 0x19, 0x1a, and 0x1b.
26However, the device cannot be detected without writing to the i2c bus, so no
27detection is done.
28You should force the device address.
29
30$ modprobe ds2482 force=0,0x18
31
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig
index 51bd64d0e54d..1ff11b5a3ad2 100644
--- a/drivers/w1/masters/Kconfig
+++ b/drivers/w1/masters/Kconfig
@@ -34,5 +34,15 @@ config W1_MASTER_DS9490_BRIDGE
34 This support is also available as a module. If so, the module 34 This support is also available as a module. If so, the module
35 will be called ds_w1_bridge.ko. 35 will be called ds_w1_bridge.ko.
36 36
37config W1_MASTER_DS2482
38 tristate "Maxim DS2482 I2C to 1-Wire bridge"
39 depends on I2C && W1 && EXPERIMENTAL
40 help
41 If you say yes here you get support for the Maxim DS2482
42 I2C to 1-Wire bridge.
43
44 This driver can also be built as a module. If so, the module
45 will be called ds2482.
46
37endmenu 47endmenu
38 48
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile
index d9b84e522d6c..1f3c8b983dc1 100644
--- a/drivers/w1/masters/Makefile
+++ b/drivers/w1/masters/Makefile
@@ -9,3 +9,5 @@ ds9490r-objs := dscore.o
9 9
10obj-$(CONFIG_W1_MASTER_DS9490_BRIDGE) += ds_w1_bridge.o 10obj-$(CONFIG_W1_MASTER_DS9490_BRIDGE) += ds_w1_bridge.o
11 11
12obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o
13
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c
new file mode 100644
index 000000000000..d1cacd23576b
--- /dev/null
+++ b/drivers/w1/masters/ds2482.c
@@ -0,0 +1,564 @@
1/**
2 * ds2482.c - provides i2c to w1-master bridge(s)
3 * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
4 *
5 * The DS2482 is a sensor chip made by Dallas Semiconductor (Maxim).
6 * It is a I2C to 1-wire bridge.
7 * There are two variations: -100 and -800, which have 1 or 8 1-wire ports.
8 * The complete datasheet can be obtained from MAXIM's website at:
9 * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/4382
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
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/delay.h>
21#include <asm/delay.h>
22
23#include "../w1.h"
24#include "../w1_int.h"
25
26/**
27 * Address is selected using 2 pins, resulting in 4 possible addresses.
28 * 0x18, 0x19, 0x1a, 0x1b
29 * However, the chip cannot be detected without doing an i2c write,
30 * so use the force module parameter.
31 */
32static unsigned short normal_i2c[] = {I2C_CLIENT_END};
33
34/**
35 * Insmod parameters
36 */
37I2C_CLIENT_INSMOD_1(ds2482);
38
39/**
40 * The DS2482 registers - there are 3 registers that are addressed by a read
41 * pointer. The read pointer is set by the last command executed.
42 *
43 * To read the data, issue a register read for any address
44 */
45#define DS2482_CMD_RESET 0xF0 /* No param */
46#define DS2482_CMD_SET_READ_PTR 0xE1 /* Param: DS2482_PTR_CODE_xxx */
47#define DS2482_CMD_CHANNEL_SELECT 0xC3 /* Param: Channel byte - DS2482-800 only */
48#define DS2482_CMD_WRITE_CONFIG 0xD2 /* Param: Config byte */
49#define DS2482_CMD_1WIRE_RESET 0xB4 /* Param: None */
50#define DS2482_CMD_1WIRE_SINGLE_BIT 0x87 /* Param: Bit byte (bit7) */
51#define DS2482_CMD_1WIRE_WRITE_BYTE 0xA5 /* Param: Data byte */
52#define DS2482_CMD_1WIRE_READ_BYTE 0x96 /* Param: None */
53/* Note to read the byte, Set the ReadPtr to Data then read (any addr) */
54#define DS2482_CMD_1WIRE_TRIPLET 0x78 /* Param: Dir byte (bit7) */
55
56/* Values for DS2482_CMD_SET_READ_PTR */
57#define DS2482_PTR_CODE_STATUS 0xF0
58#define DS2482_PTR_CODE_DATA 0xE1
59#define DS2482_PTR_CODE_CHANNEL 0xD2 /* DS2482-800 only */
60#define DS2482_PTR_CODE_CONFIG 0xC3
61
62/**
63 * Configure Register bit definitions
64 * The top 4 bits always read 0.
65 * To write, the top nibble must be the 1's compl. of the low nibble.
66 */
67#define DS2482_REG_CFG_1WS 0x08
68#define DS2482_REG_CFG_SPU 0x04
69#define DS2482_REG_CFG_PPM 0x02
70#define DS2482_REG_CFG_APU 0x01
71
72
73/**
74 * Write and verify codes for the CHANNEL_SELECT command (DS2482-800 only).
75 * To set the channel, write the value at the index of the channel.
76 * Read and compare against the corresponding value to verify the change.
77 */
78static const u8 ds2482_chan_wr[8] =
79 { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 };
80static const u8 ds2482_chan_rd[8] =
81 { 0xB8, 0xB1, 0xAA, 0xA3, 0x9C, 0x95, 0x8E, 0x87 };
82
83
84/**
85 * Status Register bit definitions (read only)
86 */
87#define DS2482_REG_STS_DIR 0x80
88#define DS2482_REG_STS_TSB 0x40
89#define DS2482_REG_STS_SBR 0x20
90#define DS2482_REG_STS_RST 0x10
91#define DS2482_REG_STS_LL 0x08
92#define DS2482_REG_STS_SD 0x04
93#define DS2482_REG_STS_PPD 0x02
94#define DS2482_REG_STS_1WB 0x01
95
96
97static int ds2482_attach_adapter(struct i2c_adapter *adapter);
98static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind);
99static int ds2482_detach_client(struct i2c_client *client);
100
101
102/**
103 * Driver data (common to all clients)
104 */
105static struct i2c_driver ds2482_driver = {
106 .driver = {
107 .owner = THIS_MODULE,
108 .name = "ds2482",
109 },
110 .attach_adapter = ds2482_attach_adapter,
111 .detach_client = ds2482_detach_client,
112};
113
114/*
115 * Client data (each client gets its own)
116 */
117
118struct ds2482_data;
119
120struct ds2482_w1_chan {
121 struct ds2482_data *pdev;
122 u8 channel;
123 struct w1_bus_master w1_bm;
124};
125
126struct ds2482_data {
127 struct i2c_client client;
128 struct semaphore access_lock;
129
130 /* 1-wire interface(s) */
131 int w1_count; /* 1 or 8 */
132 struct ds2482_w1_chan w1_ch[8];
133
134 /* per-device values */
135 u8 channel;
136 u8 read_prt; /* see DS2482_PTR_CODE_xxx */
137 u8 reg_config;
138};
139
140
141/**
142 * Sets the read pointer.
143 * @param pdev The ds2482 client pointer
144 * @param read_ptr see DS2482_PTR_CODE_xxx above
145 * @return -1 on failure, 0 on success
146 */
147static inline int ds2482_select_register(struct ds2482_data *pdev, u8 read_ptr)
148{
149 if (pdev->read_prt != read_ptr) {
150 if (i2c_smbus_write_byte_data(&pdev->client,
151 DS2482_CMD_SET_READ_PTR,
152 read_ptr) < 0)
153 return -1;
154
155 pdev->read_prt = read_ptr;
156 }
157 return 0;
158}
159
160/**
161 * Sends a command without a parameter
162 * @param pdev The ds2482 client pointer
163 * @param cmd DS2482_CMD_RESET,
164 * DS2482_CMD_1WIRE_RESET,
165 * DS2482_CMD_1WIRE_READ_BYTE
166 * @return -1 on failure, 0 on success
167 */
168static inline int ds2482_send_cmd(struct ds2482_data *pdev, u8 cmd)
169{
170 if (i2c_smbus_write_byte(&pdev->client, cmd) < 0)
171 return -1;
172
173 pdev->read_prt = DS2482_PTR_CODE_STATUS;
174 return 0;
175}
176
177/**
178 * Sends a command with a parameter
179 * @param pdev The ds2482 client pointer
180 * @param cmd DS2482_CMD_WRITE_CONFIG,
181 * DS2482_CMD_1WIRE_SINGLE_BIT,
182 * DS2482_CMD_1WIRE_WRITE_BYTE,
183 * DS2482_CMD_1WIRE_TRIPLET
184 * @param byte The data to send
185 * @return -1 on failure, 0 on success
186 */
187static inline int ds2482_send_cmd_data(struct ds2482_data *pdev,
188 u8 cmd, u8 byte)
189{
190 if (i2c_smbus_write_byte_data(&pdev->client, cmd, byte) < 0)
191 return -1;
192
193 /* all cmds leave in STATUS, except CONFIG */
194 pdev->read_prt = (cmd != DS2482_CMD_WRITE_CONFIG) ?
195 DS2482_PTR_CODE_STATUS : DS2482_PTR_CODE_CONFIG;
196 return 0;
197}
198
199
200/*
201 * 1-Wire interface code
202 */
203
204#define DS2482_WAIT_IDLE_TIMEOUT 100
205
206/**
207 * Waits until the 1-wire interface is idle (not busy)
208 *
209 * @param pdev Pointer to the device structure
210 * @return the last value read from status or -1 (failure)
211 */
212static int ds2482_wait_1wire_idle(struct ds2482_data *pdev)
213{
214 int temp = -1;
215 int retries = 0;
216
217 if (!ds2482_select_register(pdev, DS2482_PTR_CODE_STATUS)) {
218 do {
219 temp = i2c_smbus_read_byte(&pdev->client);
220 } while ((temp >= 0) && (temp & DS2482_REG_STS_1WB) &&
221 (++retries > DS2482_WAIT_IDLE_TIMEOUT));
222 }
223
224 if (retries > DS2482_WAIT_IDLE_TIMEOUT)
225 printk(KERN_ERR "%s: timeout on channel %d\n",
226 __func__, pdev->channel);
227
228 return temp;
229}
230
231/**
232 * Selects a w1 channel.
233 * The 1-wire interface must be idle before calling this function.
234 *
235 * @param pdev The ds2482 client pointer
236 * @param channel 0-7
237 * @return -1 (failure) or 0 (success)
238 */
239static int ds2482_set_channel(struct ds2482_data *pdev, u8 channel)
240{
241 if (i2c_smbus_write_byte_data(&pdev->client, DS2482_CMD_CHANNEL_SELECT,
242 ds2482_chan_wr[channel]) < 0)
243 return -1;
244
245 pdev->read_prt = DS2482_PTR_CODE_CHANNEL;
246 pdev->channel = -1;
247 if (i2c_smbus_read_byte(&pdev->client) == ds2482_chan_rd[channel]) {
248 pdev->channel = channel;
249 return 0;
250 }
251 return -1;
252}
253
254
255/**
256 * Performs the touch-bit function, which writes a 0 or 1 and reads the level.
257 *
258 * @param data The ds2482 channel pointer
259 * @param bit The level to write: 0 or non-zero
260 * @return The level read: 0 or 1
261 */
262static u8 ds2482_w1_touch_bit(void *data, u8 bit)
263{
264 struct ds2482_w1_chan *pchan = data;
265 struct ds2482_data *pdev = pchan->pdev;
266 int status = -1;
267
268 down(&pdev->access_lock);
269
270 /* Select the channel */
271 ds2482_wait_1wire_idle(pdev);
272 if (pdev->w1_count > 1)
273 ds2482_set_channel(pdev, pchan->channel);
274
275 /* Send the touch command, wait until 1WB == 0, return the status */
276 if (!ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_SINGLE_BIT,
277 bit ? 0xFF : 0))
278 status = ds2482_wait_1wire_idle(pdev);
279
280 up(&pdev->access_lock);
281
282 return (status & DS2482_REG_STS_SBR) ? 1 : 0;
283}
284
285/**
286 * Performs the triplet function, which reads two bits and writes a bit.
287 * The bit written is determined by the two reads:
288 * 00 => dbit, 01 => 0, 10 => 1
289 *
290 * @param data The ds2482 channel pointer
291 * @param dbit The direction to choose if both branches are valid
292 * @return b0=read1 b1=read2 b3=bit written
293 */
294static u8 ds2482_w1_triplet(void *data, u8 dbit)
295{
296 struct ds2482_w1_chan *pchan = data;
297 struct ds2482_data *pdev = pchan->pdev;
298 int status = (3 << 5);
299
300 down(&pdev->access_lock);
301
302 /* Select the channel */
303 ds2482_wait_1wire_idle(pdev);
304 if (pdev->w1_count > 1)
305 ds2482_set_channel(pdev, pchan->channel);
306
307 /* Send the triplet command, wait until 1WB == 0, return the status */
308 if (!ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_TRIPLET,
309 dbit ? 0xFF : 0))
310 status = ds2482_wait_1wire_idle(pdev);
311
312 up(&pdev->access_lock);
313
314 /* Decode the status */
315 return (status >> 5);
316}
317
318/**
319 * Performs the write byte function.
320 *
321 * @param data The ds2482 channel pointer
322 * @param byte The value to write
323 */
324static void ds2482_w1_write_byte(void *data, u8 byte)
325{
326 struct ds2482_w1_chan *pchan = data;
327 struct ds2482_data *pdev = pchan->pdev;
328
329 down(&pdev->access_lock);
330
331 /* Select the channel */
332 ds2482_wait_1wire_idle(pdev);
333 if (pdev->w1_count > 1)
334 ds2482_set_channel(pdev, pchan->channel);
335
336 /* Send the write byte command */
337 ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_WRITE_BYTE, byte);
338
339 up(&pdev->access_lock);
340}
341
342/**
343 * Performs the read byte function.
344 *
345 * @param data The ds2482 channel pointer
346 * @return The value read
347 */
348static u8 ds2482_w1_read_byte(void *data)
349{
350 struct ds2482_w1_chan *pchan = data;
351 struct ds2482_data *pdev = pchan->pdev;
352 int result;
353
354 down(&pdev->access_lock);
355
356 /* Select the channel */
357 ds2482_wait_1wire_idle(pdev);
358 if (pdev->w1_count > 1)
359 ds2482_set_channel(pdev, pchan->channel);
360
361 /* Send the read byte command */
362 ds2482_send_cmd(pdev, DS2482_CMD_1WIRE_READ_BYTE);
363
364 /* Wait until 1WB == 0 */
365 ds2482_wait_1wire_idle(pdev);
366
367 /* Select the data register */
368 ds2482_select_register(pdev, DS2482_PTR_CODE_DATA);
369
370 /* Read the data byte */
371 result = i2c_smbus_read_byte(&pdev->client);
372
373 up(&pdev->access_lock);
374
375 return result;
376}
377
378
379/**
380 * Sends a reset on the 1-wire interface
381 *
382 * @param data The ds2482 channel pointer
383 * @return 0=Device present, 1=No device present or error
384 */
385static u8 ds2482_w1_reset_bus(void *data)
386{
387 struct ds2482_w1_chan *pchan = data;
388 struct ds2482_data *pdev = pchan->pdev;
389 int err;
390 u8 retval = 1;
391
392 down(&pdev->access_lock);
393
394 /* Select the channel */
395 ds2482_wait_1wire_idle(pdev);
396 if (pdev->w1_count > 1)
397 ds2482_set_channel(pdev, pchan->channel);
398
399 /* Send the reset command */
400 err = ds2482_send_cmd(pdev, DS2482_CMD_1WIRE_RESET);
401 if (err >= 0) {
402 /* Wait until the reset is complete */
403 err = ds2482_wait_1wire_idle(pdev);
404 retval = !(err & DS2482_REG_STS_PPD);
405
406 /* If the chip did reset since detect, re-config it */
407 if (err & DS2482_REG_STS_RST)
408 ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG,
409 0xF0);
410 }
411
412 up(&pdev->access_lock);
413
414 return retval;
415}
416
417
418/**
419 * Called to see if the device exists on an i2c bus.
420 */
421static int ds2482_attach_adapter(struct i2c_adapter *adapter)
422{
423 return i2c_probe(adapter, &addr_data, ds2482_detect);
424}
425
426
427/*
428 * The following function does more than just detection. If detection
429 * succeeds, it also registers the new chip.
430 */
431static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind)
432{
433 struct ds2482_data *data;
434 struct i2c_client *new_client;
435 int err = 0;
436 int temp1;
437 int idx;
438
439 if (!i2c_check_functionality(adapter,
440 I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
441 I2C_FUNC_SMBUS_BYTE))
442 goto exit;
443
444 if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) {
445 err = -ENOMEM;
446 goto exit;
447 }
448
449 new_client = &data->client;
450 i2c_set_clientdata(new_client, data);
451 new_client->addr = address;
452 new_client->driver = &ds2482_driver;
453 new_client->adapter = adapter;
454
455 /* Reset the device (sets the read_ptr to status) */
456 if (ds2482_send_cmd(data, DS2482_CMD_RESET) < 0) {
457 dev_dbg(&adapter->dev, "DS2482 reset failed at 0x%02x.\n",
458 address);
459 goto exit_free;
460 }
461
462 /* Sleep at least 525ns to allow the reset to complete */
463 ndelay(525);
464
465 /* Read the status byte - only reset bit and line should be set */
466 temp1 = i2c_smbus_read_byte(new_client);
467 if (temp1 != (DS2482_REG_STS_LL | DS2482_REG_STS_RST)) {
468 dev_dbg(&adapter->dev, "DS2482 (0x%02x) reset status "
469 "0x%02X - not a DS2482\n", address, temp1);
470 goto exit_free;
471 }
472
473 /* Detect the 8-port version */
474 data->w1_count = 1;
475 if (ds2482_set_channel(data, 7) == 0)
476 data->w1_count = 8;
477
478 /* Set all config items to 0 (off) */
479 ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, 0xF0);
480
481 /* We can fill in the remaining client fields */
482 snprintf(new_client->name, sizeof(new_client->name), "ds2482-%d00",
483 data->w1_count);
484
485 init_MUTEX(&data->access_lock);
486
487 /* Tell the I2C layer a new client has arrived */
488 if ((err = i2c_attach_client(new_client)))
489 goto exit_free;
490
491 /* Register 1-wire interface(s) */
492 for (idx = 0; idx < data->w1_count; idx++) {
493 data->w1_ch[idx].pdev = data;
494 data->w1_ch[idx].channel = idx;
495
496 /* Populate all the w1 bus master stuff */
497 data->w1_ch[idx].w1_bm.data = &data->w1_ch[idx];
498 data->w1_ch[idx].w1_bm.read_byte = ds2482_w1_read_byte;
499 data->w1_ch[idx].w1_bm.write_byte = ds2482_w1_write_byte;
500 data->w1_ch[idx].w1_bm.touch_bit = ds2482_w1_touch_bit;
501 data->w1_ch[idx].w1_bm.triplet = ds2482_w1_triplet;
502 data->w1_ch[idx].w1_bm.reset_bus = ds2482_w1_reset_bus;
503
504 err = w1_add_master_device(&data->w1_ch[idx].w1_bm);
505 if (err) {
506 data->w1_ch[idx].pdev = NULL;
507 goto exit_w1_remove;
508 }
509 }
510
511 return 0;
512
513exit_w1_remove:
514 i2c_detach_client(new_client);
515
516 for (idx = 0; idx < data->w1_count; idx++) {
517 if (data->w1_ch[idx].pdev != NULL)
518 w1_remove_master_device(&data->w1_ch[idx].w1_bm);
519 }
520exit_free:
521 kfree(data);
522exit:
523 return err;
524}
525
526static int ds2482_detach_client(struct i2c_client *client)
527{
528 struct ds2482_data *data = i2c_get_clientdata(client);
529 int err, idx;
530
531 /* Unregister the 1-wire bridge(s) */
532 for (idx = 0; idx < data->w1_count; idx++) {
533 if (data->w1_ch[idx].pdev != NULL)
534 w1_remove_master_device(&data->w1_ch[idx].w1_bm);
535 }
536
537 /* Detach the i2c device */
538 if ((err = i2c_detach_client(client))) {
539 dev_err(&client->dev,
540 "Deregistration failed, client not detached.\n");
541 return err;
542 }
543
544 /* Free the memory */
545 kfree(data);
546 return 0;
547}
548
549static int __init sensors_ds2482_init(void)
550{
551 return i2c_add_driver(&ds2482_driver);
552}
553
554static void __exit sensors_ds2482_exit(void)
555{
556 i2c_del_driver(&ds2482_driver);
557}
558
559MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
560MODULE_DESCRIPTION("DS2482 driver");
561MODULE_LICENSE("GPL");
562
563module_init(sensors_ds2482_init);
564module_exit(sensors_ds2482_exit);