aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-22 13:41:59 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-22 13:41:59 -0400
commita0cd30fd26a398c0c6e50c6760610d4529f17a84 (patch)
tree00c02a25966468706adf9a1d035c08f71baa6078
parent94eb7f4cefaf3ed8e97504ce4f3946bdb908e501 (diff)
parente5c515b4532f4aac2b1136612d8c3ecd1891f431 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/w1-2.6
-rw-r--r--Documentation/w1/w1.generic107
-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
16 files changed, 716 insertions, 439 deletions
diff --git a/Documentation/w1/w1.generic b/Documentation/w1/w1.generic
index eace3046a858..f937fbe1cacb 100644
--- a/Documentation/w1/w1.generic
+++ b/Documentation/w1/w1.generic
@@ -1,19 +1,92 @@
1Any w1 device must be connected to w1 bus master device - for example 1The 1-wire (w1) subsystem
2ds9490 usb device or w1-over-GPIO or RS232 converter. 2------------------------------------------------------------------
3Driver for w1 bus master must provide several functions(you can find 3The 1-wire bus is a simple master-slave bus that communicates via a single
4them in struct w1_bus_master definition in w1.h) which then will be 4signal wire (plus ground, so two wires).
5called by w1 core to send various commands over w1 bus(by default it is 5
6reset and search commands). When some device is found on the bus, w1 core 6Devices communicate on the bus by pulling the signal to ground via an open
7checks if driver for it's family is loaded. 7drain output and by sampling the logic level of the signal line.
8If driver is loaded w1 core creates new w1_slave object and registers it 8
9in the system(creates some generic sysfs files(struct w1_family_ops in 9The w1 subsystem provides the framework for managing w1 masters and
10w1_family.h), notifies any registered listener and so on...). 10communication with slaves.
11It is device driver's business to provide any communication method 11
12upstream. 12All w1 slave devices must be connected to a w1 bus master device.
13For example w1_therm driver(ds18?20 thermal sensor family driver) 13
14provides temperature reading function which is bound to ->rbin() method 14Example w1 master devices:
15of the above w1_family_ops structure. 15 DS9490 usb device
16w1_smem - driver for simple 64bit memory cell provides ID reading 16 W1-over-GPIO
17method. 17 DS2482 (i2c to w1 bridge)
18 Emulated devices, such as a RS232 converter, parallel port adapter, etc
19
20
21What does the w1 subsystem do?
22------------------------------------------------------------------
23When a w1 master driver registers with the w1 subsystem, the following occurs:
24
25 - sysfs entries for that w1 master are created
26 - the w1 bus is periodically searched for new slave devices
27
28When a device is found on the bus, w1 core checks if driver for it's family is
29loaded. If so, the family driver is attached to the slave.
30If there is no driver for the family, a simple sysfs entry is created
31for the slave device.
32
33
34W1 device families
35------------------------------------------------------------------
36Slave devices are handled by a driver written for a family of w1 devices.
37
38A family driver populates a struct w1_family_ops (see w1_family.h) and
39registers with the w1 subsystem.
40
41Current family drivers:
42w1_therm - (ds18?20 thermal sensor family driver)
43 provides temperature reading function which is bound to ->rbin() method
44 of the above w1_family_ops structure.
45
46w1_smem - driver for simple 64bit memory cell provides ID reading method.
18 47
19You can call above methods by reading appropriate sysfs files. 48You can call above methods by reading appropriate sysfs files.
49
50
51What does a w1 master driver need to implement?
52------------------------------------------------------------------
53
54The driver for w1 bus master must provide at minimum two functions.
55
56Emulated devices must provide the ability to set the output signal level
57(write_bit) and sample the signal level (read_bit).
58
59Devices that support the 1-wire natively must provide the ability to write and
60sample a bit (touch_bit) and reset the bus (reset_bus).
61
62Most hardware provides higher-level functions that offload w1 handling.
63See struct w1_bus_master definition in w1.h for details.
64
65
66w1 master sysfs interface
67------------------------------------------------------------------
68<xx-xxxxxxxxxxxxx> - a directory for a found device. The format is family-serial
69bus - (standard) symlink to the w1 bus
70driver - (standard) symlink to the w1 driver
71w1_master_attempts - the number of times a search was attempted
72w1_master_max_slave_count
73 - the maximum slaves that may be attached to a master
74w1_master_name - the name of the device (w1_bus_masterX)
75w1_master_search - the number of searches left to do, -1=continual (default)
76w1_master_slave_count
77 - the number of slaves found
78w1_master_slaves - the names of the slaves, one per line
79w1_master_timeout - the delay in seconds between searches
80
81If you have a w1 bus that never changes (you don't add or remove devices),
82you can set w1_master_search to a positive value to disable searches.
83
84
85w1 slave sysfs interface
86------------------------------------------------------------------
87bus - (standard) symlink to the w1 bus
88driver - (standard) symlink to the w1 driver
89name - the device name, usually the same as the directory name
90w1_slave - (optional) a binary file whose meaning depends on the
91 family driver
92
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);