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>
19 #include "../w1_int.h"
20 #include "../w1_family.h"
22 MODULE_LICENSE("GPL");
23 MODULE_AUTHOR("Jean-Francois Dagenais <dagenaisj@sonatest.com>");
24 MODULE_DESCRIPTION("w1 family 29 driver for DS2408 8 Pin IO");
25 MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2408));
28 #define W1_F29_RETRIES 3
30 #define W1_F29_REG_LOGIG_STATE 0x88 /* R */
31 #define W1_F29_REG_OUTPUT_LATCH_STATE 0x89 /* R */
32 #define W1_F29_REG_ACTIVITY_LATCH_STATE 0x8A /* R */
33 #define W1_F29_REG_COND_SEARCH_SELECT_MASK 0x8B /* RW */
34 #define W1_F29_REG_COND_SEARCH_POL_SELECT 0x8C /* RW */
35 #define W1_F29_REG_CONTROL_AND_STATUS 0x8D /* RW */
37 #define W1_F29_FUNC_READ_PIO_REGS 0xF0
38 #define W1_F29_FUNC_CHANN_ACCESS_READ 0xF5
39 #define W1_F29_FUNC_CHANN_ACCESS_WRITE 0x5A
40 /* also used to write the control/status reg (0x8D): */
41 #define W1_F29_FUNC_WRITE_COND_SEARCH_REG 0xCC
42 #define W1_F29_FUNC_RESET_ACTIVITY_LATCHES 0xC3
44 #define W1_F29_SUCCESS_CONFIRM_BYTE 0xAA
46 static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf)
50 "Reading with slave: %p, reg addr: %0#4x, buff addr: %p",
51 sl, (unsigned int)address, buf);
56 mutex_lock(&sl->master->bus_mutex);
57 dev_dbg(&sl->dev, "mutex locked");
59 if (w1_reset_select_slave(sl)) {
60 mutex_unlock(&sl->master->bus_mutex);
64 wrbuf[0] = W1_F29_FUNC_READ_PIO_REGS;
67 w1_write_block(sl->master, wrbuf, 3);
68 *buf = w1_read_8(sl->master);
70 mutex_unlock(&sl->master->bus_mutex);
71 dev_dbg(&sl->dev, "mutex unlocked");
75 static ssize_t state_read(struct file *filp, struct kobject *kobj,
76 struct bin_attribute *bin_attr, char *buf, loff_t off,
79 dev_dbg(&kobj_to_w1_slave(kobj)->dev,
80 "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
81 bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
82 if (count != 1 || off != 0)
84 return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf);
87 static ssize_t output_read(struct file *filp, struct kobject *kobj,
88 struct bin_attribute *bin_attr, char *buf,
89 loff_t off, size_t count)
91 dev_dbg(&kobj_to_w1_slave(kobj)->dev,
92 "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
93 bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
94 if (count != 1 || off != 0)
96 return _read_reg(kobj_to_w1_slave(kobj),
97 W1_F29_REG_OUTPUT_LATCH_STATE, buf);
100 static ssize_t activity_read(struct file *filp, struct kobject *kobj,
101 struct bin_attribute *bin_attr, char *buf,
102 loff_t off, size_t count)
104 dev_dbg(&kobj_to_w1_slave(kobj)->dev,
105 "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
106 bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
107 if (count != 1 || off != 0)
109 return _read_reg(kobj_to_w1_slave(kobj),
110 W1_F29_REG_ACTIVITY_LATCH_STATE, buf);
113 static ssize_t cond_search_mask_read(struct file *filp, struct kobject *kobj,
114 struct bin_attribute *bin_attr, char *buf,
115 loff_t off, size_t count)
117 dev_dbg(&kobj_to_w1_slave(kobj)->dev,
118 "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
119 bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
120 if (count != 1 || off != 0)
122 return _read_reg(kobj_to_w1_slave(kobj),
123 W1_F29_REG_COND_SEARCH_SELECT_MASK, buf);
126 static ssize_t cond_search_polarity_read(struct file *filp,
127 struct kobject *kobj,
128 struct bin_attribute *bin_attr,
129 char *buf, loff_t off, size_t count)
131 if (count != 1 || off != 0)
133 return _read_reg(kobj_to_w1_slave(kobj),
134 W1_F29_REG_COND_SEARCH_POL_SELECT, buf);
137 static ssize_t status_control_read(struct file *filp, struct kobject *kobj,
138 struct bin_attribute *bin_attr, char *buf,
139 loff_t off, size_t count)
141 if (count != 1 || off != 0)
143 return _read_reg(kobj_to_w1_slave(kobj),
144 W1_F29_REG_CONTROL_AND_STATUS, buf);
147 static ssize_t output_write(struct file *filp, struct kobject *kobj,
148 struct bin_attribute *bin_attr, char *buf,
149 loff_t off, size_t count)
151 struct w1_slave *sl = kobj_to_w1_slave(kobj);
154 unsigned int retries = W1_F29_RETRIES;
156 if (count != 1 || off != 0)
159 dev_dbg(&sl->dev, "locking mutex for write_output");
160 mutex_lock(&sl->master->bus_mutex);
161 dev_dbg(&sl->dev, "mutex locked");
163 if (w1_reset_select_slave(sl))
167 w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE;
170 w1_write_block(sl->master, w1_buf, 3);
172 readBack = w1_read_8(sl->master);
174 if (readBack != W1_F29_SUCCESS_CONFIRM_BYTE) {
175 if (w1_reset_resume_command(sl->master))
177 /* try again, the slave is ready for a command */
181 #ifdef CONFIG_W1_SLAVE_DS2408_READBACK
182 /* here the master could read another byte which
183 would be the PIO reg (the actual pin logic state)
184 since in this driver we don't know which pins are
185 in and outs, there's no value to read the state and
186 compare. with (*buf) so end this command abruptly: */
187 if (w1_reset_resume_command(sl->master))
190 /* go read back the output latches */
191 /* (the direct effect of the write above) */
192 w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
193 w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE;
195 w1_write_block(sl->master, w1_buf, 3);
196 /* read the result of the READ_PIO_REGS command */
197 if (w1_read_8(sl->master) == *buf)
201 mutex_unlock(&sl->master->bus_mutex);
203 "mutex unlocked, retries:%d", retries);
208 mutex_unlock(&sl->master->bus_mutex);
209 dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries);
216 * Writing to the activity file resets the activity latches.
218 static ssize_t activity_write(struct file *filp, struct kobject *kobj,
219 struct bin_attribute *bin_attr, char *buf,
220 loff_t off, size_t count)
222 struct w1_slave *sl = kobj_to_w1_slave(kobj);
223 unsigned int retries = W1_F29_RETRIES;
225 if (count != 1 || off != 0)
228 mutex_lock(&sl->master->bus_mutex);
230 if (w1_reset_select_slave(sl))
234 w1_write_8(sl->master, W1_F29_FUNC_RESET_ACTIVITY_LATCHES);
235 if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE) {
236 mutex_unlock(&sl->master->bus_mutex);
239 if (w1_reset_resume_command(sl->master))
244 mutex_unlock(&sl->master->bus_mutex);
248 static ssize_t status_control_write(struct file *filp, struct kobject *kobj,
249 struct bin_attribute *bin_attr, char *buf,
250 loff_t off, size_t count)
252 struct w1_slave *sl = kobj_to_w1_slave(kobj);
254 unsigned int retries = W1_F29_RETRIES;
256 if (count != 1 || off != 0)
259 mutex_lock(&sl->master->bus_mutex);
261 if (w1_reset_select_slave(sl))
265 w1_buf[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG;
266 w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
270 w1_write_block(sl->master, w1_buf, 4);
271 if (w1_reset_resume_command(sl->master))
274 w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
275 w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
278 w1_write_block(sl->master, w1_buf, 3);
279 if (w1_read_8(sl->master) == *buf) {
281 mutex_unlock(&sl->master->bus_mutex);
286 mutex_unlock(&sl->master->bus_mutex);
292 * This is a special sequence we must do to ensure the P0 output is not stuck
293 * in test mode. This is described in rev 2 of the ds2408's datasheet
294 * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under
295 * "APPLICATION INFORMATION/Power-up timing".
297 static int w1_f29_disable_test_mode(struct w1_slave *sl)
300 u8 magic[10] = {0x96, };
301 u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
303 memcpy(&magic[1], &rn, 8);
306 mutex_lock(&sl->master->bus_mutex);
308 res = w1_reset_bus(sl->master);
311 w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
313 res = w1_reset_bus(sl->master);
315 mutex_unlock(&sl->master->bus_mutex);
319 static BIN_ATTR_RO(state, 1);
320 static BIN_ATTR_RW(output, 1);
321 static BIN_ATTR_RW(activity, 1);
322 static BIN_ATTR_RO(cond_search_mask, 1);
323 static BIN_ATTR_RO(cond_search_polarity, 1);
324 static BIN_ATTR_RW(status_control, 1);
326 static struct bin_attribute *w1_f29_bin_attrs[] = {
330 &bin_attr_cond_search_mask,
331 &bin_attr_cond_search_polarity,
332 &bin_attr_status_control,
336 static const struct attribute_group w1_f29_group = {
337 .bin_attrs = w1_f29_bin_attrs,
340 static const struct attribute_group *w1_f29_groups[] = {
345 static struct w1_family_ops w1_f29_fops = {
346 .add_slave = w1_f29_disable_test_mode,
347 .groups = w1_f29_groups,
350 static struct w1_family w1_family_29 = {
351 .fid = W1_FAMILY_DS2408,
352 .fops = &w1_f29_fops,
354 module_w1_family(w1_family_29);