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
22MODULE_LICENSE("GPL");
23MODULE_AUTHOR("Jean-Francois Dagenais <dagenaisj@sonatest.com>");
24MODULE_DESCRIPTION("w1 family 29 driver for DS2408 8 Pin IO");
25MODULE_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
46static 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
75static 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
87static 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
100static 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
113static 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
126static 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
137static 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
147static 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	}
207error:
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 */
218static 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
243error:
244	mutex_unlock(&sl->master->bus_mutex);
245	return -EIO;
246}
247
248static 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	}
285error:
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 */
297static 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);
314out:
315	mutex_unlock(&sl->master->bus_mutex);
316	return res;
317}
318
319static BIN_ATTR_RO(state, 1);
320static BIN_ATTR_RW(output, 1);
321static BIN_ATTR_RW(activity, 1);
322static BIN_ATTR_RO(cond_search_mask, 1);
323static BIN_ATTR_RO(cond_search_polarity, 1);
324static BIN_ATTR_RW(status_control, 1);
325
326static 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
336static const struct attribute_group w1_f29_group = {
337	.bin_attrs = w1_f29_bin_attrs,
338};
339
340static const struct attribute_group *w1_f29_groups[] = {
341	&w1_f29_group,
342	NULL,
343};
344
345static struct w1_family_ops w1_f29_fops = {
346	.add_slave      = w1_f29_disable_test_mode,
347	.groups		= w1_f29_groups,
348};
349
350static struct w1_family w1_family_29 = {
351	.fid = W1_FAMILY_DS2408,
352	.fops = &w1_f29_fops,
353};
354
355static int __init w1_f29_init(void)
356{
357	return w1_register_family(&w1_family_29);
358}
359
360static void __exit w1_f29_exit(void)
361{
362	w1_unregister_family(&w1_family_29);
363}
364
365module_init(w1_f29_init);
366module_exit(w1_f29_exit);
367