2 * w1_ds2408.c - w1 family 29 (DS2408) driver
4 * Copyright (c) 2010 Jean-Francois Dagenais <dagenaisj@sonatest.com>
6 * This source code is licensed under the GNU General Public License,
7 * Version 2. See the file COPYING for more details.
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/moduleparam.h>
13 #include <linux/device.h>
14 #include <linux/types.h>
15 #include <linux/delay.h>
16 #include <linux/slab.h>
20 #define W1_FAMILY_DS2408 0x29
22 #define W1_F29_RETRIES 3
24 #define W1_F29_REG_LOGIG_STATE 0x88 /* R */
25 #define W1_F29_REG_OUTPUT_LATCH_STATE 0x89 /* R */
26 #define W1_F29_REG_ACTIVITY_LATCH_STATE 0x8A /* R */
27 #define W1_F29_REG_COND_SEARCH_SELECT_MASK 0x8B /* RW */
28 #define W1_F29_REG_COND_SEARCH_POL_SELECT 0x8C /* RW */
29 #define W1_F29_REG_CONTROL_AND_STATUS 0x8D /* RW */
31 #define W1_F29_FUNC_READ_PIO_REGS 0xF0
32 #define W1_F29_FUNC_CHANN_ACCESS_READ 0xF5
33 #define W1_F29_FUNC_CHANN_ACCESS_WRITE 0x5A
34 /* also used to write the control/status reg (0x8D): */
35 #define W1_F29_FUNC_WRITE_COND_SEARCH_REG 0xCC
36 #define W1_F29_FUNC_RESET_ACTIVITY_LATCHES 0xC3
38 #define W1_F29_SUCCESS_CONFIRM_BYTE 0xAA
40 static int _read_reg(struct w1_slave
*sl
, u8 address
, unsigned char* buf
)
44 "Reading with slave: %p, reg addr: %0#4x, buff addr: %p",
45 sl
, (unsigned int)address
, buf
);
50 mutex_lock(&sl
->master
->bus_mutex
);
51 dev_dbg(&sl
->dev
, "mutex locked");
53 if (w1_reset_select_slave(sl
)) {
54 mutex_unlock(&sl
->master
->bus_mutex
);
58 wrbuf
[0] = W1_F29_FUNC_READ_PIO_REGS
;
61 w1_write_block(sl
->master
, wrbuf
, 3);
62 *buf
= w1_read_8(sl
->master
);
64 mutex_unlock(&sl
->master
->bus_mutex
);
65 dev_dbg(&sl
->dev
, "mutex unlocked");
69 static ssize_t
state_read(struct file
*filp
, struct kobject
*kobj
,
70 struct bin_attribute
*bin_attr
, char *buf
, loff_t off
,
73 dev_dbg(&kobj_to_w1_slave(kobj
)->dev
,
74 "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
75 bin_attr
->attr
.name
, kobj
, (unsigned int)off
, count
, buf
);
76 if (count
!= 1 || off
!= 0)
78 return _read_reg(kobj_to_w1_slave(kobj
), W1_F29_REG_LOGIG_STATE
, buf
);
81 static ssize_t
output_read(struct file
*filp
, struct kobject
*kobj
,
82 struct bin_attribute
*bin_attr
, char *buf
,
83 loff_t off
, size_t count
)
85 dev_dbg(&kobj_to_w1_slave(kobj
)->dev
,
86 "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
87 bin_attr
->attr
.name
, kobj
, (unsigned int)off
, count
, buf
);
88 if (count
!= 1 || off
!= 0)
90 return _read_reg(kobj_to_w1_slave(kobj
),
91 W1_F29_REG_OUTPUT_LATCH_STATE
, buf
);
94 static ssize_t
activity_read(struct file
*filp
, struct kobject
*kobj
,
95 struct bin_attribute
*bin_attr
, char *buf
,
96 loff_t off
, size_t count
)
98 dev_dbg(&kobj_to_w1_slave(kobj
)->dev
,
99 "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
100 bin_attr
->attr
.name
, kobj
, (unsigned int)off
, count
, buf
);
101 if (count
!= 1 || off
!= 0)
103 return _read_reg(kobj_to_w1_slave(kobj
),
104 W1_F29_REG_ACTIVITY_LATCH_STATE
, buf
);
107 static ssize_t
cond_search_mask_read(struct file
*filp
, struct kobject
*kobj
,
108 struct bin_attribute
*bin_attr
, char *buf
,
109 loff_t off
, size_t count
)
111 dev_dbg(&kobj_to_w1_slave(kobj
)->dev
,
112 "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
113 bin_attr
->attr
.name
, kobj
, (unsigned int)off
, count
, buf
);
114 if (count
!= 1 || off
!= 0)
116 return _read_reg(kobj_to_w1_slave(kobj
),
117 W1_F29_REG_COND_SEARCH_SELECT_MASK
, buf
);
120 static ssize_t
cond_search_polarity_read(struct file
*filp
,
121 struct kobject
*kobj
,
122 struct bin_attribute
*bin_attr
,
123 char *buf
, loff_t off
, size_t count
)
125 if (count
!= 1 || off
!= 0)
127 return _read_reg(kobj_to_w1_slave(kobj
),
128 W1_F29_REG_COND_SEARCH_POL_SELECT
, buf
);
131 static ssize_t
status_control_read(struct file
*filp
, struct kobject
*kobj
,
132 struct bin_attribute
*bin_attr
, char *buf
,
133 loff_t off
, size_t count
)
135 if (count
!= 1 || off
!= 0)
137 return _read_reg(kobj_to_w1_slave(kobj
),
138 W1_F29_REG_CONTROL_AND_STATUS
, buf
);
141 static ssize_t
output_write(struct file
*filp
, struct kobject
*kobj
,
142 struct bin_attribute
*bin_attr
, char *buf
,
143 loff_t off
, size_t count
)
145 struct w1_slave
*sl
= kobj_to_w1_slave(kobj
);
148 unsigned int retries
= W1_F29_RETRIES
;
150 if (count
!= 1 || off
!= 0)
153 dev_dbg(&sl
->dev
, "locking mutex for write_output");
154 mutex_lock(&sl
->master
->bus_mutex
);
155 dev_dbg(&sl
->dev
, "mutex locked");
157 if (w1_reset_select_slave(sl
))
161 w1_buf
[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE
;
164 w1_write_block(sl
->master
, w1_buf
, 3);
166 readBack
= w1_read_8(sl
->master
);
168 if (readBack
!= W1_F29_SUCCESS_CONFIRM_BYTE
) {
169 if (w1_reset_resume_command(sl
->master
))
171 /* try again, the slave is ready for a command */
175 #ifdef CONFIG_W1_SLAVE_DS2408_READBACK
176 /* here the master could read another byte which
177 would be the PIO reg (the actual pin logic state)
178 since in this driver we don't know which pins are
179 in and outs, there's no value to read the state and
180 compare. with (*buf) so end this command abruptly: */
181 if (w1_reset_resume_command(sl
->master
))
184 /* go read back the output latches */
185 /* (the direct effect of the write above) */
186 w1_buf
[0] = W1_F29_FUNC_READ_PIO_REGS
;
187 w1_buf
[1] = W1_F29_REG_OUTPUT_LATCH_STATE
;
189 w1_write_block(sl
->master
, w1_buf
, 3);
190 /* read the result of the READ_PIO_REGS command */
191 if (w1_read_8(sl
->master
) == *buf
)
195 mutex_unlock(&sl
->master
->bus_mutex
);
197 "mutex unlocked, retries:%d", retries
);
202 mutex_unlock(&sl
->master
->bus_mutex
);
203 dev_dbg(&sl
->dev
, "mutex unlocked in error, retries:%d", retries
);
210 * Writing to the activity file resets the activity latches.
212 static ssize_t
activity_write(struct file
*filp
, struct kobject
*kobj
,
213 struct bin_attribute
*bin_attr
, char *buf
,
214 loff_t off
, size_t count
)
216 struct w1_slave
*sl
= kobj_to_w1_slave(kobj
);
217 unsigned int retries
= W1_F29_RETRIES
;
219 if (count
!= 1 || off
!= 0)
222 mutex_lock(&sl
->master
->bus_mutex
);
224 if (w1_reset_select_slave(sl
))
228 w1_write_8(sl
->master
, W1_F29_FUNC_RESET_ACTIVITY_LATCHES
);
229 if (w1_read_8(sl
->master
) == W1_F29_SUCCESS_CONFIRM_BYTE
) {
230 mutex_unlock(&sl
->master
->bus_mutex
);
233 if (w1_reset_resume_command(sl
->master
))
238 mutex_unlock(&sl
->master
->bus_mutex
);
242 static ssize_t
status_control_write(struct file
*filp
, struct kobject
*kobj
,
243 struct bin_attribute
*bin_attr
, char *buf
,
244 loff_t off
, size_t count
)
246 struct w1_slave
*sl
= kobj_to_w1_slave(kobj
);
248 unsigned int retries
= W1_F29_RETRIES
;
250 if (count
!= 1 || off
!= 0)
253 mutex_lock(&sl
->master
->bus_mutex
);
255 if (w1_reset_select_slave(sl
))
259 w1_buf
[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG
;
260 w1_buf
[1] = W1_F29_REG_CONTROL_AND_STATUS
;
264 w1_write_block(sl
->master
, w1_buf
, 4);
265 if (w1_reset_resume_command(sl
->master
))
268 w1_buf
[0] = W1_F29_FUNC_READ_PIO_REGS
;
269 w1_buf
[1] = W1_F29_REG_CONTROL_AND_STATUS
;
272 w1_write_block(sl
->master
, w1_buf
, 3);
273 if (w1_read_8(sl
->master
) == *buf
) {
275 mutex_unlock(&sl
->master
->bus_mutex
);
280 mutex_unlock(&sl
->master
->bus_mutex
);
286 * This is a special sequence we must do to ensure the P0 output is not stuck
287 * in test mode. This is described in rev 2 of the ds2408's datasheet
288 * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under
289 * "APPLICATION INFORMATION/Power-up timing".
291 static int w1_f29_disable_test_mode(struct w1_slave
*sl
)
294 u8 magic
[10] = {0x96, };
295 u64 rn
= le64_to_cpu(*((u64
*)&sl
->reg_num
));
297 memcpy(&magic
[1], &rn
, 8);
300 mutex_lock(&sl
->master
->bus_mutex
);
302 res
= w1_reset_bus(sl
->master
);
305 w1_write_block(sl
->master
, magic
, ARRAY_SIZE(magic
));
307 res
= w1_reset_bus(sl
->master
);
309 mutex_unlock(&sl
->master
->bus_mutex
);
313 static BIN_ATTR_RO(state
, 1);
314 static BIN_ATTR_RW(output
, 1);
315 static BIN_ATTR_RW(activity
, 1);
316 static BIN_ATTR_RO(cond_search_mask
, 1);
317 static BIN_ATTR_RO(cond_search_polarity
, 1);
318 static BIN_ATTR_RW(status_control
, 1);
320 static struct bin_attribute
*w1_f29_bin_attrs
[] = {
324 &bin_attr_cond_search_mask
,
325 &bin_attr_cond_search_polarity
,
326 &bin_attr_status_control
,
330 static const struct attribute_group w1_f29_group
= {
331 .bin_attrs
= w1_f29_bin_attrs
,
334 static const struct attribute_group
*w1_f29_groups
[] = {
339 static struct w1_family_ops w1_f29_fops
= {
340 .add_slave
= w1_f29_disable_test_mode
,
341 .groups
= w1_f29_groups
,
344 static struct w1_family w1_family_29
= {
345 .fid
= W1_FAMILY_DS2408
,
346 .fops
= &w1_f29_fops
,
348 module_w1_family(w1_family_29
);
350 MODULE_AUTHOR("Jean-Francois Dagenais <dagenaisj@sonatest.com>");
351 MODULE_DESCRIPTION("w1 family 29 driver for DS2408 8 Pin IO");
352 MODULE_LICENSE("GPL");
353 MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2408
));