]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/w1/slaves/w1_therm.c
Merge branch 'topic/jack-mechanical' into to-push
[linux-2.6-omap-h63xx.git] / drivers / w1 / slaves / w1_therm.c
index fb28acaeed6c4ab01235f09b764b8d0b7e1b20b6..2c8dff9f77da13396b0d02207e15d486ddbd5d4e 100644 (file)
@@ -37,31 +37,33 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
 MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family.");
 
+/* Allow the strong pullup to be disabled, but default to enabled.
+ * If it was disabled a parasite powered device might not get the require
+ * current to do a temperature conversion.  If it is enabled parasite powered
+ * devices have a better chance of getting the current required.
+ */
+static int w1_strong_pullup = 1;
+module_param_named(strong_pullup, w1_strong_pullup, int, 0);
+
 static u8 bad_roms[][9] = {
                                {0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87},
                                {}
                        };
 
-static ssize_t w1_therm_read_bin(struct kobject *, struct bin_attribute *,
-                                char *, loff_t, size_t);
+static ssize_t w1_therm_read(struct device *device,
+       struct device_attribute *attr, char *buf);
 
-static struct bin_attribute w1_therm_bin_attr = {
-       .attr = {
-               .name = "w1_slave",
-               .mode = S_IRUGO,
-       },
-       .size = W1_SLAVE_DATA_SIZE,
-       .read = w1_therm_read_bin,
-};
+static struct device_attribute w1_therm_attr =
+       __ATTR(w1_slave, S_IRUGO, w1_therm_read, NULL);
 
 static int w1_therm_add_slave(struct w1_slave *sl)
 {
-       return sysfs_create_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+       return device_create_file(&sl->dev, &w1_therm_attr);
 }
 
 static void w1_therm_remove_slave(struct w1_slave *sl)
 {
-       sysfs_remove_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+       device_remove_file(&sl->dev, &w1_therm_attr);
 }
 
 static struct w1_family_ops w1_therm_fops = {
@@ -160,30 +162,19 @@ static int w1_therm_check_rom(u8 rom[9])
        return 0;
 }
 
-static ssize_t w1_therm_read_bin(struct kobject *kobj,
-                                struct bin_attribute *bin_attr,
-                                char *buf, loff_t off, size_t count)
+static ssize_t w1_therm_read(struct device *device,
+       struct device_attribute *attr, char *buf)
 {
-       struct w1_slave *sl = kobj_to_w1_slave(kobj);
+       struct w1_slave *sl = dev_to_w1_slave(device);
        struct w1_master *dev = sl->master;
        u8 rom[9], crc, verdict;
        int i, max_trying = 10;
+       ssize_t c = PAGE_SIZE;
 
-       mutex_lock(&sl->master->mutex);
+       mutex_lock(&dev->mutex);
 
-       if (off > W1_SLAVE_DATA_SIZE) {
-               count = 0;
-               goto out;
-       }
-       if (off + count > W1_SLAVE_DATA_SIZE) {
-               count = 0;
-               goto out;
-       }
-
-       memset(buf, 0, count);
        memset(rom, 0, sizeof(rom));
 
-       count = 0;
        verdict = 0;
        crc = 0;
 
@@ -192,15 +183,20 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj,
                        int count = 0;
                        unsigned int tm = 750;
 
+                       /* 750ms strong pullup (or delay) after the convert */
+                       if (w1_strong_pullup)
+                               w1_next_pullup(dev, tm);
                        w1_write_8(dev, W1_CONVERT_TEMP);
-
-                       msleep(tm);
+                       if (!w1_strong_pullup)
+                               msleep(tm);
 
                        if (!w1_reset_select_slave(sl)) {
 
                                w1_write_8(dev, W1_READ_SCRATCHPAD);
                                if ((count = w1_read_block(dev, rom, 9)) != 9) {
-                                       dev_warn(&dev->dev, "w1_read_block() returned %d instead of 9.\n", count);
+                                       dev_warn(device, "w1_read_block() "
+                                               "returned %u instead of 9.\n",
+                                               count);
                                }
 
                                crc = w1_calc_crc8(rom, 8);
@@ -215,22 +211,22 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj,
        }
 
        for (i = 0; i < 9; ++i)
-               count += sprintf(buf + count, "%02x ", rom[i]);
-       count += sprintf(buf + count, ": crc=%02x %s\n",
+               c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", rom[i]);
+       c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n",
                           crc, (verdict) ? "YES" : "NO");
        if (verdict)
                memcpy(sl->rom, rom, sizeof(sl->rom));
        else
-               dev_warn(&dev->dev, "18S20 doesn't respond to CONVERT_TEMP.\n");
+               dev_warn(device, "18S20 doesn't respond to CONVERT_TEMP.\n");
 
        for (i = 0; i < 9; ++i)
-               count += sprintf(buf + count, "%02x ", sl->rom[i]);
+               c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]);
 
-       count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid));
-out:
+       c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n",
+               w1_convert_temp(rom, sl->family->fid));
        mutex_unlock(&dev->mutex);
 
-       return count;
+       return PAGE_SIZE - c;
 }
 
 static int __init w1_therm_init(void)