aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/w1.c
diff options
context:
space:
mode:
authorDavid Fries <david@fries.net>2008-10-16 01:04:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 14:21:49 -0400
commit6a158c0de791a81eb761ccf26ead1bd0834abac2 (patch)
treec4a35705bbeb2f90b81a5e5d44e9a7b45c2f666a /drivers/w1/w1.c
parent3c52e4e627896b42152cc6ff98216c302932227e (diff)
W1: feature, enable hardware strong pullup
Add a strong pullup option to the w1 system. This supplies extra power for parasite powered devices. There is a w1_master_pullup sysfs entry and enable_pullup module parameter to enable or disable the strong pullup. The one wire bus requires at a minimum one wire and ground. The common wire is used for sending and receiving data as well as supplying power to devices that are parasite powered of which temperature sensors can be one example. The bus must be idle and left high while a temperature conversion is in progress, in addition the normal pullup resister on larger networks or even higher temperatures might not supply enough power. The pullup resister can't provide too much pullup current, because devices need to pull the bus down to write a value. This enables the strong pullup for supported hardware, which can supply more current when requested. Unsupported hardware will just delay with the bus high. The hardware USB 2490 one wire bus master has a bit on some commands which will enable the strong pullup as soon as the command finishes executing. To use strong pullup, call the new w1_next_pullup function to register the duration. The next write command will call set_pullup before sending the data, and reset the duration to zero once it returns. Switched from simple_strtol to strict_strtol. Signed-off-by: David Fries <david@fries.net> Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/w1/w1.c')
-rw-r--r--drivers/w1/w1.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 9b5c11701c37..32418d4e555a 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -246,10 +246,14 @@ static ssize_t w1_master_attribute_store_search(struct device * dev,
246 struct device_attribute *attr, 246 struct device_attribute *attr,
247 const char * buf, size_t count) 247 const char * buf, size_t count)
248{ 248{
249 long tmp;
249 struct w1_master *md = dev_to_w1_master(dev); 250 struct w1_master *md = dev_to_w1_master(dev);
250 251
252 if (strict_strtol(buf, 0, &tmp) == -EINVAL)
253 return -EINVAL;
254
251 mutex_lock(&md->mutex); 255 mutex_lock(&md->mutex);
252 md->search_count = simple_strtol(buf, NULL, 0); 256 md->search_count = tmp;
253 mutex_unlock(&md->mutex); 257 mutex_unlock(&md->mutex);
254 wake_up_process(md->thread); 258 wake_up_process(md->thread);
255 259
@@ -270,6 +274,38 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
270 return count; 274 return count;
271} 275}
272 276
277static ssize_t w1_master_attribute_store_pullup(struct device *dev,
278 struct device_attribute *attr,
279 const char *buf, size_t count)
280{
281 long tmp;
282 struct w1_master *md = dev_to_w1_master(dev);
283
284 if (strict_strtol(buf, 0, &tmp) == -EINVAL)
285 return -EINVAL;
286
287 mutex_lock(&md->mutex);
288 md->enable_pullup = tmp;
289 mutex_unlock(&md->mutex);
290 wake_up_process(md->thread);
291
292 return count;
293}
294
295static ssize_t w1_master_attribute_show_pullup(struct device *dev,
296 struct device_attribute *attr,
297 char *buf)
298{
299 struct w1_master *md = dev_to_w1_master(dev);
300 ssize_t count;
301
302 mutex_lock(&md->mutex);
303 count = sprintf(buf, "%d\n", md->enable_pullup);
304 mutex_unlock(&md->mutex);
305
306 return count;
307}
308
273static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf) 309static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf)
274{ 310{
275 struct w1_master *md = dev_to_w1_master(dev); 311 struct w1_master *md = dev_to_w1_master(dev);
@@ -365,6 +401,7 @@ static W1_MASTER_ATTR_RO(attempts, S_IRUGO);
365static W1_MASTER_ATTR_RO(timeout, S_IRUGO); 401static W1_MASTER_ATTR_RO(timeout, S_IRUGO);
366static W1_MASTER_ATTR_RO(pointer, S_IRUGO); 402static W1_MASTER_ATTR_RO(pointer, S_IRUGO);
367static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO); 403static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO);
404static W1_MASTER_ATTR_RW(pullup, S_IRUGO | S_IWUGO);
368 405
369static struct attribute *w1_master_default_attrs[] = { 406static struct attribute *w1_master_default_attrs[] = {
370 &w1_master_attribute_name.attr, 407 &w1_master_attribute_name.attr,
@@ -375,6 +412,7 @@ static struct attribute *w1_master_default_attrs[] = {
375 &w1_master_attribute_timeout.attr, 412 &w1_master_attribute_timeout.attr,
376 &w1_master_attribute_pointer.attr, 413 &w1_master_attribute_pointer.attr,
377 &w1_master_attribute_search.attr, 414 &w1_master_attribute_search.attr,
415 &w1_master_attribute_pullup.attr,
378 NULL 416 NULL
379}; 417};
380 418