xref: /openbmc/linux/drivers/w1/slaves/w1_ds2408.c (revision 92a76f6d)
1 /*
2  *	w1_ds2408.c - w1 family 29 (DS2408) driver
3  *
4  * Copyright (c) 2010 Jean-Francois Dagenais <dagenaisj@sonatest.com>
5  *
6  * This source code is licensed under the GNU General Public License,
7  * Version 2. See the file COPYING for more details.
8  */
9 
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>
17 
18 #include "../w1.h"
19 #include "../w1_int.h"
20 #include "../w1_family.h"
21 
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));
26 
27 
28 #define W1_F29_RETRIES		3
29 
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 */
36 
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
43 
44 #define W1_F29_SUCCESS_CONFIRM_BYTE        0xAA
45 
46 static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf)
47 {
48 	u8 wrbuf[3];
49 	dev_dbg(&sl->dev,
50 			"Reading with slave: %p, reg addr: %0#4x, buff addr: %p",
51 			sl, (unsigned int)address, buf);
52 
53 	if (!buf)
54 		return -EINVAL;
55 
56 	mutex_lock(&sl->master->bus_mutex);
57 	dev_dbg(&sl->dev, "mutex locked");
58 
59 	if (w1_reset_select_slave(sl)) {
60 		mutex_unlock(&sl->master->bus_mutex);
61 		return -EIO;
62 	}
63 
64 	wrbuf[0] = W1_F29_FUNC_READ_PIO_REGS;
65 	wrbuf[1] = address;
66 	wrbuf[2] = 0;
67 	w1_write_block(sl->master, wrbuf, 3);
68 	*buf = w1_read_8(sl->master);
69 
70 	mutex_unlock(&sl->master->bus_mutex);
71 	dev_dbg(&sl->dev, "mutex unlocked");
72 	return 1;
73 }
74 
75 static ssize_t state_read(struct file *filp, struct kobject *kobj,
76 			  struct bin_attribute *bin_attr, char *buf, loff_t off,
77 			  size_t count)
78 {
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)
83 		return -EFAULT;
84 	return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf);
85 }
86 
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)
90 {
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)
95 		return -EFAULT;
96 	return _read_reg(kobj_to_w1_slave(kobj),
97 					 W1_F29_REG_OUTPUT_LATCH_STATE, buf);
98 }
99 
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)
103 {
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)
108 		return -EFAULT;
109 	return _read_reg(kobj_to_w1_slave(kobj),
110 					 W1_F29_REG_ACTIVITY_LATCH_STATE, buf);
111 }
112 
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)
116 {
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)
121 		return -EFAULT;
122 	return _read_reg(kobj_to_w1_slave(kobj),
123 		W1_F29_REG_COND_SEARCH_SELECT_MASK, buf);
124 }
125 
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)
130 {
131 	if (count != 1 || off != 0)
132 		return -EFAULT;
133 	return _read_reg(kobj_to_w1_slave(kobj),
134 		W1_F29_REG_COND_SEARCH_POL_SELECT, buf);
135 }
136 
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)
140 {
141 	if (count != 1 || off != 0)
142 		return -EFAULT;
143 	return _read_reg(kobj_to_w1_slave(kobj),
144 		W1_F29_REG_CONTROL_AND_STATUS, buf);
145 }
146 
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)
150 {
151 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
152 	u8 w1_buf[3];
153 	u8 readBack;
154 	unsigned int retries = W1_F29_RETRIES;
155 
156 	if (count != 1 || off != 0)
157 		return -EFAULT;
158 
159 	dev_dbg(&sl->dev, "locking mutex for write_output");
160 	mutex_lock(&sl->master->bus_mutex);
161 	dev_dbg(&sl->dev, "mutex locked");
162 
163 	if (w1_reset_select_slave(sl))
164 		goto error;
165 
166 	while (retries--) {
167 		w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE;
168 		w1_buf[1] = *buf;
169 		w1_buf[2] = ~(*buf);
170 		w1_write_block(sl->master, w1_buf, 3);
171 
172 		readBack = w1_read_8(sl->master);
173 
174 		if (readBack != W1_F29_SUCCESS_CONFIRM_BYTE) {
175 			if (w1_reset_resume_command(sl->master))
176 				goto error;
177 			/* try again, the slave is ready for a command */
178 			continue;
179 		}
180 
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))
188 			goto error;
189 
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;
194 		w1_buf[2] = 0;
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)
198 #endif
199 		{
200 			/* success! */
201 			mutex_unlock(&sl->master->bus_mutex);
202 			dev_dbg(&sl->dev,
203 				"mutex unlocked, retries:%d", retries);
204 			return 1;
205 		}
206 	}
207 error:
208 	mutex_unlock(&sl->master->bus_mutex);
209 	dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries);
210 
211 	return -EIO;
212 }
213 
214 
215 /**
216  * Writing to the activity file resets the activity latches.
217  */
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)
221 {
222 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
223 	unsigned int retries = W1_F29_RETRIES;
224 
225 	if (count != 1 || off != 0)
226 		return -EFAULT;
227 
228 	mutex_lock(&sl->master->bus_mutex);
229 
230 	if (w1_reset_select_slave(sl))
231 		goto error;
232 
233 	while (retries--) {
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);
237 			return 1;
238 		}
239 		if (w1_reset_resume_command(sl->master))
240 			goto error;
241 	}
242 
243 error:
244 	mutex_unlock(&sl->master->bus_mutex);
245 	return -EIO;
246 }
247 
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)
251 {
252 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
253 	u8 w1_buf[4];
254 	unsigned int retries = W1_F29_RETRIES;
255 
256 	if (count != 1 || off != 0)
257 		return -EFAULT;
258 
259 	mutex_lock(&sl->master->bus_mutex);
260 
261 	if (w1_reset_select_slave(sl))
262 		goto error;
263 
264 	while (retries--) {
265 		w1_buf[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG;
266 		w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
267 		w1_buf[2] = 0;
268 		w1_buf[3] = *buf;
269 
270 		w1_write_block(sl->master, w1_buf, 4);
271 		if (w1_reset_resume_command(sl->master))
272 			goto error;
273 
274 		w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
275 		w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
276 		w1_buf[2] = 0;
277 
278 		w1_write_block(sl->master, w1_buf, 3);
279 		if (w1_read_8(sl->master) == *buf) {
280 			/* success! */
281 			mutex_unlock(&sl->master->bus_mutex);
282 			return 1;
283 		}
284 	}
285 error:
286 	mutex_unlock(&sl->master->bus_mutex);
287 
288 	return -EIO;
289 }
290 
291 /*
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".
296  */
297 static int w1_f29_disable_test_mode(struct w1_slave *sl)
298 {
299 	int res;
300 	u8 magic[10] = {0x96, };
301 	u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
302 
303 	memcpy(&magic[1], &rn, 8);
304 	magic[9] = 0x3C;
305 
306 	mutex_lock(&sl->master->bus_mutex);
307 
308 	res = w1_reset_bus(sl->master);
309 	if (res)
310 		goto out;
311 	w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
312 
313 	res = w1_reset_bus(sl->master);
314 out:
315 	mutex_unlock(&sl->master->bus_mutex);
316 	return res;
317 }
318 
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);
325 
326 static struct bin_attribute *w1_f29_bin_attrs[] = {
327 	&bin_attr_state,
328 	&bin_attr_output,
329 	&bin_attr_activity,
330 	&bin_attr_cond_search_mask,
331 	&bin_attr_cond_search_polarity,
332 	&bin_attr_status_control,
333 	NULL,
334 };
335 
336 static const struct attribute_group w1_f29_group = {
337 	.bin_attrs = w1_f29_bin_attrs,
338 };
339 
340 static const struct attribute_group *w1_f29_groups[] = {
341 	&w1_f29_group,
342 	NULL,
343 };
344 
345 static struct w1_family_ops w1_f29_fops = {
346 	.add_slave      = w1_f29_disable_test_mode,
347 	.groups		= w1_f29_groups,
348 };
349 
350 static struct w1_family w1_family_29 = {
351 	.fid = W1_FAMILY_DS2408,
352 	.fops = &w1_f29_fops,
353 };
354 
355 static int __init w1_f29_init(void)
356 {
357 	return w1_register_family(&w1_family_29);
358 }
359 
360 static void __exit w1_f29_exit(void)
361 {
362 	w1_unregister_family(&w1_family_29);
363 }
364 
365 module_init(w1_f29_init);
366 module_exit(w1_f29_exit);
367