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 #ifdef CONFIG_W1_SLAVE_DS2408_READBACK
142 static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
146 if (w1_reset_resume_command(sl->master))
149 w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
150 w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE;
153 w1_write_block(sl->master, w1_buf, 3);
155 return (w1_read_8(sl->master) == expected);
158 static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
164 static ssize_t output_write(struct file *filp, struct kobject *kobj,
165 struct bin_attribute *bin_attr, char *buf,
166 loff_t off, size_t count)
168 struct w1_slave *sl = kobj_to_w1_slave(kobj);
170 unsigned int retries = W1_F29_RETRIES;
171 ssize_t bytes_written = -EIO;
173 if (count != 1 || off != 0)
176 dev_dbg(&sl->dev, "locking mutex for write_output");
177 mutex_lock(&sl->master->bus_mutex);
178 dev_dbg(&sl->dev, "mutex locked");
180 if (w1_reset_select_slave(sl))
184 w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE;
188 w1_write_block(sl->master, w1_buf, 3);
190 if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE &&
191 optional_read_back_valid(sl, *buf)) {
196 if (w1_reset_resume_command(sl->master))
197 goto out; /* unrecoverable error */
198 /* try again, the slave is ready for a command */
202 mutex_unlock(&sl->master->bus_mutex);
204 dev_dbg(&sl->dev, "%s, mutex unlocked retries:%d\n",
205 (bytes_written > 0) ? "succeeded" : "error", retries);
207 return bytes_written;
212 * Writing to the activity file resets the activity latches.
214 static ssize_t activity_write(struct file *filp, struct kobject *kobj,
215 struct bin_attribute *bin_attr, char *buf,
216 loff_t off, size_t count)
218 struct w1_slave *sl = kobj_to_w1_slave(kobj);
219 unsigned int retries = W1_F29_RETRIES;
221 if (count != 1 || off != 0)
224 mutex_lock(&sl->master->bus_mutex);
226 if (w1_reset_select_slave(sl))
230 w1_write_8(sl->master, W1_F29_FUNC_RESET_ACTIVITY_LATCHES);
231 if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE) {
232 mutex_unlock(&sl->master->bus_mutex);
235 if (w1_reset_resume_command(sl->master))
240 mutex_unlock(&sl->master->bus_mutex);
244 static ssize_t status_control_write(struct file *filp, struct kobject *kobj,
245 struct bin_attribute *bin_attr, char *buf,
246 loff_t off, size_t count)
248 struct w1_slave *sl = kobj_to_w1_slave(kobj);
250 unsigned int retries = W1_F29_RETRIES;
252 if (count != 1 || off != 0)
255 mutex_lock(&sl->master->bus_mutex);
257 if (w1_reset_select_slave(sl))
261 w1_buf[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG;
262 w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
266 w1_write_block(sl->master, w1_buf, 4);
267 if (w1_reset_resume_command(sl->master))
270 w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
271 w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
274 w1_write_block(sl->master, w1_buf, 3);
275 if (w1_read_8(sl->master) == *buf) {
277 mutex_unlock(&sl->master->bus_mutex);
282 mutex_unlock(&sl->master->bus_mutex);
288 * This is a special sequence we must do to ensure the P0 output is not stuck
289 * in test mode. This is described in rev 2 of the ds2408's datasheet
290 * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under
291 * "APPLICATION INFORMATION/Power-up timing".
293 static int w1_f29_disable_test_mode(struct w1_slave *sl)
296 u8 magic[10] = {0x96, };
297 u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
299 memcpy(&magic[1], &rn, 8);
302 mutex_lock(&sl->master->bus_mutex);
304 res = w1_reset_bus(sl->master);
307 w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
309 res = w1_reset_bus(sl->master);
311 mutex_unlock(&sl->master->bus_mutex);
315 static BIN_ATTR_RO(state, 1);
316 static BIN_ATTR_RW(output, 1);
317 static BIN_ATTR_RW(activity, 1);
318 static BIN_ATTR_RO(cond_search_mask, 1);
319 static BIN_ATTR_RO(cond_search_polarity, 1);
320 static BIN_ATTR_RW(status_control, 1);
322 static struct bin_attribute *w1_f29_bin_attrs[] = {
326 &bin_attr_cond_search_mask,
327 &bin_attr_cond_search_polarity,
328 &bin_attr_status_control,
332 static const struct attribute_group w1_f29_group = {
333 .bin_attrs = w1_f29_bin_attrs,
336 static const struct attribute_group *w1_f29_groups[] = {
341 static struct w1_family_ops w1_f29_fops = {
342 .add_slave = w1_f29_disable_test_mode,
343 .groups = w1_f29_groups,
346 static struct w1_family w1_family_29 = {
347 .fid = W1_FAMILY_DS2408,
348 .fops = &w1_f29_fops,
350 module_w1_family(w1_family_29);
352 MODULE_AUTHOR("Jean-Francois Dagenais <dagenaisj@sonatest.com>");
353 MODULE_DESCRIPTION("w1 family 29 driver for DS2408 8 Pin IO");
354 MODULE_LICENSE("GPL");
355 MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2408));