aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/w1/Kconfig16
-rw-r--r--drivers/w1/ds_w1_bridge.c4
-rw-r--r--drivers/w1/matrox_w1.c10
-rw-r--r--drivers/w1/w1.c546
-rw-r--r--drivers/w1/w1.h113
-rw-r--r--drivers/w1/w1_family.c10
-rw-r--r--drivers/w1/w1_family.h18
-rw-r--r--drivers/w1/w1_int.c41
-rw-r--r--drivers/w1/w1_int.h6
-rw-r--r--drivers/w1/w1_io.c117
-rw-r--r--drivers/w1/w1_io.h9
-rw-r--r--drivers/w1/w1_log.h4
-rw-r--r--drivers/w1/w1_netlink.h4
-rw-r--r--drivers/w1/w1_smem.c50
-rw-r--r--drivers/w1/w1_therm.c100
15 files changed, 626 insertions, 422 deletions
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
index 2ab65c902fe5..4f120796273e 100644
--- a/drivers/w1/Kconfig
+++ b/drivers/w1/Kconfig
@@ -3,9 +3,9 @@ menu "Dallas's 1-wire bus"
3config W1 3config W1
4 tristate "Dallas's 1-wire support" 4 tristate "Dallas's 1-wire support"
5 ---help--- 5 ---help---
6 Dallas's 1-wire bus is usefull to connect slow 1-pin devices 6 Dallas's 1-wire bus is usefull to connect slow 1-pin devices
7 such as iButtons and thermal sensors. 7 such as iButtons and thermal sensors.
8 8
9 If you want W1 support, you should say Y here. 9 If you want W1 support, you should say Y here.
10 10
11 This W1 support can also be built as a module. If so, the module 11 This W1 support can also be built as a module. If so, the module
@@ -17,8 +17,8 @@ config W1_MATROX
17 help 17 help
18 Say Y here if you want to communicate with your 1-wire devices 18 Say Y here if you want to communicate with your 1-wire devices
19 using Matrox's G400 GPIO pins. 19 using Matrox's G400 GPIO pins.
20 20
21 This support is also available as a module. If so, the module 21 This support is also available as a module. If so, the module
22 will be called matrox_w1.ko. 22 will be called matrox_w1.ko.
23 23
24config W1_DS9490 24config W1_DS9490
@@ -27,17 +27,17 @@ config W1_DS9490
27 help 27 help
28 Say Y here if you want to have a driver for DS9490R UWB <-> W1 bridge. 28 Say Y here if you want to have a driver for DS9490R UWB <-> W1 bridge.
29 29
30 This support is also available as a module. If so, the module 30 This support is also available as a module. If so, the module
31 will be called ds9490r.ko. 31 will be called ds9490r.ko.
32 32
33config W1_DS9490_BRIDGE 33config W1_DS9490R_BRIDGE
34 tristate "DS9490R USB <-> W1 transport layer for 1-wire" 34 tristate "DS9490R USB <-> W1 transport layer for 1-wire"
35 depends on W1_DS9490 35 depends on W1_DS9490
36 help 36 help
37 Say Y here if you want to communicate with your 1-wire devices 37 Say Y here if you want to communicate with your 1-wire devices
38 using DS9490R USB bridge. 38 using DS9490R USB bridge.
39 39
40 This support is also available as a module. If so, the module 40 This support is also available as a module. If so, the module
41 will be called ds_w1_bridge.ko. 41 will be called ds_w1_bridge.ko.
42 42
43config W1_THERM 43config W1_THERM
@@ -51,7 +51,7 @@ config W1_SMEM
51 tristate "Simple 64bit memory family implementation" 51 tristate "Simple 64bit memory family implementation"
52 depends on W1 52 depends on W1
53 help 53 help
54 Say Y here if you want to connect 1-wire 54 Say Y here if you want to connect 1-wire
55 simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire. 55 simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire.
56 56
57endmenu 57endmenu
diff --git a/drivers/w1/ds_w1_bridge.c b/drivers/w1/ds_w1_bridge.c
index 0baaeb5fd630..7bddd8ac7d7f 100644
--- a/drivers/w1/ds_w1_bridge.c
+++ b/drivers/w1/ds_w1_bridge.c
@@ -83,11 +83,11 @@ static u8 ds9490r_read_byte(unsigned long data)
83 return byte; 83 return byte;
84} 84}
85 85
86static void ds9490r_write_block(unsigned long data, u8 *buf, int len) 86static void ds9490r_write_block(unsigned long data, const u8 *buf, int len)
87{ 87{
88 struct ds_device *dev = (struct ds_device *)data; 88 struct ds_device *dev = (struct ds_device *)data;
89 89
90 ds_write_block(dev, buf, len); 90 ds_write_block(dev, (u8 *)buf, len);
91} 91}
92 92
93static u8 ds9490r_read_block(unsigned long data, u8 *buf, int len) 93static u8 ds9490r_read_block(unsigned long data, u8 *buf, int len)
diff --git a/drivers/w1/matrox_w1.c b/drivers/w1/matrox_w1.c
index e565416458ea..0b03f8f93f63 100644
--- a/drivers/w1/matrox_w1.c
+++ b/drivers/w1/matrox_w1.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * matrox_w1.c 2 * matrox_w1.c
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@ static struct pci_driver matrox_w1_pci_driver = {
59 .remove = __devexit_p(matrox_w1_remove), 59 .remove = __devexit_p(matrox_w1_remove),
60}; 60};
61 61
62/* 62/*
63 * Matrox G400 DDC registers. 63 * Matrox G400 DDC registers.
64 */ 64 */
65 65
@@ -177,8 +177,8 @@ static int __devinit matrox_w1_probe(struct pci_dev *pdev, const struct pci_devi
177 177
178 dev->bus_master = (struct w1_bus_master *)(dev + 1); 178 dev->bus_master = (struct w1_bus_master *)(dev + 1);
179 179
180 /* 180 /*
181 * True for G400, for some other we need resource 0, see drivers/video/matrox/matroxfb_base.c 181 * True for G400, for some other we need resource 0, see drivers/video/matrox/matroxfb_base.c
182 */ 182 */
183 183
184 dev->phys_addr = pci_resource_start(pdev, 1); 184 dev->phys_addr = pci_resource_start(pdev, 1);
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 24a192e3b8b4..b460927ec32a 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1.c 2 * w1.c
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -59,6 +59,19 @@ static pid_t control_thread;
59static int control_needs_exit; 59static int control_needs_exit;
60static DECLARE_COMPLETION(w1_control_complete); 60static DECLARE_COMPLETION(w1_control_complete);
61 61
62/* stuff for the default family */
63static ssize_t w1_famdefault_read_name(struct device *dev, struct device_attribute *attr, char *buf)
64{
65 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
66 return(sprintf(buf, "%s\n", sl->name));
67}
68static struct w1_family_ops w1_default_fops = {
69 .rname = &w1_famdefault_read_name,
70};
71static struct w1_family w1_default_family = {
72 .fops = &w1_default_fops,
73};
74
62static int w1_master_match(struct device *dev, struct device_driver *drv) 75static int w1_master_match(struct device *dev, struct device_driver *drv)
63{ 76{
64 return 1; 77 return 1;
@@ -99,6 +112,20 @@ static ssize_t w1_default_read_bin(struct kobject *kobj, char *buf, loff_t off,
99 return sprintf(buf, "No family registered.\n"); 112 return sprintf(buf, "No family registered.\n");
100} 113}
101 114
115static struct device_attribute w1_slave_attribute =
116 __ATTR(name, S_IRUGO, w1_default_read_name, NULL);
117
118static struct bin_attribute w1_slave_bin_attribute = {
119 .attr = {
120 .name = "w1_slave",
121 .mode = S_IRUGO,
122 .owner = THIS_MODULE,
123 },
124 .size = W1_SLAVE_DATA_SIZE,
125 .read = &w1_default_read_bin,
126};
127
128
102static struct bus_type w1_bus_type = { 129static struct bus_type w1_bus_type = {
103 .name = "w1", 130 .name = "w1",
104 .match = w1_master_match, 131 .match = w1_master_match,
@@ -119,34 +146,49 @@ struct device w1_device = {
119 .release = &w1_master_release 146 .release = &w1_master_release
120}; 147};
121 148
122static struct device_attribute w1_slave_attribute = {
123 .attr = {
124 .name = "name",
125 .mode = S_IRUGO,
126 .owner = THIS_MODULE
127 },
128 .show = &w1_default_read_name,
129};
130
131static struct device_attribute w1_slave_attribute_val = {
132 .attr = {
133 .name = "value",
134 .mode = S_IRUGO,
135 .owner = THIS_MODULE
136 },
137 .show = &w1_default_read_name,
138};
139
140static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf) 149static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf)
141{ 150{
142 struct w1_master *md = container_of (dev, struct w1_master, dev); 151 struct w1_master *md = container_of(dev, struct w1_master, dev);
143 ssize_t count; 152 ssize_t count;
144 153
145 if (down_interruptible (&md->mutex)) 154 if (down_interruptible (&md->mutex))
146 return -EBUSY; 155 return -EBUSY;
147 156
148 count = sprintf(buf, "%s\n", md->name); 157 count = sprintf(buf, "%s\n", md->name);
149 158
159 up(&md->mutex);
160
161 return count;
162}
163
164static ssize_t w1_master_attribute_store_search(struct device * dev,
165 struct device_attribute *attr,
166 const char * buf, size_t count)
167{
168 struct w1_master *md = container_of(dev, struct w1_master, dev);
169
170 if (down_interruptible (&md->mutex))
171 return -EBUSY;
172
173 md->search_count = simple_strtol(buf, NULL, 0);
174
175 up(&md->mutex);
176
177 return count;
178}
179
180static ssize_t w1_master_attribute_show_search(struct device *dev,
181 struct device_attribute *attr,
182 char *buf)
183{
184 struct w1_master *md = container_of(dev, struct w1_master, dev);
185 ssize_t count;
186
187 if (down_interruptible (&md->mutex))
188 return -EBUSY;
189
190 count = sprintf(buf, "%d\n", md->search_count);
191
150 up(&md->mutex); 192 up(&md->mutex);
151 193
152 return count; 194 return count;
@@ -156,12 +198,12 @@ static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct devic
156{ 198{
157 struct w1_master *md = container_of(dev, struct w1_master, dev); 199 struct w1_master *md = container_of(dev, struct w1_master, dev);
158 ssize_t count; 200 ssize_t count;
159 201
160 if (down_interruptible(&md->mutex)) 202 if (down_interruptible(&md->mutex))
161 return -EBUSY; 203 return -EBUSY;
162 204
163 count = sprintf(buf, "0x%p\n", md->bus_master); 205 count = sprintf(buf, "0x%p\n", md->bus_master);
164 206
165 up(&md->mutex); 207 up(&md->mutex);
166 return count; 208 return count;
167} 209}
@@ -177,12 +219,12 @@ static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, stru
177{ 219{
178 struct w1_master *md = container_of(dev, struct w1_master, dev); 220 struct w1_master *md = container_of(dev, struct w1_master, dev);
179 ssize_t count; 221 ssize_t count;
180 222
181 if (down_interruptible(&md->mutex)) 223 if (down_interruptible(&md->mutex))
182 return -EBUSY; 224 return -EBUSY;
183 225
184 count = sprintf(buf, "%d\n", md->max_slave_count); 226 count = sprintf(buf, "%d\n", md->max_slave_count);
185 227
186 up(&md->mutex); 228 up(&md->mutex);
187 return count; 229 return count;
188} 230}
@@ -191,12 +233,12 @@ static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct devi
191{ 233{
192 struct w1_master *md = container_of(dev, struct w1_master, dev); 234 struct w1_master *md = container_of(dev, struct w1_master, dev);
193 ssize_t count; 235 ssize_t count;
194 236
195 if (down_interruptible(&md->mutex)) 237 if (down_interruptible(&md->mutex))
196 return -EBUSY; 238 return -EBUSY;
197 239
198 count = sprintf(buf, "%lu\n", md->attempts); 240 count = sprintf(buf, "%lu\n", md->attempts);
199 241
200 up(&md->mutex); 242 up(&md->mutex);
201 return count; 243 return count;
202} 244}
@@ -205,18 +247,17 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct d
205{ 247{
206 struct w1_master *md = container_of(dev, struct w1_master, dev); 248 struct w1_master *md = container_of(dev, struct w1_master, dev);
207 ssize_t count; 249 ssize_t count;
208 250
209 if (down_interruptible(&md->mutex)) 251 if (down_interruptible(&md->mutex))
210 return -EBUSY; 252 return -EBUSY;
211 253
212 count = sprintf(buf, "%d\n", md->slave_count); 254 count = sprintf(buf, "%d\n", md->slave_count);
213 255
214 up(&md->mutex); 256 up(&md->mutex);
215 return count; 257 return count;
216} 258}
217 259
218static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf) 260static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)
219
220{ 261{
221 struct w1_master *md = container_of(dev, struct w1_master, dev); 262 struct w1_master *md = container_of(dev, struct w1_master, dev);
222 int c = PAGE_SIZE; 263 int c = PAGE_SIZE;
@@ -233,7 +274,7 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device
233 list_for_each_safe(ent, n, &md->slist) { 274 list_for_each_safe(ent, n, &md->slist) {
234 sl = list_entry(ent, struct w1_slave, w1_slave_entry); 275 sl = list_entry(ent, struct w1_slave, w1_slave_entry);
235 276
236 c -= snprintf(buf + PAGE_SIZE - c, c, "%s\n", sl->name); 277 c -= snprintf(buf + PAGE_SIZE - c, c, "%s\n", sl->name);
237 } 278 }
238 } 279 }
239 280
@@ -242,73 +283,52 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device
242 return PAGE_SIZE - c; 283 return PAGE_SIZE - c;
243} 284}
244 285
245static struct device_attribute w1_master_attribute_slaves = { 286#define W1_MASTER_ATTR_RO(_name, _mode) \
246 .attr = { 287 struct device_attribute w1_master_attribute_##_name = \
247 .name = "w1_master_slaves", 288 __ATTR(w1_master_##_name, _mode, \
248 .mode = S_IRUGO, 289 w1_master_attribute_show_##_name, NULL)
249 .owner = THIS_MODULE, 290
250 }, 291#define W1_MASTER_ATTR_RW(_name, _mode) \
251 .show = &w1_master_attribute_show_slaves, 292 struct device_attribute w1_master_attribute_##_name = \
252}; 293 __ATTR(w1_master_##_name, _mode, \
253static struct device_attribute w1_master_attribute_slave_count = { 294 w1_master_attribute_show_##_name, \
254 .attr = { 295 w1_master_attribute_store_##_name)
255 .name = "w1_master_slave_count", 296
256 .mode = S_IRUGO, 297static W1_MASTER_ATTR_RO(name, S_IRUGO);
257 .owner = THIS_MODULE 298static W1_MASTER_ATTR_RO(slaves, S_IRUGO);
258 }, 299static W1_MASTER_ATTR_RO(slave_count, S_IRUGO);
259 .show = &w1_master_attribute_show_slave_count, 300static W1_MASTER_ATTR_RO(max_slave_count, S_IRUGO);
260}; 301static W1_MASTER_ATTR_RO(attempts, S_IRUGO);
261static struct device_attribute w1_master_attribute_attempts = { 302static W1_MASTER_ATTR_RO(timeout, S_IRUGO);
262 .attr = { 303static W1_MASTER_ATTR_RO(pointer, S_IRUGO);
263 .name = "w1_master_attempts", 304static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO);
264 .mode = S_IRUGO, 305
265 .owner = THIS_MODULE 306static struct attribute *w1_master_default_attrs[] = {
266 }, 307 &w1_master_attribute_name.attr,
267 .show = &w1_master_attribute_show_attempts, 308 &w1_master_attribute_slaves.attr,
268}; 309 &w1_master_attribute_slave_count.attr,
269static struct device_attribute w1_master_attribute_max_slave_count = { 310 &w1_master_attribute_max_slave_count.attr,
270 .attr = { 311 &w1_master_attribute_attempts.attr,
271 .name = "w1_master_max_slave_count", 312 &w1_master_attribute_timeout.attr,
272 .mode = S_IRUGO, 313 &w1_master_attribute_pointer.attr,
273 .owner = THIS_MODULE 314 &w1_master_attribute_search.attr,
274 }, 315 NULL
275 .show = &w1_master_attribute_show_max_slave_count,
276};
277static struct device_attribute w1_master_attribute_timeout = {
278 .attr = {
279 .name = "w1_master_timeout",
280 .mode = S_IRUGO,
281 .owner = THIS_MODULE
282 },
283 .show = &w1_master_attribute_show_timeout,
284};
285static struct device_attribute w1_master_attribute_pointer = {
286 .attr = {
287 .name = "w1_master_pointer",
288 .mode = S_IRUGO,
289 .owner = THIS_MODULE
290 },
291 .show = &w1_master_attribute_show_pointer,
292};
293static struct device_attribute w1_master_attribute_name = {
294 .attr = {
295 .name = "w1_master_name",
296 .mode = S_IRUGO,
297 .owner = THIS_MODULE
298 },
299 .show = &w1_master_attribute_show_name,
300}; 316};
301 317
302static struct bin_attribute w1_slave_bin_attribute = { 318static struct attribute_group w1_master_defattr_group = {
303 .attr = { 319 .attrs = w1_master_default_attrs,
304 .name = "w1_slave",
305 .mode = S_IRUGO,
306 .owner = THIS_MODULE,
307 },
308 .size = W1_SLAVE_DATA_SIZE,
309 .read = &w1_default_read_bin,
310}; 320};
311 321
322int w1_create_master_attributes(struct w1_master *master)
323{
324 return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group);
325}
326
327void w1_destroy_master_attributes(struct w1_master *master)
328{
329 sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
330}
331
312static int __w1_attach_slave_device(struct w1_slave *sl) 332static int __w1_attach_slave_device(struct w1_slave *sl)
313{ 333{
314 int err; 334 int err;
@@ -319,13 +339,13 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
319 sl->dev.release = &w1_slave_release; 339 sl->dev.release = &w1_slave_release;
320 340
321 snprintf(&sl->dev.bus_id[0], sizeof(sl->dev.bus_id), 341 snprintf(&sl->dev.bus_id[0], sizeof(sl->dev.bus_id),
322 "%02x-%012llx", 342 "%02x-%012llx",
323 (unsigned int) sl->reg_num.family, 343 (unsigned int) sl->reg_num.family,
324 (unsigned long long) sl->reg_num.id); 344 (unsigned long long) sl->reg_num.id);
325 snprintf (&sl->name[0], sizeof(sl->name), 345 snprintf(&sl->name[0], sizeof(sl->name),
326 "%02x-%012llx", 346 "%02x-%012llx",
327 (unsigned int) sl->reg_num.family, 347 (unsigned int) sl->reg_num.family,
328 (unsigned long long) sl->reg_num.id); 348 (unsigned long long) sl->reg_num.id);
329 349
330 dev_dbg(&sl->dev, "%s: registering %s.\n", __func__, 350 dev_dbg(&sl->dev, "%s: registering %s.\n", __func__,
331 &sl->dev.bus_id[0]); 351 &sl->dev.bus_id[0]);
@@ -333,48 +353,36 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
333 err = device_register(&sl->dev); 353 err = device_register(&sl->dev);
334 if (err < 0) { 354 if (err < 0) {
335 dev_err(&sl->dev, 355 dev_err(&sl->dev,
336 "Device registration [%s] failed. err=%d\n", 356 "Device registration [%s] failed. err=%d\n",
337 sl->dev.bus_id, err); 357 sl->dev.bus_id, err);
338 return err; 358 return err;
339 } 359 }
340 360
341 memcpy(&sl->attr_bin, &w1_slave_bin_attribute, sizeof(sl->attr_bin)); 361 memcpy(&sl->attr_bin, &w1_slave_bin_attribute, sizeof(sl->attr_bin));
342 memcpy(&sl->attr_name, &w1_slave_attribute, sizeof(sl->attr_name)); 362 memcpy(&sl->attr_name, &w1_slave_attribute, sizeof(sl->attr_name));
343 memcpy(&sl->attr_val, &w1_slave_attribute_val, sizeof(sl->attr_val)); 363
344
345 sl->attr_bin.read = sl->family->fops->rbin; 364 sl->attr_bin.read = sl->family->fops->rbin;
346 sl->attr_name.show = sl->family->fops->rname; 365 sl->attr_name.show = sl->family->fops->rname;
347 sl->attr_val.show = sl->family->fops->rval;
348 sl->attr_val.attr.name = sl->family->fops->rvalname;
349 366
350 err = device_create_file(&sl->dev, &sl->attr_name); 367 err = device_create_file(&sl->dev, &sl->attr_name);
351 if (err < 0) { 368 if (err < 0) {
352 dev_err(&sl->dev, 369 dev_err(&sl->dev,
353 "sysfs file creation for [%s] failed. err=%d\n", 370 "sysfs file creation for [%s] failed. err=%d\n",
354 sl->dev.bus_id, err); 371 sl->dev.bus_id, err);
355 device_unregister(&sl->dev);
356 return err;
357 }
358
359 err = device_create_file(&sl->dev, &sl->attr_val);
360 if (err < 0) {
361 dev_err(&sl->dev,
362 "sysfs file creation for [%s] failed. err=%d\n",
363 sl->dev.bus_id, err);
364 device_remove_file(&sl->dev, &sl->attr_name);
365 device_unregister(&sl->dev); 372 device_unregister(&sl->dev);
366 return err; 373 return err;
367 } 374 }
368 375
369 err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin); 376 if ( sl->attr_bin.read ) {
370 if (err < 0) { 377 err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin);
371 dev_err(&sl->dev, 378 if (err < 0) {
372 "sysfs file creation for [%s] failed. err=%d\n", 379 dev_err(&sl->dev,
373 sl->dev.bus_id, err); 380 "sysfs file creation for [%s] failed. err=%d\n",
374 device_remove_file(&sl->dev, &sl->attr_name); 381 sl->dev.bus_id, err);
375 device_remove_file(&sl->dev, &sl->attr_val); 382 device_remove_file(&sl->dev, &sl->attr_name);
376 device_unregister(&sl->dev); 383 device_unregister(&sl->dev);
377 return err; 384 return err;
385 }
378 } 386 }
379 387
380 list_add_tail(&sl->w1_slave_entry, &sl->master->slist); 388 list_add_tail(&sl->w1_slave_entry, &sl->master->slist);
@@ -410,12 +418,10 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
410 spin_lock(&w1_flock); 418 spin_lock(&w1_flock);
411 f = w1_family_registered(rn->family); 419 f = w1_family_registered(rn->family);
412 if (!f) { 420 if (!f) {
413 spin_unlock(&w1_flock); 421 f= &w1_default_family;
414 dev_info(&dev->dev, "Family %x for %02x.%012llx.%02x is not registered.\n", 422 dev_info(&dev->dev, "Family %x for %02x.%012llx.%02x is not registered.\n",
415 rn->family, rn->family, 423 rn->family, rn->family,
416 (unsigned long long)rn->id, rn->crc); 424 (unsigned long long)rn->id, rn->crc);
417 kfree(sl);
418 return -ENODEV;
419 } 425 }
420 __w1_family_get(f); 426 __w1_family_get(f);
421 spin_unlock(&w1_flock); 427 spin_unlock(&w1_flock);
@@ -445,7 +451,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
445static void w1_slave_detach(struct w1_slave *sl) 451static void w1_slave_detach(struct w1_slave *sl)
446{ 452{
447 struct w1_netlink_msg msg; 453 struct w1_netlink_msg msg;
448 454
449 dev_info(&sl->dev, "%s: detaching %s.\n", __func__, sl->name); 455 dev_info(&sl->dev, "%s: detaching %s.\n", __func__, sl->name);
450 456
451 while (atomic_read(&sl->refcnt)) { 457 while (atomic_read(&sl->refcnt)) {
@@ -456,12 +462,15 @@ static void w1_slave_detach(struct w1_slave *sl)
456 flush_signals(current); 462 flush_signals(current);
457 } 463 }
458 464
459 sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin); 465 if ( sl->attr_bin.read ) {
466 sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin);
467 }
460 device_remove_file(&sl->dev, &sl->attr_name); 468 device_remove_file(&sl->dev, &sl->attr_name);
461 device_remove_file(&sl->dev, &sl->attr_val);
462 device_unregister(&sl->dev); 469 device_unregister(&sl->dev);
463 w1_family_put(sl->family); 470 w1_family_put(sl->family);
464 471
472 sl->master->slave_count--;
473
465 memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id)); 474 memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id));
466 msg.type = W1_SLAVE_REMOVE; 475 msg.type = W1_SLAVE_REMOVE;
467 w1_netlink_send(sl->master, &msg); 476 w1_netlink_send(sl->master, &msg);
@@ -471,8 +480,8 @@ static struct w1_master *w1_search_master(unsigned long data)
471{ 480{
472 struct w1_master *dev; 481 struct w1_master *dev;
473 int found = 0; 482 int found = 0;
474 483
475 spin_lock_irq(&w1_mlock); 484 spin_lock_bh(&w1_mlock);
476 list_for_each_entry(dev, &w1_masters, w1_master_entry) { 485 list_for_each_entry(dev, &w1_masters, w1_master_entry) {
477 if (dev->bus_master->data == data) { 486 if (dev->bus_master->data == data) {
478 found = 1; 487 found = 1;
@@ -480,12 +489,26 @@ static struct w1_master *w1_search_master(unsigned long data)
480 break; 489 break;
481 } 490 }
482 } 491 }
483 spin_unlock_irq(&w1_mlock); 492 spin_unlock_bh(&w1_mlock);
484 493
485 return (found)?dev:NULL; 494 return (found)?dev:NULL;
486} 495}
487 496
488void w1_slave_found(unsigned long data, u64 rn) 497void w1_reconnect_slaves(struct w1_family *f)
498{
499 struct w1_master *dev;
500
501 spin_lock_bh(&w1_mlock);
502 list_for_each_entry(dev, &w1_masters, w1_master_entry) {
503 dev_info(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",
504 dev->name, f->fid);
505 set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
506 }
507 spin_unlock_bh(&w1_mlock);
508}
509
510
511static void w1_slave_found(unsigned long data, u64 rn)
489{ 512{
490 int slave_count; 513 int slave_count;
491 struct w1_slave *sl; 514 struct w1_slave *sl;
@@ -500,7 +523,7 @@ void w1_slave_found(unsigned long data, u64 rn)
500 data); 523 data);
501 return; 524 return;
502 } 525 }
503 526
504 tmp = (struct w1_reg_num *) &rn; 527 tmp = (struct w1_reg_num *) &rn;
505 528
506 slave_count = 0; 529 slave_count = 0;
@@ -513,8 +536,7 @@ void w1_slave_found(unsigned long data, u64 rn)
513 sl->reg_num.crc == tmp->crc) { 536 sl->reg_num.crc == tmp->crc) {
514 set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); 537 set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
515 break; 538 break;
516 } 539 } else if (sl->reg_num.family == tmp->family) {
517 else if (sl->reg_num.family == tmp->family) {
518 family_found = 1; 540 family_found = 1;
519 break; 541 break;
520 } 542 }
@@ -528,30 +550,43 @@ void w1_slave_found(unsigned long data, u64 rn)
528 rn && ((le64_to_cpu(rn) >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) { 550 rn && ((le64_to_cpu(rn) >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
529 w1_attach_slave_device(dev, tmp); 551 w1_attach_slave_device(dev, tmp);
530 } 552 }
531 553
532 atomic_dec(&dev->refcnt); 554 atomic_dec(&dev->refcnt);
533} 555}
534 556
535void w1_search(struct w1_master *dev) 557/**
558 * Performs a ROM Search & registers any devices found.
559 * The 1-wire search is a simple binary tree search.
560 * For each bit of the address, we read two bits and write one bit.
561 * The bit written will put to sleep all devies that don't match that bit.
562 * When the two reads differ, the direction choice is obvious.
563 * When both bits are 0, we must choose a path to take.
564 * When we can scan all 64 bits without having to choose a path, we are done.
565 *
566 * See "Application note 187 1-wire search algorithm" at www.maxim-ic.com
567 *
568 * @dev The master device to search
569 * @cb Function to call when a device is found
570 */
571void w1_search(struct w1_master *dev, w1_slave_found_callback cb)
536{ 572{
537 u64 last, rn, tmp; 573 u64 last_rn, rn, tmp64;
538 int i, count = 0; 574 int i, slave_count = 0;
539 int last_family_desc, last_zero, last_device; 575 int last_zero, last_device;
540 int search_bit, id_bit, comp_bit, desc_bit; 576 int search_bit, desc_bit;
577 u8 triplet_ret = 0;
541 578
542 search_bit = id_bit = comp_bit = 0; 579 search_bit = 0;
543 rn = tmp = last = 0; 580 rn = last_rn = 0;
544 last_device = last_zero = last_family_desc = 0; 581 last_device = 0;
582 last_zero = -1;
545 583
546 desc_bit = 64; 584 desc_bit = 64;
547 585
548 while (!(id_bit && comp_bit) && !last_device 586 while ( !last_device && (slave_count++ < dev->max_slave_count) ) {
549 && count++ < dev->max_slave_count) { 587 last_rn = rn;
550 last = rn;
551 rn = 0; 588 rn = 0;
552 589
553 last_family_desc = 0;
554
555 /* 590 /*
556 * Reset bus and all 1-wire device state machines 591 * Reset bus and all 1-wire device state machines
557 * so they can respond to our requests. 592 * so they can respond to our requests.
@@ -563,94 +598,46 @@ void w1_search(struct w1_master *dev)
563 break; 598 break;
564 } 599 }
565 600
566#if 1 601 /* Start the search */
567 w1_write_8(dev, W1_SEARCH); 602 w1_write_8(dev, W1_SEARCH);
568 for (i = 0; i < 64; ++i) { 603 for (i = 0; i < 64; ++i) {
569 /* 604 /* Determine the direction/search bit */
570 * Read 2 bits from bus. 605 if (i == desc_bit)
571 * All who don't sleep must send ID bit and COMPLEMENT ID bit. 606 search_bit = 1; /* took the 0 path last time, so take the 1 path */
572 * They actually are ANDed between all senders. 607 else if (i > desc_bit)
573 */ 608 search_bit = 0; /* take the 0 path on the next branch */
574 id_bit = w1_touch_bit(dev, 1);
575 comp_bit = w1_touch_bit(dev, 1);
576
577 if (id_bit && comp_bit)
578 break;
579
580 if (id_bit == 0 && comp_bit == 0) {
581 if (i == desc_bit)
582 search_bit = 1;
583 else if (i > desc_bit)
584 search_bit = 0;
585 else
586 search_bit = ((last >> i) & 0x1);
587
588 if (search_bit == 0) {
589 last_zero = i;
590 if (last_zero < 9)
591 last_family_desc = last_zero;
592 }
593
594 }
595 else 609 else
596 search_bit = id_bit; 610 search_bit = ((last_rn >> i) & 0x1);
597 611
598 tmp = search_bit; 612 /** Read two bits and write one bit */
599 rn |= (tmp << i); 613 triplet_ret = w1_triplet(dev, search_bit);
600 614
601 /* 615 /* quit if no device responded */
602 * Write 1 bit to bus 616 if ( (triplet_ret & 0x03) == 0x03 )
603 * and make all who don't have "search_bit" in "i"'th position 617 break;
604 * in it's registration number sleep.
605 */
606 if (dev->bus_master->touch_bit)
607 w1_touch_bit(dev, search_bit);
608 else
609 w1_write_bit(dev, search_bit);
610 618
611 } 619 /* If both directions were valid, and we took the 0 path... */
612#endif 620 if (triplet_ret == 0)
621 last_zero = i;
613 622
614 if (desc_bit == last_zero) 623 /* extract the direction taken & update the device number */
615 last_device = 1; 624 tmp64 = (triplet_ret >> 2);
625 rn |= (tmp64 << i);
626 }
616 627
617 desc_bit = last_zero; 628 if ( (triplet_ret & 0x03) != 0x03 ) {
618 629 if ( (desc_bit == last_zero) || (last_zero < 0))
619 w1_slave_found(dev->bus_master->data, rn); 630 last_device = 1;
631 desc_bit = last_zero;
632 cb(dev->bus_master->data, rn);
633 }
620 } 634 }
621} 635}
622 636
623int w1_create_master_attributes(struct w1_master *dev) 637static int w1_control(void *data)
624{
625 if ( device_create_file(&dev->dev, &w1_master_attribute_slaves) < 0 ||
626 device_create_file(&dev->dev, &w1_master_attribute_slave_count) < 0 ||
627 device_create_file(&dev->dev, &w1_master_attribute_attempts) < 0 ||
628 device_create_file(&dev->dev, &w1_master_attribute_max_slave_count) < 0 ||
629 device_create_file(&dev->dev, &w1_master_attribute_timeout) < 0||
630 device_create_file(&dev->dev, &w1_master_attribute_pointer) < 0||
631 device_create_file(&dev->dev, &w1_master_attribute_name) < 0)
632 return -EINVAL;
633
634 return 0;
635}
636
637void w1_destroy_master_attributes(struct w1_master *dev)
638{ 638{
639 device_remove_file(&dev->dev, &w1_master_attribute_slaves); 639 struct w1_slave *sl, *sln;
640 device_remove_file(&dev->dev, &w1_master_attribute_slave_count); 640 struct w1_master *dev, *n;
641 device_remove_file(&dev->dev, &w1_master_attribute_attempts);
642 device_remove_file(&dev->dev, &w1_master_attribute_max_slave_count);
643 device_remove_file(&dev->dev, &w1_master_attribute_timeout);
644 device_remove_file(&dev->dev, &w1_master_attribute_pointer);
645 device_remove_file(&dev->dev, &w1_master_attribute_name);
646}
647
648
649int w1_control(void *data)
650{
651 struct w1_slave *sl;
652 struct w1_master *dev;
653 struct list_head *ent, *ment, *n, *mn;
654 int err, have_to_wait = 0; 641 int err, have_to_wait = 0;
655 642
656 daemonize("w1_control"); 643 daemonize("w1_control");
@@ -665,10 +652,8 @@ int w1_control(void *data)
665 if (signal_pending(current)) 652 if (signal_pending(current))
666 flush_signals(current); 653 flush_signals(current);
667 654
668 list_for_each_safe(ment, mn, &w1_masters) { 655 list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) {
669 dev = list_entry(ment, struct w1_master, w1_master_entry); 656 if (!control_needs_exit && !dev->flags)
670
671 if (!control_needs_exit && !dev->need_exit)
672 continue; 657 continue;
673 /* 658 /*
674 * Little race: we can create thread but not set the flag. 659 * Little race: we can create thread but not set the flag.
@@ -679,12 +664,8 @@ int w1_control(void *data)
679 continue; 664 continue;
680 } 665 }
681 666
682 spin_lock(&w1_mlock);
683 list_del(&dev->w1_master_entry);
684 spin_unlock(&w1_mlock);
685
686 if (control_needs_exit) { 667 if (control_needs_exit) {
687 dev->need_exit = 1; 668 set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
688 669
689 err = kill_proc(dev->kpid, SIGTERM, 1); 670 err = kill_proc(dev->kpid, SIGTERM, 1);
690 if (err) 671 if (err)
@@ -693,24 +674,42 @@ int w1_control(void *data)
693 dev->kpid); 674 dev->kpid);
694 } 675 }
695 676
696 wait_for_completion(&dev->dev_exited); 677 if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
697 678 wait_for_completion(&dev->dev_exited);
698 list_for_each_safe(ent, n, &dev->slist) { 679 spin_lock_bh(&w1_mlock);
699 sl = list_entry(ent, struct w1_slave, w1_slave_entry); 680 list_del(&dev->w1_master_entry);
681 spin_unlock_bh(&w1_mlock);
700 682
701 if (!sl) 683 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
702 dev_warn(&dev->dev,
703 "%s: slave entry is NULL.\n",
704 __func__);
705 else {
706 list_del(&sl->w1_slave_entry); 684 list_del(&sl->w1_slave_entry);
707 685
708 w1_slave_detach(sl); 686 w1_slave_detach(sl);
709 kfree(sl); 687 kfree(sl);
710 } 688 }
689 w1_destroy_master_attributes(dev);
690 atomic_dec(&dev->refcnt);
691 continue;
692 }
693
694 if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
695 dev_info(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
696 down(&dev->mutex);
697 list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
698 if (sl->family->fid == W1_FAMILY_DEFAULT) {
699 struct w1_reg_num rn;
700 list_del(&sl->w1_slave_entry);
701 w1_slave_detach(sl);
702
703 memcpy(&rn, &sl->reg_num, sizeof(rn));
704
705 kfree(sl);
706
707 w1_attach_slave_device(dev, &rn);
708 }
709 }
710 clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
711 up(&dev->mutex);
711 } 712 }
712 w1_destroy_master_attributes(dev);
713 atomic_dec(&dev->refcnt);
714 } 713 }
715 } 714 }
716 715
@@ -720,51 +719,50 @@ int w1_control(void *data)
720int w1_process(void *data) 719int w1_process(void *data)
721{ 720{
722 struct w1_master *dev = (struct w1_master *) data; 721 struct w1_master *dev = (struct w1_master *) data;
723 struct list_head *ent, *n; 722 struct w1_slave *sl, *sln;
724 struct w1_slave *sl;
725 723
726 daemonize("%s", dev->name); 724 daemonize("%s", dev->name);
727 allow_signal(SIGTERM); 725 allow_signal(SIGTERM);
728 726
729 while (!dev->need_exit) { 727 while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
730 try_to_freeze(PF_FREEZE); 728 try_to_freeze(PF_FREEZE);
731 msleep_interruptible(w1_timeout * 1000); 729 msleep_interruptible(w1_timeout * 1000);
732 730
733 if (signal_pending(current)) 731 if (signal_pending(current))
734 flush_signals(current); 732 flush_signals(current);
735 733
736 if (dev->need_exit) 734 if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags))
737 break; 735 break;
738 736
739 if (!dev->initialized) 737 if (!dev->initialized)
740 continue; 738 continue;
741 739
740 if (dev->search_count == 0)
741 continue;
742
742 if (down_interruptible(&dev->mutex)) 743 if (down_interruptible(&dev->mutex))
743 continue; 744 continue;
744 745
745 list_for_each_safe(ent, n, &dev->slist) { 746 list_for_each_entry(sl, &dev->slist, w1_slave_entry)
746 sl = list_entry(ent, struct w1_slave, w1_slave_entry); 747 clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
747 748
748 if (sl)
749 clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
750 }
751
752 w1_search_devices(dev, w1_slave_found); 749 w1_search_devices(dev, w1_slave_found);
753 750
754 list_for_each_safe(ent, n, &dev->slist) { 751 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
755 sl = list_entry(ent, struct w1_slave, w1_slave_entry); 752 if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {
756
757 if (sl && !test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {
758 list_del (&sl->w1_slave_entry); 753 list_del (&sl->w1_slave_entry);
759 754
760 w1_slave_detach (sl); 755 w1_slave_detach (sl);
761 kfree (sl); 756 kfree (sl);
762 757
763 dev->slave_count--; 758 dev->slave_count--;
764 } 759 } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))
765 else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))
766 sl->ttl = dev->slave_ttl; 760 sl->ttl = dev->slave_ttl;
767 } 761 }
762
763 if (dev->search_count > 0)
764 dev->search_count--;
765
768 up(&dev->mutex); 766 up(&dev->mutex);
769 } 767 }
770 768
@@ -774,7 +772,7 @@ int w1_process(void *data)
774 return 0; 772 return 0;
775} 773}
776 774
777int w1_init(void) 775static int w1_init(void)
778{ 776{
779 int retval; 777 int retval;
780 778
@@ -814,18 +812,14 @@ err_out_exit_init:
814 return retval; 812 return retval;
815} 813}
816 814
817void w1_fini(void) 815static void w1_fini(void)
818{ 816{
819 struct w1_master *dev; 817 struct w1_master *dev;
820 struct list_head *ent, *n;
821 818
822 list_for_each_safe(ent, n, &w1_masters) { 819 list_for_each_entry(dev, &w1_masters, w1_master_entry)
823 dev = list_entry(ent, struct w1_master, w1_master_entry);
824 __w1_remove_master_device(dev); 820 __w1_remove_master_device(dev);
825 }
826 821
827 control_needs_exit = 1; 822 control_needs_exit = 1;
828
829 wait_for_completion(&w1_control_complete); 823 wait_for_completion(&w1_control_complete);
830 824
831 driver_unregister(&w1_driver); 825 driver_unregister(&w1_driver);
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h
index abbddaf3f8e2..4f0a986e33e3 100644
--- a/drivers/w1/w1.h
+++ b/drivers/w1/w1.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1.h 2 * w1.h
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -74,36 +74,86 @@ struct w1_slave
74 int ttl; 74 int ttl;
75 75
76 struct w1_master *master; 76 struct w1_master *master;
77 struct w1_family *family; 77 struct w1_family *family;
78 struct device dev; 78 struct device dev;
79 struct completion dev_released; 79 struct completion dev_released;
80 80
81 struct bin_attribute attr_bin; 81 struct bin_attribute attr_bin;
82 struct device_attribute attr_name, attr_val; 82 struct device_attribute attr_name;
83}; 83};
84 84
85typedef void (* w1_slave_found_callback)(unsigned long, u64); 85typedef void (* w1_slave_found_callback)(unsigned long, u64);
86 86
87
88/**
89 * Note: read_bit and write_bit are very low level functions and should only
90 * be used with hardware that doesn't really support 1-wire operations,
91 * like a parallel/serial port.
92 * Either define read_bit and write_bit OR define, at minimum, touch_bit and
93 * reset_bus.
94 */
87struct w1_bus_master 95struct w1_bus_master
88{ 96{
89 unsigned long data; 97 /** the first parameter in all the functions below */
90 98 unsigned long data;
91 u8 (*read_bit)(unsigned long); 99
92 void (*write_bit)(unsigned long, u8); 100 /**
93 101 * Sample the line level
94 u8 (*read_byte)(unsigned long); 102 * @return the level read (0 or 1)
95 void (*write_byte)(unsigned long, u8); 103 */
96 104 u8 (*read_bit)(unsigned long);
97 u8 (*read_block)(unsigned long, u8 *, int); 105
98 void (*write_block)(unsigned long, u8 *, int); 106 /** Sets the line level */
99 107 void (*write_bit)(unsigned long, u8);
100 u8 (*touch_bit)(unsigned long, u8); 108
101 109 /**
102 u8 (*reset_bus)(unsigned long); 110 * touch_bit is the lowest-level function for devices that really
103 111 * support the 1-wire protocol.
104 void (*search)(unsigned long, w1_slave_found_callback); 112 * touch_bit(0) = write-0 cycle
113 * touch_bit(1) = write-1 / read cycle
114 * @return the bit read (0 or 1)
115 */
116 u8 (*touch_bit)(unsigned long, u8);
117
118 /**
119 * Reads a bytes. Same as 8 touch_bit(1) calls.
120 * @return the byte read
121 */
122 u8 (*read_byte)(unsigned long);
123
124 /**
125 * Writes a byte. Same as 8 touch_bit(x) calls.
126 */
127 void (*write_byte)(unsigned long, u8);
128
129 /**
130 * Same as a series of read_byte() calls
131 * @return the number of bytes read
132 */
133 u8 (*read_block)(unsigned long, u8 *, int);
134
135 /** Same as a series of write_byte() calls */
136 void (*write_block)(unsigned long, const u8 *, int);
137
138 /**
139 * Combines two reads and a smart write for ROM searches
140 * @return bit0=Id bit1=comp_id bit2=dir_taken
141 */
142 u8 (*triplet)(unsigned long, u8);
143
144 /**
145 * long write-0 with a read for the presence pulse detection
146 * @return -1=Error, 0=Device present, 1=No device present
147 */
148 u8 (*reset_bus)(unsigned long);
149
150 /** Really nice hardware can handles the ROM searches */
151 void (*search)(unsigned long, w1_slave_found_callback);
105}; 152};
106 153
154#define W1_MASTER_NEED_EXIT 0
155#define W1_MASTER_NEED_RECONNECT 1
156
107struct w1_master 157struct w1_master
108{ 158{
109 struct list_head w1_master_entry; 159 struct list_head w1_master_entry;
@@ -115,30 +165,31 @@ struct w1_master
115 int slave_ttl; 165 int slave_ttl;
116 int initialized; 166 int initialized;
117 u32 id; 167 u32 id;
168 int search_count;
118 169
119 atomic_t refcnt; 170 atomic_t refcnt;
120 171
121 void *priv; 172 void *priv;
122 int priv_size; 173 int priv_size;
123 174
124 int need_exit; 175 long flags;
176
125 pid_t kpid; 177 pid_t kpid;
126 struct semaphore mutex; 178 struct semaphore mutex;
127 179
128 struct device_driver *driver; 180 struct device_driver *driver;
129 struct device dev; 181 struct device dev;
130 struct completion dev_released; 182 struct completion dev_released;
131 struct completion dev_exited; 183 struct completion dev_exited;
132 184
133 struct w1_bus_master *bus_master; 185 struct w1_bus_master *bus_master;
134 186
135 u32 seq, groups; 187 u32 seq, groups;
136 struct sock *nls; 188 struct sock *nls;
137}; 189};
138 190
139int w1_create_master_attributes(struct w1_master *); 191int w1_create_master_attributes(struct w1_master *);
140void w1_destroy_master_attributes(struct w1_master *); 192void w1_search(struct w1_master *dev, w1_slave_found_callback cb);
141void w1_search(struct w1_master *dev);
142 193
143#endif /* __KERNEL__ */ 194#endif /* __KERNEL__ */
144 195
diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
index d1d56eca1061..02eee57d3c0c 100644
--- a/drivers/w1/w1_family.c
+++ b/drivers/w1/w1_family.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1_family.c 2 * w1_family.c
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -27,10 +27,11 @@
27 27
28DEFINE_SPINLOCK(w1_flock); 28DEFINE_SPINLOCK(w1_flock);
29static LIST_HEAD(w1_families); 29static LIST_HEAD(w1_families);
30extern void w1_reconnect_slaves(struct w1_family *f);
30 31
31static int w1_check_family(struct w1_family *f) 32static int w1_check_family(struct w1_family *f)
32{ 33{
33 if (!f->fops->rname || !f->fops->rbin || !f->fops->rval || !f->fops->rvalname) 34 if (!f->fops->rname || !f->fops->rbin)
34 return -EINVAL; 35 return -EINVAL;
35 36
36 return 0; 37 return 0;
@@ -60,9 +61,10 @@ int w1_register_family(struct w1_family *newf)
60 newf->need_exit = 0; 61 newf->need_exit = 0;
61 list_add_tail(&newf->family_entry, &w1_families); 62 list_add_tail(&newf->family_entry, &w1_families);
62 } 63 }
63
64 spin_unlock(&w1_flock); 64 spin_unlock(&w1_flock);
65 65
66 w1_reconnect_slaves(newf);
67
66 return ret; 68 return ret;
67} 69}
68 70
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index 07fa49412a90..b26da01bbc38 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1_family.h 2 * w1_family.h
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -27,8 +27,11 @@
27#include <asm/atomic.h> 27#include <asm/atomic.h>
28 28
29#define W1_FAMILY_DEFAULT 0 29#define W1_FAMILY_DEFAULT 0
30#define W1_FAMILY_THERM 0x10 30#define W1_FAMILY_SMEM_01 0x01
31#define W1_FAMILY_SMEM 0x01 31#define W1_FAMILY_SMEM_81 0x81
32#define W1_THERM_DS18S20 0x10
33#define W1_THERM_DS1822 0x22
34#define W1_THERM_DS18B20 0x28
32 35
33#define MAXNAMELEN 32 36#define MAXNAMELEN 32
34 37
@@ -36,18 +39,15 @@ struct w1_family_ops
36{ 39{
37 ssize_t (* rname)(struct device *, struct device_attribute *, char *); 40 ssize_t (* rname)(struct device *, struct device_attribute *, char *);
38 ssize_t (* rbin)(struct kobject *, char *, loff_t, size_t); 41 ssize_t (* rbin)(struct kobject *, char *, loff_t, size_t);
39
40 ssize_t (* rval)(struct device *, struct device_attribute *, char *);
41 unsigned char rvalname[MAXNAMELEN];
42}; 42};
43 43
44struct w1_family 44struct w1_family
45{ 45{
46 struct list_head family_entry; 46 struct list_head family_entry;
47 u8 fid; 47 u8 fid;
48 48
49 struct w1_family_ops *fops; 49 struct w1_family_ops *fops;
50 50
51 atomic_t refcnt; 51 atomic_t refcnt;
52 u8 need_exit; 52 u8 need_exit;
53}; 53};
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 5f0bafbbd575..35e85d961702 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1_int.c 2 * w1_int.c
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -39,8 +39,9 @@ extern spinlock_t w1_mlock;
39 39
40extern int w1_process(void *); 40extern int w1_process(void *);
41 41
42struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, 42static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
43 struct device_driver *driver, struct device *device) 43 struct device_driver *driver,
44 struct device *device)
44{ 45{
45 struct w1_master *dev; 46 struct w1_master *dev;
46 int err; 47 int err;
@@ -60,14 +61,15 @@ struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
60 61
61 dev->bus_master = (struct w1_bus_master *)(dev + 1); 62 dev->bus_master = (struct w1_bus_master *)(dev + 1);
62 63
63 dev->owner = THIS_MODULE; 64 dev->owner = THIS_MODULE;
64 dev->max_slave_count = slave_count; 65 dev->max_slave_count = slave_count;
65 dev->slave_count = 0; 66 dev->slave_count = 0;
66 dev->attempts = 0; 67 dev->attempts = 0;
67 dev->kpid = -1; 68 dev->kpid = -1;
68 dev->initialized = 0; 69 dev->initialized = 0;
69 dev->id = id; 70 dev->id = id;
70 dev->slave_ttl = slave_ttl; 71 dev->slave_ttl = slave_ttl;
72 dev->search_count = -1; /* continual scan */
71 73
72 atomic_set(&dev->refcnt, 2); 74 atomic_set(&dev->refcnt, 2);
73 75
@@ -105,7 +107,7 @@ struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
105 return dev; 107 return dev;
106} 108}
107 109
108void w1_free_dev(struct w1_master *dev) 110static void w1_free_dev(struct w1_master *dev)
109{ 111{
110 device_unregister(&dev->dev); 112 device_unregister(&dev->dev);
111 if (dev->nls && dev->nls->sk_socket) 113 if (dev->nls && dev->nls->sk_socket)
@@ -120,6 +122,13 @@ int w1_add_master_device(struct w1_bus_master *master)
120 int retval = 0; 122 int retval = 0;
121 struct w1_netlink_msg msg; 123 struct w1_netlink_msg msg;
122 124
125 /* validate minimum functionality */
126 if (!(master->touch_bit && master->reset_bus) &&
127 !(master->write_bit && master->read_bit)) {
128 printk(KERN_ERR "w1_add_master_device: invalid function set\n");
129 return(-EINVAL);
130 }
131
123 dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_driver, &w1_device); 132 dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_driver, &w1_device);
124 if (!dev) 133 if (!dev)
125 return -ENOMEM; 134 return -ENOMEM;
@@ -153,7 +162,7 @@ int w1_add_master_device(struct w1_bus_master *master)
153 return 0; 162 return 0;
154 163
155err_out_kill_thread: 164err_out_kill_thread:
156 dev->need_exit = 1; 165 set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
157 if (kill_proc(dev->kpid, SIGTERM, 1)) 166 if (kill_proc(dev->kpid, SIGTERM, 1))
158 dev_err(&dev->dev, 167 dev_err(&dev->dev,
159 "Failed to send signal to w1 kernel thread %d.\n", 168 "Failed to send signal to w1 kernel thread %d.\n",
@@ -171,7 +180,7 @@ void __w1_remove_master_device(struct w1_master *dev)
171 int err; 180 int err;
172 struct w1_netlink_msg msg; 181 struct w1_netlink_msg msg;
173 182
174 dev->need_exit = 1; 183 set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
175 err = kill_proc(dev->kpid, SIGTERM, 1); 184 err = kill_proc(dev->kpid, SIGTERM, 1);
176 if (err) 185 if (err)
177 dev_err(&dev->dev, 186 dev_err(&dev->dev,
@@ -197,10 +206,8 @@ void __w1_remove_master_device(struct w1_master *dev)
197void w1_remove_master_device(struct w1_bus_master *bm) 206void w1_remove_master_device(struct w1_bus_master *bm)
198{ 207{
199 struct w1_master *dev = NULL; 208 struct w1_master *dev = NULL;
200 struct list_head *ent, *n;
201 209
202 list_for_each_safe(ent, n, &w1_masters) { 210 list_for_each_entry(dev, &w1_masters, w1_master_entry) {
203 dev = list_entry(ent, struct w1_master, w1_master_entry);
204 if (!dev->initialized) 211 if (!dev->initialized)
205 continue; 212 continue;
206 213
diff --git a/drivers/w1/w1_int.h b/drivers/w1/w1_int.h
index fdb531e87faa..4274082d2262 100644
--- a/drivers/w1/w1_int.h
+++ b/drivers/w1/w1_int.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1_int.h 2 * w1_int.h
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -27,8 +27,6 @@
27 27
28#include "w1.h" 28#include "w1.h"
29 29
30struct w1_master * w1_alloc_dev(u32, int, int, struct device_driver *, struct device *);
31void w1_free_dev(struct w1_master *dev);
32int w1_add_master_device(struct w1_bus_master *); 30int w1_add_master_device(struct w1_bus_master *);
33void w1_remove_master_device(struct w1_bus_master *); 31void w1_remove_master_device(struct w1_bus_master *);
34void __w1_remove_master_device(struct w1_master *); 32void __w1_remove_master_device(struct w1_master *);
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
index 02796b5a39f6..00f032220173 100644
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1_io.c 2 * w1_io.c
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -55,15 +55,29 @@ void w1_delay(unsigned long tm)
55 udelay(tm * w1_delay_parm); 55 udelay(tm * w1_delay_parm);
56} 56}
57 57
58static void w1_write_bit(struct w1_master *dev, int bit);
59static u8 w1_read_bit(struct w1_master *dev);
60
61/**
62 * Generates a write-0 or write-1 cycle and samples the level.
63 */
58u8 w1_touch_bit(struct w1_master *dev, int bit) 64u8 w1_touch_bit(struct w1_master *dev, int bit)
59{ 65{
60 if (dev->bus_master->touch_bit) 66 if (dev->bus_master->touch_bit)
61 return dev->bus_master->touch_bit(dev->bus_master->data, bit); 67 return dev->bus_master->touch_bit(dev->bus_master->data, bit);
62 else 68 else if (bit)
63 return w1_read_bit(dev); 69 return w1_read_bit(dev);
70 else {
71 w1_write_bit(dev, 0);
72 return(0);
73 }
64} 74}
65 75
66void w1_write_bit(struct w1_master *dev, int bit) 76/**
77 * Generates a write-0 or write-1 cycle.
78 * Only call if dev->bus_master->touch_bit is NULL
79 */
80static void w1_write_bit(struct w1_master *dev, int bit)
67{ 81{
68 if (bit) { 82 if (bit) {
69 dev->bus_master->write_bit(dev->bus_master->data, 0); 83 dev->bus_master->write_bit(dev->bus_master->data, 0);
@@ -78,6 +92,12 @@ void w1_write_bit(struct w1_master *dev, int bit)
78 } 92 }
79} 93}
80 94
95/**
96 * Writes 8 bits.
97 *
98 * @param dev the master device
99 * @param byte the byte to write
100 */
81void w1_write_8(struct w1_master *dev, u8 byte) 101void w1_write_8(struct w1_master *dev, u8 byte)
82{ 102{
83 int i; 103 int i;
@@ -86,10 +106,15 @@ void w1_write_8(struct w1_master *dev, u8 byte)
86 dev->bus_master->write_byte(dev->bus_master->data, byte); 106 dev->bus_master->write_byte(dev->bus_master->data, byte);
87 else 107 else
88 for (i = 0; i < 8; ++i) 108 for (i = 0; i < 8; ++i)
89 w1_write_bit(dev, (byte >> i) & 0x1); 109 w1_touch_bit(dev, (byte >> i) & 0x1);
90} 110}
91 111
92u8 w1_read_bit(struct w1_master *dev) 112
113/**
114 * Generates a write-1 cycle and samples the level.
115 * Only call if dev->bus_master->touch_bit is NULL
116 */
117static u8 w1_read_bit(struct w1_master *dev)
93{ 118{
94 int result; 119 int result;
95 120
@@ -104,6 +129,53 @@ u8 w1_read_bit(struct w1_master *dev)
104 return result & 0x1; 129 return result & 0x1;
105} 130}
106 131
132/**
133 * Does a triplet - used for searching ROM addresses.
134 * Return bits:
135 * bit 0 = id_bit
136 * bit 1 = comp_bit
137 * bit 2 = dir_taken
138 * If both bits 0 & 1 are set, the search should be restarted.
139 *
140 * @param dev the master device
141 * @param bdir the bit to write if both id_bit and comp_bit are 0
142 * @return bit fields - see above
143 */
144u8 w1_triplet(struct w1_master *dev, int bdir)
145{
146 if ( dev->bus_master->triplet )
147 return(dev->bus_master->triplet(dev->bus_master->data, bdir));
148 else {
149 u8 id_bit = w1_touch_bit(dev, 1);
150 u8 comp_bit = w1_touch_bit(dev, 1);
151 u8 retval;
152
153 if ( id_bit && comp_bit )
154 return(0x03); /* error */
155
156 if ( !id_bit && !comp_bit ) {
157 /* Both bits are valid, take the direction given */
158 retval = bdir ? 0x04 : 0;
159 } else {
160 /* Only one bit is valid, take that direction */
161 bdir = id_bit;
162 retval = id_bit ? 0x05 : 0x02;
163 }
164
165 if ( dev->bus_master->touch_bit )
166 w1_touch_bit(dev, bdir);
167 else
168 w1_write_bit(dev, bdir);
169 return(retval);
170 }
171}
172
173/**
174 * Reads 8 bits.
175 *
176 * @param dev the master device
177 * @return the byte read
178 */
107u8 w1_read_8(struct w1_master * dev) 179u8 w1_read_8(struct w1_master * dev)
108{ 180{
109 int i; 181 int i;
@@ -113,12 +185,20 @@ u8 w1_read_8(struct w1_master * dev)
113 res = dev->bus_master->read_byte(dev->bus_master->data); 185 res = dev->bus_master->read_byte(dev->bus_master->data);
114 else 186 else
115 for (i = 0; i < 8; ++i) 187 for (i = 0; i < 8; ++i)
116 res |= (w1_read_bit(dev) << i); 188 res |= (w1_touch_bit(dev,1) << i);
117 189
118 return res; 190 return res;
119} 191}
120 192
121void w1_write_block(struct w1_master *dev, u8 *buf, int len) 193/**
194 * Writes a series of bytes.
195 *
196 * @param dev the master device
197 * @param buf pointer to the data to write
198 * @param len the number of bytes to write
199 * @return the byte read
200 */
201void w1_write_block(struct w1_master *dev, const u8 *buf, int len)
122{ 202{
123 int i; 203 int i;
124 204
@@ -129,6 +209,14 @@ void w1_write_block(struct w1_master *dev, u8 *buf, int len)
129 w1_write_8(dev, buf[i]); 209 w1_write_8(dev, buf[i]);
130} 210}
131 211
212/**
213 * Reads a series of bytes.
214 *
215 * @param dev the master device
216 * @param buf pointer to the buffer to fill
217 * @param len the number of bytes to read
218 * @return the number of bytes read
219 */
132u8 w1_read_block(struct w1_master *dev, u8 *buf, int len) 220u8 w1_read_block(struct w1_master *dev, u8 *buf, int len)
133{ 221{
134 int i; 222 int i;
@@ -145,9 +233,15 @@ u8 w1_read_block(struct w1_master *dev, u8 *buf, int len)
145 return ret; 233 return ret;
146} 234}
147 235
236/**
237 * Issues a reset bus sequence.
238 *
239 * @param dev The bus master pointer
240 * @return 0=Device present, 1=No device present or error
241 */
148int w1_reset_bus(struct w1_master *dev) 242int w1_reset_bus(struct w1_master *dev)
149{ 243{
150 int result = 0; 244 int result;
151 245
152 if (dev->bus_master->reset_bus) 246 if (dev->bus_master->reset_bus)
153 result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1; 247 result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1;
@@ -180,12 +274,11 @@ void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb)
180 if (dev->bus_master->search) 274 if (dev->bus_master->search)
181 dev->bus_master->search(dev->bus_master->data, cb); 275 dev->bus_master->search(dev->bus_master->data, cb);
182 else 276 else
183 w1_search(dev); 277 w1_search(dev, cb);
184} 278}
185 279
186EXPORT_SYMBOL(w1_write_bit); 280EXPORT_SYMBOL(w1_touch_bit);
187EXPORT_SYMBOL(w1_write_8); 281EXPORT_SYMBOL(w1_write_8);
188EXPORT_SYMBOL(w1_read_bit);
189EXPORT_SYMBOL(w1_read_8); 282EXPORT_SYMBOL(w1_read_8);
190EXPORT_SYMBOL(w1_reset_bus); 283EXPORT_SYMBOL(w1_reset_bus);
191EXPORT_SYMBOL(w1_calc_crc8); 284EXPORT_SYMBOL(w1_calc_crc8);
diff --git a/drivers/w1/w1_io.h b/drivers/w1/w1_io.h
index 6c573005a712..af5829778aaa 100644
--- a/drivers/w1/w1_io.h
+++ b/drivers/w1/w1_io.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1_io.h 2 * w1_io.h
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -26,13 +26,12 @@
26 26
27void w1_delay(unsigned long); 27void w1_delay(unsigned long);
28u8 w1_touch_bit(struct w1_master *, int); 28u8 w1_touch_bit(struct w1_master *, int);
29void w1_write_bit(struct w1_master *, int); 29u8 w1_triplet(struct w1_master *dev, int bdir);
30void w1_write_8(struct w1_master *, u8); 30void w1_write_8(struct w1_master *, u8);
31u8 w1_read_bit(struct w1_master *);
32u8 w1_read_8(struct w1_master *); 31u8 w1_read_8(struct w1_master *);
33int w1_reset_bus(struct w1_master *); 32int w1_reset_bus(struct w1_master *);
34u8 w1_calc_crc8(u8 *, int); 33u8 w1_calc_crc8(u8 *, int);
35void w1_write_block(struct w1_master *, u8 *, int); 34void w1_write_block(struct w1_master *, const u8 *, int);
36u8 w1_read_block(struct w1_master *, u8 *, int); 35u8 w1_read_block(struct w1_master *, u8 *, int);
37void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb); 36void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb);
38 37
diff --git a/drivers/w1/w1_log.h b/drivers/w1/w1_log.h
index a6bf6f44dce2..fe6bdf43380f 100644
--- a/drivers/w1/w1_log.h
+++ b/drivers/w1/w1_log.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1_log.h 2 * w1_log.h
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/w1/w1_netlink.h b/drivers/w1/w1_netlink.h
index ea1b530abad0..8615756946df 100644
--- a/drivers/w1/w1_netlink.h
+++ b/drivers/w1/w1_netlink.h
@@ -33,13 +33,13 @@ enum w1_netlink_message_types {
33 W1_MASTER_REMOVE, 33 W1_MASTER_REMOVE,
34}; 34};
35 35
36struct w1_netlink_msg 36struct w1_netlink_msg
37{ 37{
38 __u8 type; 38 __u8 type;
39 __u8 reserved[3]; 39 __u8 reserved[3];
40 union 40 union
41 { 41 {
42 struct w1_reg_num id; 42 struct w1_reg_num id;
43 __u64 w1_id; 43 __u64 w1_id;
44 struct 44 struct
45 { 45 {
diff --git a/drivers/w1/w1_smem.c b/drivers/w1/w1_smem.c
index 674eb75a9bad..70d2d469963c 100644
--- a/drivers/w1/w1_smem.c
+++ b/drivers/w1/w1_smem.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1_smem.c 2 * w1_smem.c
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the smems of the GNU General Public License as published by 8 * it under the smems of the GNU General Public License as published by
@@ -37,14 +37,11 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
37MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family."); 37MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family.");
38 38
39static ssize_t w1_smem_read_name(struct device *, struct device_attribute *attr, char *); 39static ssize_t w1_smem_read_name(struct device *, struct device_attribute *attr, char *);
40static ssize_t w1_smem_read_val(struct device *, struct device_attribute *attr, char *);
41static ssize_t w1_smem_read_bin(struct kobject *, char *, loff_t, size_t); 40static ssize_t w1_smem_read_bin(struct kobject *, char *, loff_t, size_t);
42 41
43static struct w1_family_ops w1_smem_fops = { 42static struct w1_family_ops w1_smem_fops = {
44 .rname = &w1_smem_read_name, 43 .rname = &w1_smem_read_name,
45 .rbin = &w1_smem_read_bin, 44 .rbin = &w1_smem_read_bin,
46 .rval = &w1_smem_read_val,
47 .rvalname = "id",
48}; 45};
49 46
50static ssize_t w1_smem_read_name(struct device *dev, struct device_attribute *attr, char *buf) 47static ssize_t w1_smem_read_name(struct device *dev, struct device_attribute *attr, char *buf)
@@ -54,23 +51,10 @@ static ssize_t w1_smem_read_name(struct device *dev, struct device_attribute *at
54 return sprintf(buf, "%s\n", sl->name); 51 return sprintf(buf, "%s\n", sl->name);
55} 52}
56 53
57static ssize_t w1_smem_read_val(struct device *dev, struct device_attribute *attr, char *buf)
58{
59 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
60 int i;
61 ssize_t count = 0;
62
63 for (i = 0; i < 8; ++i)
64 count += sprintf(buf + count, "%02x ", ((u8 *)&sl->reg_num)[i]);
65 count += sprintf(buf + count, "\n");
66
67 return count;
68}
69
70static ssize_t w1_smem_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count) 54static ssize_t w1_smem_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
71{ 55{
72 struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj), 56 struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj),
73 struct w1_slave, dev); 57 struct w1_slave, dev);
74 int i; 58 int i;
75 59
76 atomic_inc(&sl->refcnt); 60 atomic_inc(&sl->refcnt);
@@ -90,7 +74,7 @@ static ssize_t w1_smem_read_bin(struct kobject *kobj, char *buf, loff_t off, siz
90 for (i = 0; i < 8; ++i) 74 for (i = 0; i < 8; ++i)
91 count += sprintf(buf + count, "%02x ", ((u8 *)&sl->reg_num)[i]); 75 count += sprintf(buf + count, "%02x ", ((u8 *)&sl->reg_num)[i]);
92 count += sprintf(buf + count, "\n"); 76 count += sprintf(buf + count, "\n");
93 77
94out: 78out:
95 up(&sl->master->mutex); 79 up(&sl->master->mutex);
96out_dec: 80out_dec:
@@ -99,19 +83,37 @@ out_dec:
99 return count; 83 return count;
100} 84}
101 85
102static struct w1_family w1_smem_family = { 86static struct w1_family w1_smem_family_01 = {
103 .fid = W1_FAMILY_SMEM, 87 .fid = W1_FAMILY_SMEM_01,
88 .fops = &w1_smem_fops,
89};
90
91static struct w1_family w1_smem_family_81 = {
92 .fid = W1_FAMILY_SMEM_81,
104 .fops = &w1_smem_fops, 93 .fops = &w1_smem_fops,
105}; 94};
106 95
107static int __init w1_smem_init(void) 96static int __init w1_smem_init(void)
108{ 97{
109 return w1_register_family(&w1_smem_family); 98 int err;
99
100 err = w1_register_family(&w1_smem_family_01);
101 if (err)
102 return err;
103
104 err = w1_register_family(&w1_smem_family_81);
105 if (err) {
106 w1_unregister_family(&w1_smem_family_01);
107 return err;
108 }
109
110 return 0;
110} 111}
111 112
112static void __exit w1_smem_fini(void) 113static void __exit w1_smem_fini(void)
113{ 114{
114 w1_unregister_family(&w1_smem_family); 115 w1_unregister_family(&w1_smem_family_01);
116 w1_unregister_family(&w1_smem_family_81);
115} 117}
116 118
117module_init(w1_smem_init); 119module_init(w1_smem_init);
diff --git a/drivers/w1/w1_therm.c b/drivers/w1/w1_therm.c
index 70310f7a722e..165526c9360a 100644
--- a/drivers/w1/w1_therm.c
+++ b/drivers/w1/w1_therm.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * w1_therm.c 2 * w1_therm.c
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the therms of the GNU General Public License as published by 8 * it under the therms of the GNU General Public License as published by
@@ -38,19 +38,56 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
38MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family."); 38MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family.");
39 39
40static u8 bad_roms[][9] = { 40static u8 bad_roms[][9] = {
41 {0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87}, 41 {0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87},
42 {} 42 {}
43 }; 43 };
44 44
45static ssize_t w1_therm_read_name(struct device *, struct device_attribute *attr, char *); 45static ssize_t w1_therm_read_name(struct device *, struct device_attribute *attr, char *);
46static ssize_t w1_therm_read_temp(struct device *, struct device_attribute *attr, char *);
47static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t); 46static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t);
48 47
49static struct w1_family_ops w1_therm_fops = { 48static struct w1_family_ops w1_therm_fops = {
50 .rname = &w1_therm_read_name, 49 .rname = &w1_therm_read_name,
51 .rbin = &w1_therm_read_bin, 50 .rbin = &w1_therm_read_bin,
52 .rval = &w1_therm_read_temp, 51};
53 .rvalname = "temp1_input", 52
53static struct w1_family w1_therm_family_DS18S20 = {
54 .fid = W1_THERM_DS18S20,
55 .fops = &w1_therm_fops,
56};
57
58static struct w1_family w1_therm_family_DS18B20 = {
59 .fid = W1_THERM_DS18B20,
60 .fops = &w1_therm_fops,
61};
62static struct w1_family w1_therm_family_DS1822 = {
63 .fid = W1_THERM_DS1822,
64 .fops = &w1_therm_fops,
65};
66
67struct w1_therm_family_converter
68{
69 u8 broken;
70 u16 reserved;
71 struct w1_family *f;
72 int (*convert)(u8 rom[9]);
73};
74
75static inline int w1_DS18B20_convert_temp(u8 rom[9]);
76static inline int w1_DS18S20_convert_temp(u8 rom[9]);
77
78static struct w1_therm_family_converter w1_therm_families[] = {
79 {
80 .f = &w1_therm_family_DS18S20,
81 .convert = w1_DS18S20_convert_temp
82 },
83 {
84 .f = &w1_therm_family_DS1822,
85 .convert = w1_DS18B20_convert_temp
86 },
87 {
88 .f = &w1_therm_family_DS18B20,
89 .convert = w1_DS18B20_convert_temp
90 },
54}; 91};
55 92
56static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *attr, char *buf) 93static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *attr, char *buf)
@@ -60,9 +97,19 @@ static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *a
60 return sprintf(buf, "%s\n", sl->name); 97 return sprintf(buf, "%s\n", sl->name);
61} 98}
62 99
63static inline int w1_convert_temp(u8 rom[9]) 100static inline int w1_DS18B20_convert_temp(u8 rom[9])
101{
102 int t = (rom[1] << 8) | rom[0];
103 t /= 16;
104 return t;
105}
106
107static inline int w1_DS18S20_convert_temp(u8 rom[9])
64{ 108{
65 int t, h; 109 int t, h;
110
111 if (!rom[7])
112 return 0;
66 113
67 if (rom[1] == 0) 114 if (rom[1] == 0)
68 t = ((s32)rom[0] >> 1)*1000; 115 t = ((s32)rom[0] >> 1)*1000;
@@ -77,11 +124,15 @@ static inline int w1_convert_temp(u8 rom[9])
77 return t; 124 return t;
78} 125}
79 126
80static ssize_t w1_therm_read_temp(struct device *dev, struct device_attribute *attr, char *buf) 127static inline int w1_convert_temp(u8 rom[9], u8 fid)
81{ 128{
82 struct w1_slave *sl = container_of(dev, struct w1_slave, dev); 129 int i;
130
131 for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i)
132 if (w1_therm_families[i].f->fid == fid)
133 return w1_therm_families[i].convert(rom);
83 134
84 return sprintf(buf, "%d\n", w1_convert_temp(sl->rom)); 135 return 0;
85} 136}
86 137
87static int w1_therm_check_rom(u8 rom[9]) 138static int w1_therm_check_rom(u8 rom[9])
@@ -98,7 +149,7 @@ static int w1_therm_check_rom(u8 rom[9])
98static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count) 149static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
99{ 150{
100 struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj), 151 struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj),
101 struct w1_slave, dev); 152 struct w1_slave, dev);
102 struct w1_master *dev = sl->master; 153 struct w1_master *dev = sl->master;
103 u8 rom[9], crc, verdict; 154 u8 rom[9], crc, verdict;
104 int i, max_trying = 10; 155 int i, max_trying = 10;
@@ -133,7 +184,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
133 unsigned int tm = 750; 184 unsigned int tm = 750;
134 185
135 memcpy(&match[1], (u64 *) & sl->reg_num, 8); 186 memcpy(&match[1], (u64 *) & sl->reg_num, 8);
136 187
137 w1_write_block(dev, match, 9); 188 w1_write_block(dev, match, 9);
138 189
139 w1_write_8(dev, W1_CONVERT_TEMP); 190 w1_write_8(dev, W1_CONVERT_TEMP);
@@ -146,7 +197,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
146 197
147 if (!w1_reset_bus (dev)) { 198 if (!w1_reset_bus (dev)) {
148 w1_write_block(dev, match, 9); 199 w1_write_block(dev, match, 9);
149 200
150 w1_write_8(dev, W1_READ_SCRATCHPAD); 201 w1_write_8(dev, W1_READ_SCRATCHPAD);
151 if ((count = w1_read_block(dev, rom, 9)) != 9) { 202 if ((count = w1_read_block(dev, rom, 9)) != 9) {
152 dev_warn(&dev->dev, "w1_read_block() returned %d instead of 9.\n", count); 203 dev_warn(&dev->dev, "w1_read_block() returned %d instead of 9.\n", count);
@@ -176,7 +227,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
176 for (i = 0; i < 9; ++i) 227 for (i = 0; i < 9; ++i)
177 count += sprintf(buf + count, "%02x ", sl->rom[i]); 228 count += sprintf(buf + count, "%02x ", sl->rom[i]);
178 229
179 count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom)); 230 count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid));
180out: 231out:
181 up(&dev->mutex); 232 up(&dev->mutex);
182out_dec: 233out_dec:
@@ -186,19 +237,26 @@ out_dec:
186 return count; 237 return count;
187} 238}
188 239
189static struct w1_family w1_therm_family = {
190 .fid = W1_FAMILY_THERM,
191 .fops = &w1_therm_fops,
192};
193
194static int __init w1_therm_init(void) 240static int __init w1_therm_init(void)
195{ 241{
196 return w1_register_family(&w1_therm_family); 242 int err, i;
243
244 for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i) {
245 err = w1_register_family(w1_therm_families[i].f);
246 if (err)
247 w1_therm_families[i].broken = 1;
248 }
249
250 return 0;
197} 251}
198 252
199static void __exit w1_therm_fini(void) 253static void __exit w1_therm_fini(void)
200{ 254{
201 w1_unregister_family(&w1_therm_family); 255 int i;
256
257 for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i)
258 if (!w1_therm_families[i].broken)
259 w1_unregister_family(w1_therm_families[i].f);
202} 260}
203 261
204module_init(w1_therm_init); 262module_init(w1_therm_init);