]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/w1/slaves/w1_ds2408.c
Merge branches 'powercap', 'pm-cpufreq' and 'pm-domains'
[mirror_ubuntu-zesty-kernel.git] / drivers / w1 / slaves / w1_ds2408.c
CommitLineData
89610274
JFD
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");
8d7bda51 25MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2408));
89610274
JFD
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
b02f8bed 56 mutex_lock(&sl->master->bus_mutex);
89610274
JFD
57 dev_dbg(&sl->dev, "mutex locked");
58
59 if (w1_reset_select_slave(sl)) {
b02f8bed 60 mutex_unlock(&sl->master->bus_mutex);
89610274
JFD
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
b02f8bed 70 mutex_unlock(&sl->master->bus_mutex);
89610274
JFD
71 dev_dbg(&sl->dev, "mutex unlocked");
72 return 1;
73}
74
32ea4175
GKH
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)
89610274
JFD
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
32ea4175
GKH
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)
89610274
JFD
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
32ea4175
GKH
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)
89610274
JFD
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
32ea4175
GKH
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)
89610274
JFD
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
32ea4175
GKH
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)
89610274
JFD
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
32ea4175
GKH
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)
89610274
JFD
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
32ea4175
GKH
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)
89610274
JFD
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");
b02f8bed 160 mutex_lock(&sl->master->bus_mutex);
89610274
JFD
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);
aceca285
JFD
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
89610274
JFD
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
89610274
JFD
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 */
aceca285
JFD
197 if (w1_read_8(sl->master) == *buf)
198#endif
199 {
89610274 200 /* success! */
b02f8bed 201 mutex_unlock(&sl->master->bus_mutex);
89610274
JFD
202 dev_dbg(&sl->dev,
203 "mutex unlocked, retries:%d", retries);
204 return 1;
205 }
206 }
207error:
b02f8bed 208 mutex_unlock(&sl->master->bus_mutex);
89610274
JFD
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 */
32ea4175
GKH
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)
89610274
JFD
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
b02f8bed 228 mutex_lock(&sl->master->bus_mutex);
89610274
JFD
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) {
b02f8bed 236 mutex_unlock(&sl->master->bus_mutex);
89610274
JFD
237 return 1;
238 }
239 if (w1_reset_resume_command(sl->master))
240 goto error;
241 }
242
243error:
b02f8bed 244 mutex_unlock(&sl->master->bus_mutex);
89610274
JFD
245 return -EIO;
246}
247
32ea4175
GKH
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)
89610274
JFD
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
b02f8bed 259 mutex_lock(&sl->master->bus_mutex);
89610274
JFD
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! */
b02f8bed 281 mutex_unlock(&sl->master->bus_mutex);
89610274
JFD
282 return 1;
283 }
284 }
285error:
b02f8bed 286 mutex_unlock(&sl->master->bus_mutex);
89610274
JFD
287
288 return -EIO;
289}
290
d5528773
JFD
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);
89610274 307
d5528773
JFD
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}
89610274 318
32ea4175
GKH
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,
89610274
JFD
334};
335
32ea4175
GKH
336static const struct attribute_group w1_f29_group = {
337 .bin_attrs = w1_f29_bin_attrs,
338};
89610274 339
32ea4175
GKH
340static const struct attribute_group *w1_f29_groups[] = {
341 &w1_f29_group,
342 NULL,
343};
89610274
JFD
344
345static struct w1_family_ops w1_f29_fops = {
32ea4175
GKH
346 .add_slave = w1_f29_disable_test_mode,
347 .groups = w1_f29_groups,
89610274
JFD
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);