xref: /openbmc/linux/drivers/w1/slaves/w1_ds2408.c (revision d3964221)
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 <linux/w1.h>
19 
20 #define W1_FAMILY_DS2408	0x29
21 
22 #define W1_F29_RETRIES		3
23 
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 */
30 
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
37 
38 #define W1_F29_SUCCESS_CONFIRM_BYTE        0xAA
39 
40 static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf)
41 {
42 	u8 wrbuf[3];
43 	dev_dbg(&sl->dev,
44 			"Reading with slave: %p, reg addr: %0#4x, buff addr: %p",
45 			sl, (unsigned int)address, buf);
46 
47 	if (!buf)
48 		return -EINVAL;
49 
50 	mutex_lock(&sl->master->bus_mutex);
51 	dev_dbg(&sl->dev, "mutex locked");
52 
53 	if (w1_reset_select_slave(sl)) {
54 		mutex_unlock(&sl->master->bus_mutex);
55 		return -EIO;
56 	}
57 
58 	wrbuf[0] = W1_F29_FUNC_READ_PIO_REGS;
59 	wrbuf[1] = address;
60 	wrbuf[2] = 0;
61 	w1_write_block(sl->master, wrbuf, 3);
62 	*buf = w1_read_8(sl->master);
63 
64 	mutex_unlock(&sl->master->bus_mutex);
65 	dev_dbg(&sl->dev, "mutex unlocked");
66 	return 1;
67 }
68 
69 static ssize_t state_read(struct file *filp, struct kobject *kobj,
70 			  struct bin_attribute *bin_attr, char *buf, loff_t off,
71 			  size_t count)
72 {
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)
77 		return -EFAULT;
78 	return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf);
79 }
80 
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)
84 {
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)
89 		return -EFAULT;
90 	return _read_reg(kobj_to_w1_slave(kobj),
91 					 W1_F29_REG_OUTPUT_LATCH_STATE, buf);
92 }
93 
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)
97 {
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)
102 		return -EFAULT;
103 	return _read_reg(kobj_to_w1_slave(kobj),
104 					 W1_F29_REG_ACTIVITY_LATCH_STATE, buf);
105 }
106 
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)
110 {
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)
115 		return -EFAULT;
116 	return _read_reg(kobj_to_w1_slave(kobj),
117 		W1_F29_REG_COND_SEARCH_SELECT_MASK, buf);
118 }
119 
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)
124 {
125 	if (count != 1 || off != 0)
126 		return -EFAULT;
127 	return _read_reg(kobj_to_w1_slave(kobj),
128 		W1_F29_REG_COND_SEARCH_POL_SELECT, buf);
129 }
130 
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)
134 {
135 	if (count != 1 || off != 0)
136 		return -EFAULT;
137 	return _read_reg(kobj_to_w1_slave(kobj),
138 		W1_F29_REG_CONTROL_AND_STATUS, buf);
139 }
140 
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)
144 {
145 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
146 	u8 w1_buf[3];
147 	u8 readBack;
148 	unsigned int retries = W1_F29_RETRIES;
149 
150 	if (count != 1 || off != 0)
151 		return -EFAULT;
152 
153 	dev_dbg(&sl->dev, "locking mutex for write_output");
154 	mutex_lock(&sl->master->bus_mutex);
155 	dev_dbg(&sl->dev, "mutex locked");
156 
157 	if (w1_reset_select_slave(sl))
158 		goto error;
159 
160 	while (retries--) {
161 		w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE;
162 		w1_buf[1] = *buf;
163 		w1_buf[2] = ~(*buf);
164 		w1_write_block(sl->master, w1_buf, 3);
165 
166 		readBack = w1_read_8(sl->master);
167 
168 		if (readBack != W1_F29_SUCCESS_CONFIRM_BYTE) {
169 			if (w1_reset_resume_command(sl->master))
170 				goto error;
171 			/* try again, the slave is ready for a command */
172 			continue;
173 		}
174 
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))
182 			goto error;
183 
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;
188 		w1_buf[2] = 0;
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)
192 #endif
193 		{
194 			/* success! */
195 			mutex_unlock(&sl->master->bus_mutex);
196 			dev_dbg(&sl->dev,
197 				"mutex unlocked, retries:%d", retries);
198 			return 1;
199 		}
200 	}
201 error:
202 	mutex_unlock(&sl->master->bus_mutex);
203 	dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries);
204 
205 	return -EIO;
206 }
207 
208 
209 /**
210  * Writing to the activity file resets the activity latches.
211  */
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)
215 {
216 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
217 	unsigned int retries = W1_F29_RETRIES;
218 
219 	if (count != 1 || off != 0)
220 		return -EFAULT;
221 
222 	mutex_lock(&sl->master->bus_mutex);
223 
224 	if (w1_reset_select_slave(sl))
225 		goto error;
226 
227 	while (retries--) {
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);
231 			return 1;
232 		}
233 		if (w1_reset_resume_command(sl->master))
234 			goto error;
235 	}
236 
237 error:
238 	mutex_unlock(&sl->master->bus_mutex);
239 	return -EIO;
240 }
241 
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)
245 {
246 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
247 	u8 w1_buf[4];
248 	unsigned int retries = W1_F29_RETRIES;
249 
250 	if (count != 1 || off != 0)
251 		return -EFAULT;
252 
253 	mutex_lock(&sl->master->bus_mutex);
254 
255 	if (w1_reset_select_slave(sl))
256 		goto error;
257 
258 	while (retries--) {
259 		w1_buf[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG;
260 		w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
261 		w1_buf[2] = 0;
262 		w1_buf[3] = *buf;
263 
264 		w1_write_block(sl->master, w1_buf, 4);
265 		if (w1_reset_resume_command(sl->master))
266 			goto error;
267 
268 		w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
269 		w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
270 		w1_buf[2] = 0;
271 
272 		w1_write_block(sl->master, w1_buf, 3);
273 		if (w1_read_8(sl->master) == *buf) {
274 			/* success! */
275 			mutex_unlock(&sl->master->bus_mutex);
276 			return 1;
277 		}
278 	}
279 error:
280 	mutex_unlock(&sl->master->bus_mutex);
281 
282 	return -EIO;
283 }
284 
285 /*
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".
290  */
291 static int w1_f29_disable_test_mode(struct w1_slave *sl)
292 {
293 	int res;
294 	u8 magic[10] = {0x96, };
295 	u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
296 
297 	memcpy(&magic[1], &rn, 8);
298 	magic[9] = 0x3C;
299 
300 	mutex_lock(&sl->master->bus_mutex);
301 
302 	res = w1_reset_bus(sl->master);
303 	if (res)
304 		goto out;
305 	w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
306 
307 	res = w1_reset_bus(sl->master);
308 out:
309 	mutex_unlock(&sl->master->bus_mutex);
310 	return res;
311 }
312 
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);
319 
320 static struct bin_attribute *w1_f29_bin_attrs[] = {
321 	&bin_attr_state,
322 	&bin_attr_output,
323 	&bin_attr_activity,
324 	&bin_attr_cond_search_mask,
325 	&bin_attr_cond_search_polarity,
326 	&bin_attr_status_control,
327 	NULL,
328 };
329 
330 static const struct attribute_group w1_f29_group = {
331 	.bin_attrs = w1_f29_bin_attrs,
332 };
333 
334 static const struct attribute_group *w1_f29_groups[] = {
335 	&w1_f29_group,
336 	NULL,
337 };
338 
339 static struct w1_family_ops w1_f29_fops = {
340 	.add_slave      = w1_f29_disable_test_mode,
341 	.groups		= w1_f29_groups,
342 };
343 
344 static struct w1_family w1_family_29 = {
345 	.fid = W1_FAMILY_DS2408,
346 	.fops = &w1_f29_fops,
347 };
348 module_w1_family(w1_family_29);
349 
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));
354