GNU Linux-libre 4.14.303-gnu1
[releases.git] / drivers / w1 / slaves / w1_ds2408.c
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));