xref: /openbmc/linux/drivers/w1/slaves/w1_ds2408.c (revision 151f4e2b)
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 #ifdef fCONFIG_W1_SLAVE_DS2408_READBACK
142 static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
143 {
144 	u8 w1_buf[3];
145 
146 	if (w1_reset_resume_command(sl->master))
147 		return false;
148 
149 	w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
150 	w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE;
151 	w1_buf[2] = 0;
152 
153 	w1_write_block(sl->master, w1_buf, 3);
154 
155 	return (w1_read_8(sl->master) == expected);
156 }
157 #else
158 static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
159 {
160 	return true;
161 }
162 #endif
163 
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)
167 {
168 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
169 	u8 w1_buf[3];
170 	unsigned int retries = W1_F29_RETRIES;
171 	ssize_t bytes_written = -EIO;
172 
173 	if (count != 1 || off != 0)
174 		return -EFAULT;
175 
176 	dev_dbg(&sl->dev, "locking mutex for write_output");
177 	mutex_lock(&sl->master->bus_mutex);
178 	dev_dbg(&sl->dev, "mutex locked");
179 
180 	if (w1_reset_select_slave(sl))
181 		goto out;
182 
183 	do {
184 		w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE;
185 		w1_buf[1] = *buf;
186 		w1_buf[2] = ~(*buf);
187 
188 		w1_write_block(sl->master, w1_buf, 3);
189 
190 		if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE &&
191 		    optional_read_back_valid(sl, *buf)) {
192 			bytes_written = 1;
193 			goto out;
194 		}
195 
196 		if (w1_reset_resume_command(sl->master))
197 			goto out; /* unrecoverable error */
198 		/* try again, the slave is ready for a command */
199 	} while (--retries);
200 
201 out:
202 	mutex_unlock(&sl->master->bus_mutex);
203 
204 	dev_dbg(&sl->dev, "%s, mutex unlocked retries:%d\n",
205 		(bytes_written > 0) ? "succeeded" : "error", retries);
206 
207 	return bytes_written;
208 }
209 
210 
211 /**
212  * Writing to the activity file resets the activity latches.
213  */
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)
217 {
218 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
219 	unsigned int retries = W1_F29_RETRIES;
220 
221 	if (count != 1 || off != 0)
222 		return -EFAULT;
223 
224 	mutex_lock(&sl->master->bus_mutex);
225 
226 	if (w1_reset_select_slave(sl))
227 		goto error;
228 
229 	while (retries--) {
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);
233 			return 1;
234 		}
235 		if (w1_reset_resume_command(sl->master))
236 			goto error;
237 	}
238 
239 error:
240 	mutex_unlock(&sl->master->bus_mutex);
241 	return -EIO;
242 }
243 
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)
247 {
248 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
249 	u8 w1_buf[4];
250 	unsigned int retries = W1_F29_RETRIES;
251 
252 	if (count != 1 || off != 0)
253 		return -EFAULT;
254 
255 	mutex_lock(&sl->master->bus_mutex);
256 
257 	if (w1_reset_select_slave(sl))
258 		goto error;
259 
260 	while (retries--) {
261 		w1_buf[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG;
262 		w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
263 		w1_buf[2] = 0;
264 		w1_buf[3] = *buf;
265 
266 		w1_write_block(sl->master, w1_buf, 4);
267 		if (w1_reset_resume_command(sl->master))
268 			goto error;
269 
270 		w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
271 		w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
272 		w1_buf[2] = 0;
273 
274 		w1_write_block(sl->master, w1_buf, 3);
275 		if (w1_read_8(sl->master) == *buf) {
276 			/* success! */
277 			mutex_unlock(&sl->master->bus_mutex);
278 			return 1;
279 		}
280 	}
281 error:
282 	mutex_unlock(&sl->master->bus_mutex);
283 
284 	return -EIO;
285 }
286 
287 /*
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".
292  */
293 static int w1_f29_disable_test_mode(struct w1_slave *sl)
294 {
295 	int res;
296 	u8 magic[10] = {0x96, };
297 	u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
298 
299 	memcpy(&magic[1], &rn, 8);
300 	magic[9] = 0x3C;
301 
302 	mutex_lock(&sl->master->bus_mutex);
303 
304 	res = w1_reset_bus(sl->master);
305 	if (res)
306 		goto out;
307 	w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
308 
309 	res = w1_reset_bus(sl->master);
310 out:
311 	mutex_unlock(&sl->master->bus_mutex);
312 	return res;
313 }
314 
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);
321 
322 static struct bin_attribute *w1_f29_bin_attrs[] = {
323 	&bin_attr_state,
324 	&bin_attr_output,
325 	&bin_attr_activity,
326 	&bin_attr_cond_search_mask,
327 	&bin_attr_cond_search_polarity,
328 	&bin_attr_status_control,
329 	NULL,
330 };
331 
332 static const struct attribute_group w1_f29_group = {
333 	.bin_attrs = w1_f29_bin_attrs,
334 };
335 
336 static const struct attribute_group *w1_f29_groups[] = {
337 	&w1_f29_group,
338 	NULL,
339 };
340 
341 static struct w1_family_ops w1_f29_fops = {
342 	.add_slave      = w1_f29_disable_test_mode,
343 	.groups		= w1_f29_groups,
344 };
345 
346 static struct w1_family w1_family_29 = {
347 	.fid = W1_FAMILY_DS2408,
348 	.fops = &w1_f29_fops,
349 };
350 module_w1_family(w1_family_29);
351 
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));
356