diff options
Diffstat (limited to 'drivers/w1/slaves')
| -rw-r--r-- | drivers/w1/slaves/Kconfig | 28 | ||||
| -rw-r--r-- | drivers/w1/slaves/Makefile | 3 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_bq27000.c | 4 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_ds2408.c | 216 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_ds2413.c | 150 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_ds2423.c | 28 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_ds2431.c | 44 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_ds2433.c | 48 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_ds2760.c | 37 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_ds2780.c | 38 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_ds2781.c | 38 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_ds28e04.c | 113 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_smem.c | 2 | ||||
| -rw-r--r-- | drivers/w1/slaves/w1_therm.c | 76 |
14 files changed, 467 insertions, 358 deletions
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index 67526690acb..1cdce80b6ab 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig @@ -17,11 +17,26 @@ config W1_SLAVE_SMEM simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire. config W1_SLAVE_DS2408 - tristate "8-Channel Addressable Switch (IO Expander) 0x29 family support (DS2408)" - help - Say Y here if you want to use a 1-wire + tristate "8-Channel Addressable Switch (IO Expander) 0x29 family support (DS2408)" + help + Say Y here if you want to use a 1-wire + DS2408 8-Channel Addressable Switch device support + +config W1_SLAVE_DS2408_READBACK + bool "Read-back values written to DS2408's output register" + depends on W1_SLAVE_DS2408 + default y + help + Enabling this will cause the driver to read back the values written + to the chip's output register in order to detect errors. - DS2408 8-Channel Addressable Switch device support + This is slower but useful when debugging chips and/or busses. + +config W1_SLAVE_DS2413 + tristate "Dual Channel Addressable Switch 0x3a family support (DS2413)" + help + Say Y here if you want to use a 1-wire + DS2413 Dual Channel Addressable Switch device support config W1_SLAVE_DS2423 tristate "Counter 1-wire device (DS2423)" @@ -57,7 +72,6 @@ config W1_SLAVE_DS2433_CRC config W1_SLAVE_DS2760 tristate "Dallas 2760 battery monitor chip (HP iPAQ & others)" - depends on W1 help If you enable this you will have the DS2760 battery monitor chip support. @@ -70,7 +84,6 @@ config W1_SLAVE_DS2760 config W1_SLAVE_DS2780 tristate "Dallas 2780 battery monitor chip" - depends on W1 help If you enable this you will have the DS2780 battery monitor chip support. @@ -83,7 +96,6 @@ config W1_SLAVE_DS2780 config W1_SLAVE_DS2781 tristate "Dallas 2781 battery monitor chip" - depends on W1 help If you enable this you will have the DS2781 battery monitor chip support. @@ -96,7 +108,6 @@ config W1_SLAVE_DS2781 config W1_SLAVE_DS28E04 tristate "4096-Bit Addressable 1-Wire EEPROM with PIO (DS28E04-100)" - depends on W1 select CRC16 help If you enable this you will have the DS28E04-100 @@ -109,7 +120,6 @@ config W1_SLAVE_DS28E04 config W1_SLAVE_BQ27000 tristate "BQ27000 slave support" - depends on W1 help Say Y here if you want to use a hdq bq27000 slave support. diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index 05188f6aab5..06529f3157a 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile @@ -4,7 +4,8 @@ obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o -obj-$(CONFIG_W1_SLAVE_DS2408) += w1_ds2408.o +obj-$(CONFIG_W1_SLAVE_DS2408) += w1_ds2408.o +obj-$(CONFIG_W1_SLAVE_DS2413) += w1_ds2413.o obj-$(CONFIG_W1_SLAVE_DS2423) += w1_ds2423.o obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c index 773dca5beaf..afbefed5f2c 100644 --- a/drivers/w1/slaves/w1_bq27000.c +++ b/drivers/w1/slaves/w1_bq27000.c @@ -57,6 +57,8 @@ static int w1_bq27000_add_slave(struct w1_slave *sl) ret = platform_device_add_data(pdev, &bq27000_battery_info, sizeof(bq27000_battery_info)); + if (ret) + goto pdev_add_failed; pdev->dev.parent = &sl->dev; ret = platform_device_add(pdev); @@ -68,7 +70,7 @@ static int w1_bq27000_add_slave(struct w1_slave *sl) goto success; pdev_add_failed: - platform_device_unregister(pdev); + platform_device_put(pdev); success: return ret; } diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index 441ad3a3b58..7dfa0e11688 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c @@ -22,6 +22,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jean-Francois Dagenais <dagenaisj@sonatest.com>"); MODULE_DESCRIPTION("w1 family 29 driver for DS2408 8 Pin IO"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2408)); #define W1_F29_RETRIES 3 @@ -71,10 +72,9 @@ static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf) return 1; } -static ssize_t w1_f29_read_state( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t state_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) { dev_dbg(&kobj_to_w1_slave(kobj)->dev, "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", @@ -84,10 +84,9 @@ static ssize_t w1_f29_read_state( return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf); } -static ssize_t w1_f29_read_output( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t output_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { dev_dbg(&kobj_to_w1_slave(kobj)->dev, "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", @@ -98,10 +97,9 @@ static ssize_t w1_f29_read_output( W1_F29_REG_OUTPUT_LATCH_STATE, buf); } -static ssize_t w1_f29_read_activity( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t activity_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { dev_dbg(&kobj_to_w1_slave(kobj)->dev, "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", @@ -112,10 +110,9 @@ static ssize_t w1_f29_read_activity( W1_F29_REG_ACTIVITY_LATCH_STATE, buf); } -static ssize_t w1_f29_read_cond_search_mask( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t cond_search_mask_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { dev_dbg(&kobj_to_w1_slave(kobj)->dev, "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", @@ -126,10 +123,10 @@ static ssize_t w1_f29_read_cond_search_mask( W1_F29_REG_COND_SEARCH_SELECT_MASK, buf); } -static ssize_t w1_f29_read_cond_search_polarity( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t cond_search_polarity_read(struct file *filp, + struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) { if (count != 1 || off != 0) return -EFAULT; @@ -137,10 +134,9 @@ static ssize_t w1_f29_read_cond_search_polarity( W1_F29_REG_COND_SEARCH_POL_SELECT, buf); } -static ssize_t w1_f29_read_status_control( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t status_control_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { if (count != 1 || off != 0) return -EFAULT; @@ -148,13 +144,9 @@ static ssize_t w1_f29_read_status_control( W1_F29_REG_CONTROL_AND_STATUS, buf); } - - - -static ssize_t w1_f29_write_output( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t output_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); u8 w1_buf[3]; @@ -178,6 +170,15 @@ static ssize_t w1_f29_write_output( w1_write_block(sl->master, w1_buf, 3); readBack = w1_read_8(sl->master); + + if (readBack != W1_F29_SUCCESS_CONFIRM_BYTE) { + if (w1_reset_resume_command(sl->master)) + goto error; + /* try again, the slave is ready for a command */ + continue; + } + +#ifdef CONFIG_W1_SLAVE_DS2408_READBACK /* here the master could read another byte which would be the PIO reg (the actual pin logic state) since in this driver we don't know which pins are @@ -186,11 +187,6 @@ static ssize_t w1_f29_write_output( if (w1_reset_resume_command(sl->master)) goto error; - if (readBack != 0xAA) { - /* try again, the slave is ready for a command */ - continue; - } - /* go read back the output latches */ /* (the direct effect of the write above) */ w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS; @@ -198,7 +194,9 @@ static ssize_t w1_f29_write_output( w1_buf[2] = 0; w1_write_block(sl->master, w1_buf, 3); /* read the result of the READ_PIO_REGS command */ - if (w1_read_8(sl->master) == *buf) { + if (w1_read_8(sl->master) == *buf) +#endif + { /* success! */ mutex_unlock(&sl->master->bus_mutex); dev_dbg(&sl->dev, @@ -217,10 +215,9 @@ error: /** * Writing to the activity file resets the activity latches. */ -static ssize_t w1_f29_write_activity( - struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t activity_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); unsigned int retries = W1_F29_RETRIES; @@ -248,13 +245,9 @@ error: return -EIO; } -static ssize_t w1_f29_write_status_control( - struct file *filp, - struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, - loff_t off, - size_t count) +static ssize_t status_control_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); u8 w1_buf[4]; @@ -295,90 +288,63 @@ error: return -EIO; } +/* + * This is a special sequence we must do to ensure the P0 output is not stuck + * in test mode. This is described in rev 2 of the ds2408's datasheet + * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under + * "APPLICATION INFORMATION/Power-up timing". + */ +static int w1_f29_disable_test_mode(struct w1_slave *sl) +{ + int res; + u8 magic[10] = {0x96, }; + u64 rn = le64_to_cpu(*((u64*)&sl->reg_num)); + memcpy(&magic[1], &rn, 8); + magic[9] = 0x3C; -#define NB_SYSFS_BIN_FILES 6 -static struct bin_attribute w1_f29_sysfs_bin_files[NB_SYSFS_BIN_FILES] = { - { - .attr = { - .name = "state", - .mode = S_IRUGO, - }, - .size = 1, - .read = w1_f29_read_state, - }, - { - .attr = { - .name = "output", - .mode = S_IRUGO | S_IWUSR | S_IWGRP, - }, - .size = 1, - .read = w1_f29_read_output, - .write = w1_f29_write_output, - }, - { - .attr = { - .name = "activity", - .mode = S_IRUGO, - }, - .size = 1, - .read = w1_f29_read_activity, - .write = w1_f29_write_activity, - }, - { - .attr = { - .name = "cond_search_mask", - .mode = S_IRUGO, - }, - .size = 1, - .read = w1_f29_read_cond_search_mask, - }, - { - .attr = { - .name = "cond_search_polarity", - .mode = S_IRUGO, - }, - .size = 1, - .read = w1_f29_read_cond_search_polarity, - }, - { - .attr = { - .name = "status_control", - .mode = S_IRUGO | S_IWUSR | S_IWGRP, - }, - .size = 1, - .read = w1_f29_read_status_control, - .write = w1_f29_write_status_control, - } -}; + mutex_lock(&sl->master->bus_mutex); -static int w1_f29_add_slave(struct w1_slave *sl) -{ - int err = 0; - int i; - - for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i) - err = sysfs_create_bin_file( - &sl->dev.kobj, - &(w1_f29_sysfs_bin_files[i])); - if (err) - while (--i >= 0) - sysfs_remove_bin_file(&sl->dev.kobj, - &(w1_f29_sysfs_bin_files[i])); - return err; -} + res = w1_reset_bus(sl->master); + if (res) + goto out; + w1_write_block(sl->master, magic, ARRAY_SIZE(magic)); -static void w1_f29_remove_slave(struct w1_slave *sl) -{ - int i; - for (i = NB_SYSFS_BIN_FILES - 1; i >= 0; --i) - sysfs_remove_bin_file(&sl->dev.kobj, - &(w1_f29_sysfs_bin_files[i])); + res = w1_reset_bus(sl->master); +out: + mutex_unlock(&sl->master->bus_mutex); + return res; } +static BIN_ATTR_RO(state, 1); +static BIN_ATTR_RW(output, 1); +static BIN_ATTR_RW(activity, 1); +static BIN_ATTR_RO(cond_search_mask, 1); +static BIN_ATTR_RO(cond_search_polarity, 1); +static BIN_ATTR_RW(status_control, 1); + +static struct bin_attribute *w1_f29_bin_attrs[] = { + &bin_attr_state, + &bin_attr_output, + &bin_attr_activity, + &bin_attr_cond_search_mask, + &bin_attr_cond_search_polarity, + &bin_attr_status_control, + NULL, +}; + +static const struct attribute_group w1_f29_group = { + .bin_attrs = w1_f29_bin_attrs, +}; + +static const struct attribute_group *w1_f29_groups[] = { + &w1_f29_group, + NULL, +}; + static struct w1_family_ops w1_f29_fops = { - .add_slave = w1_f29_add_slave, - .remove_slave = w1_f29_remove_slave, + .add_slave = w1_f29_disable_test_mode, + .groups = w1_f29_groups, }; static struct w1_family w1_family_29 = { diff --git a/drivers/w1/slaves/w1_ds2413.c b/drivers/w1/slaves/w1_ds2413.c new file mode 100644 index 00000000000..ee28fc1ff39 --- /dev/null +++ b/drivers/w1/slaves/w1_ds2413.c @@ -0,0 +1,150 @@ +/* + * w1_ds2413.c - w1 family 3a (DS2413) driver + * based on w1_ds2408.c by Jean-Francois Dagenais <dagenaisj@sonatest.com> + * + * Copyright (c) 2013 Mariusz Bialonczyk <manio@skyboo.net> + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/device.h> +#include <linux/types.h> +#include <linux/delay.h> +#include <linux/slab.h> + +#include "../w1.h" +#include "../w1_int.h" +#include "../w1_family.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mariusz Bialonczyk <manio@skyboo.net>"); +MODULE_DESCRIPTION("w1 family 3a driver for DS2413 2 Pin IO"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2413)); + +#define W1_F3A_RETRIES 3 +#define W1_F3A_FUNC_PIO_ACCESS_READ 0xF5 +#define W1_F3A_FUNC_PIO_ACCESS_WRITE 0x5A +#define W1_F3A_SUCCESS_CONFIRM_BYTE 0xAA + +static ssize_t state_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) +{ + struct w1_slave *sl = kobj_to_w1_slave(kobj); + dev_dbg(&sl->dev, + "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", + bin_attr->attr.name, kobj, (unsigned int)off, count, buf); + + if (off != 0) + return 0; + if (!buf) + return -EINVAL; + + mutex_lock(&sl->master->bus_mutex); + dev_dbg(&sl->dev, "mutex locked"); + + if (w1_reset_select_slave(sl)) { + mutex_unlock(&sl->master->bus_mutex); + return -EIO; + } + + w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ); + *buf = w1_read_8(sl->master); + + mutex_unlock(&sl->master->bus_mutex); + dev_dbg(&sl->dev, "mutex unlocked"); + + /* check for correct complement */ + if ((*buf & 0x0F) != ((~*buf >> 4) & 0x0F)) + return -EIO; + else + return 1; +} + +static BIN_ATTR_RO(state, 1); + +static ssize_t output_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) +{ + struct w1_slave *sl = kobj_to_w1_slave(kobj); + u8 w1_buf[3]; + unsigned int retries = W1_F3A_RETRIES; + + if (count != 1 || off != 0) + return -EFAULT; + + dev_dbg(&sl->dev, "locking mutex for write_output"); + mutex_lock(&sl->master->bus_mutex); + dev_dbg(&sl->dev, "mutex locked"); + + if (w1_reset_select_slave(sl)) + goto error; + + /* according to the DS2413 datasheet the most significant 6 bits + should be set to "1"s, so do it now */ + *buf = *buf | 0xFC; + + while (retries--) { + w1_buf[0] = W1_F3A_FUNC_PIO_ACCESS_WRITE; + w1_buf[1] = *buf; + w1_buf[2] = ~(*buf); + w1_write_block(sl->master, w1_buf, 3); + + if (w1_read_8(sl->master) == W1_F3A_SUCCESS_CONFIRM_BYTE) { + mutex_unlock(&sl->master->bus_mutex); + dev_dbg(&sl->dev, "mutex unlocked, retries:%d", retries); + return 1; + } + if (w1_reset_resume_command(sl->master)) + goto error; + } + +error: + mutex_unlock(&sl->master->bus_mutex); + dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries); + return -EIO; +} + +static BIN_ATTR(output, S_IRUGO | S_IWUSR | S_IWGRP, NULL, output_write, 1); + +static struct bin_attribute *w1_f3a_bin_attrs[] = { + &bin_attr_state, + &bin_attr_output, + NULL, +}; + +static const struct attribute_group w1_f3a_group = { + .bin_attrs = w1_f3a_bin_attrs, +}; + +static const struct attribute_group *w1_f3a_groups[] = { + &w1_f3a_group, + NULL, +}; + +static struct w1_family_ops w1_f3a_fops = { + .groups = w1_f3a_groups, +}; + +static struct w1_family w1_family_3a = { + .fid = W1_FAMILY_DS2413, + .fops = &w1_f3a_fops, +}; + +static int __init w1_f3a_init(void) +{ + return w1_register_family(&w1_family_3a); +} + +static void __exit w1_f3a_exit(void) +{ + w1_unregister_family(&w1_family_3a); +} + +module_init(w1_f3a_init); +module_exit(w1_f3a_exit); diff --git a/drivers/w1/slaves/w1_ds2423.c b/drivers/w1/slaves/w1_ds2423.c index 40a10b5ed12..7e41b7d91fb 100644 --- a/drivers/w1/slaves/w1_ds2423.c +++ b/drivers/w1/slaves/w1_ds2423.c @@ -40,14 +40,8 @@ #define COUNTER_COUNT 4 #define READ_BYTE_COUNT 42 -static ssize_t w1_counter_read(struct device *device, - struct device_attribute *attr, char *buf); - -static struct device_attribute w1_counter_attr = - __ATTR(w1_slave, S_IRUGO, w1_counter_read, NULL); - -static ssize_t w1_counter_read(struct device *device, - struct device_attribute *attr, char *out_buf) +static ssize_t w1_slave_show(struct device *device, + struct device_attribute *attr, char *out_buf) { struct w1_slave *sl = dev_to_w1_slave(device); struct w1_master *dev = sl->master; @@ -128,19 +122,16 @@ static ssize_t w1_counter_read(struct device *device, return PAGE_SIZE - c; } -static int w1_f1d_add_slave(struct w1_slave *sl) -{ - return device_create_file(&sl->dev, &w1_counter_attr); -} +static DEVICE_ATTR_RO(w1_slave); -static void w1_f1d_remove_slave(struct w1_slave *sl) -{ - device_remove_file(&sl->dev, &w1_counter_attr); -} +static struct attribute *w1_f1d_attrs[] = { + &dev_attr_w1_slave.attr, + NULL, +}; +ATTRIBUTE_GROUPS(w1_f1d); static struct w1_family_ops w1_f1d_fops = { - .add_slave = w1_f1d_add_slave, - .remove_slave = w1_f1d_remove_slave, + .groups = w1_f1d_groups, }; static struct w1_family w1_family_1d = { @@ -164,3 +155,4 @@ module_exit(w1_f1d_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mika Laitio <lamikr@pilppa.org>"); MODULE_DESCRIPTION("w1 family 1d driver for DS2423, 4 counters and 4kb ram"); +MODULE_ALIAS("w1-family-" __stringify(W1_COUNTER_DS2423)); diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c index 984b30331a4..9c4ff9d28ad 100644 --- a/drivers/w1/slaves/w1_ds2431.c +++ b/drivers/w1/slaves/w1_ds2431.c @@ -96,9 +96,9 @@ static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf) return -1; } -static ssize_t w1_f2d_read_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); int todo = count; @@ -202,9 +202,9 @@ retry: return 0; } -static ssize_t w1_f2d_write_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); int addr, len; @@ -264,29 +264,24 @@ out_up: return count; } -static struct bin_attribute w1_f2d_bin_attr = { - .attr = { - .name = "eeprom", - .mode = S_IRUGO | S_IWUSR, - }, - .size = W1_F2D_EEPROM_SIZE, - .read = w1_f2d_read_bin, - .write = w1_f2d_write_bin, +static BIN_ATTR_RW(eeprom, W1_F2D_EEPROM_SIZE); + +static struct bin_attribute *w1_f2d_bin_attrs[] = { + &bin_attr_eeprom, + NULL, }; -static int w1_f2d_add_slave(struct w1_slave *sl) -{ - return sysfs_create_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr); -} +static const struct attribute_group w1_f2d_group = { + .bin_attrs = w1_f2d_bin_attrs, +}; -static void w1_f2d_remove_slave(struct w1_slave *sl) -{ - sysfs_remove_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr); -} +static const struct attribute_group *w1_f2d_groups[] = { + &w1_f2d_group, + NULL, +}; static struct w1_family_ops w1_f2d_fops = { - .add_slave = w1_f2d_add_slave, - .remove_slave = w1_f2d_remove_slave, + .groups = w1_f2d_groups, }; static struct w1_family w1_family_2d = { @@ -310,3 +305,4 @@ module_exit(w1_f2d_fini); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Bernhard Weirich <bernhard.weirich@riedel.net>"); MODULE_DESCRIPTION("w1 family 2d driver for DS2431, 1kb EEPROM"); +MODULE_ALIAS("w1-family-" __stringify(W1_EEPROM_DS2431)); diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index 85f2cdb27fa..72319a968a9 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c @@ -29,6 +29,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>"); MODULE_DESCRIPTION("w1 family 23 driver for DS2433, 4kb EEPROM"); +MODULE_ALIAS("w1-family-" __stringify(W1_EEPROM_DS2433)); #define W1_EEPROM_SIZE 512 #define W1_PAGE_COUNT 16 @@ -92,9 +93,9 @@ static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data, } #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ -static ssize_t w1_f23_read_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); #ifdef CONFIG_W1_SLAVE_DS2433_CRC @@ -206,9 +207,9 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data) return 0; } -static ssize_t w1_f23_write_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); int addr, len, idx; @@ -256,19 +257,24 @@ out_up: return count; } -static struct bin_attribute w1_f23_bin_attr = { - .attr = { - .name = "eeprom", - .mode = S_IRUGO | S_IWUSR, - }, - .size = W1_EEPROM_SIZE, - .read = w1_f23_read_bin, - .write = w1_f23_write_bin, +static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE); + +static struct bin_attribute *w1_f23_bin_attributes[] = { + &bin_attr_eeprom, + NULL, +}; + +static const struct attribute_group w1_f23_group = { + .bin_attrs = w1_f23_bin_attributes, +}; + +static const struct attribute_group *w1_f23_groups[] = { + &w1_f23_group, + NULL, }; static int w1_f23_add_slave(struct w1_slave *sl) { - int err; #ifdef CONFIG_W1_SLAVE_DS2433_CRC struct w1_f23_data *data; @@ -278,15 +284,7 @@ static int w1_f23_add_slave(struct w1_slave *sl) sl->family_data = data; #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ - - err = sysfs_create_bin_file(&sl->dev.kobj, &w1_f23_bin_attr); - -#ifdef CONFIG_W1_SLAVE_DS2433_CRC - if (err) - kfree(data); -#endif /* CONFIG_W1_SLAVE_DS2433_CRC */ - - return err; + return 0; } static void w1_f23_remove_slave(struct w1_slave *sl) @@ -295,12 +293,12 @@ static void w1_f23_remove_slave(struct w1_slave *sl) kfree(sl->family_data); sl->family_data = NULL; #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ - sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr); } static struct w1_family_ops w1_f23_fops = { .add_slave = w1_f23_add_slave, .remove_slave = w1_f23_remove_slave, + .groups = w1_f23_groups, }; static struct w1_family w1_family_23 = { diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index aa7bd5fa2fa..65f90dccd60 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c @@ -97,21 +97,28 @@ int w1_ds2760_recall_eeprom(struct device *dev, int addr) return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA); } -static ssize_t w1_ds2760_read_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); return w1_ds2760_read(dev, buf, off, count); } -static struct bin_attribute w1_ds2760_bin_attr = { - .attr = { - .name = "w1_slave", - .mode = S_IRUGO, - }, - .size = DS2760_DATA_SIZE, - .read = w1_ds2760_read_bin, +static BIN_ATTR_RO(w1_slave, DS2760_DATA_SIZE); + +static struct bin_attribute *w1_ds2760_bin_attrs[] = { + &bin_attr_w1_slave, + NULL, +}; + +static const struct attribute_group w1_ds2760_group = { + .bin_attrs = w1_ds2760_bin_attrs, +}; + +static const struct attribute_group *w1_ds2760_groups[] = { + &w1_ds2760_group, + NULL, }; static DEFINE_IDA(bat_ida); @@ -139,17 +146,12 @@ static int w1_ds2760_add_slave(struct w1_slave *sl) if (ret) goto pdev_add_failed; - ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr); - if (ret) - goto bin_attr_failed; - dev_set_drvdata(&sl->dev, pdev); goto success; -bin_attr_failed: pdev_add_failed: - platform_device_unregister(pdev); + platform_device_put(pdev); pdev_alloc_failed: ida_simple_remove(&bat_ida, id); noid: @@ -164,12 +166,12 @@ static void w1_ds2760_remove_slave(struct w1_slave *sl) platform_device_unregister(pdev); ida_simple_remove(&bat_ida, id); - sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr); } static struct w1_family_ops w1_ds2760_fops = { .add_slave = w1_ds2760_add_slave, .remove_slave = w1_ds2760_remove_slave, + .groups = w1_ds2760_groups, }; static struct w1_family w1_ds2760_family = { @@ -202,3 +204,4 @@ module_exit(w1_ds2760_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>"); MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2760)); diff --git a/drivers/w1/slaves/w1_ds2780.c b/drivers/w1/slaves/w1_ds2780.c index 7b09307de0e..50e85f7929d 100644 --- a/drivers/w1/slaves/w1_ds2780.c +++ b/drivers/w1/slaves/w1_ds2780.c @@ -89,22 +89,28 @@ int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd) } EXPORT_SYMBOL(w1_ds2780_eeprom_cmd); -static ssize_t w1_ds2780_read_bin(struct file *filp, - struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); return w1_ds2780_io(dev, buf, off, count, 0); } -static struct bin_attribute w1_ds2780_bin_attr = { - .attr = { - .name = "w1_slave", - .mode = S_IRUGO, - }, - .size = DS2780_DATA_SIZE, - .read = w1_ds2780_read_bin, +static BIN_ATTR_RO(w1_slave, DS2780_DATA_SIZE); + +static struct bin_attribute *w1_ds2780_bin_attrs[] = { + &bin_attr_w1_slave, + NULL, +}; + +static const struct attribute_group w1_ds2780_group = { + .bin_attrs = w1_ds2780_bin_attrs, +}; + +static const struct attribute_group *w1_ds2780_groups[] = { + &w1_ds2780_group, + NULL, }; static DEFINE_IDA(bat_ida); @@ -132,17 +138,12 @@ static int w1_ds2780_add_slave(struct w1_slave *sl) if (ret) goto pdev_add_failed; - ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2780_bin_attr); - if (ret) - goto bin_attr_failed; - dev_set_drvdata(&sl->dev, pdev); return 0; -bin_attr_failed: pdev_add_failed: - platform_device_unregister(pdev); + platform_device_put(pdev); pdev_alloc_failed: ida_simple_remove(&bat_ida, id); noid: @@ -156,12 +157,12 @@ static void w1_ds2780_remove_slave(struct w1_slave *sl) platform_device_unregister(pdev); ida_simple_remove(&bat_ida, id); - sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2780_bin_attr); } static struct w1_family_ops w1_ds2780_fops = { .add_slave = w1_ds2780_add_slave, .remove_slave = w1_ds2780_remove_slave, + .groups = w1_ds2780_groups, }; static struct w1_family w1_ds2780_family = { @@ -187,3 +188,4 @@ module_exit(w1_ds2780_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>"); MODULE_DESCRIPTION("1-wire Driver for Maxim/Dallas DS2780 Stand-Alone Fuel Gauge IC"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2780)); diff --git a/drivers/w1/slaves/w1_ds2781.c b/drivers/w1/slaves/w1_ds2781.c index 877daf74159..1eb98fb1688 100644 --- a/drivers/w1/slaves/w1_ds2781.c +++ b/drivers/w1/slaves/w1_ds2781.c @@ -87,22 +87,28 @@ int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd) } EXPORT_SYMBOL(w1_ds2781_eeprom_cmd); -static ssize_t w1_ds2781_read_bin(struct file *filp, - struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); return w1_ds2781_io(dev, buf, off, count, 0); } -static struct bin_attribute w1_ds2781_bin_attr = { - .attr = { - .name = "w1_slave", - .mode = S_IRUGO, - }, - .size = DS2781_DATA_SIZE, - .read = w1_ds2781_read_bin, +static BIN_ATTR_RO(w1_slave, DS2781_DATA_SIZE); + +static struct bin_attribute *w1_ds2781_bin_attrs[] = { + &bin_attr_w1_slave, + NULL, +}; + +static const struct attribute_group w1_ds2781_group = { + .bin_attrs = w1_ds2781_bin_attrs, +}; + +static const struct attribute_group *w1_ds2781_groups[] = { + &w1_ds2781_group, + NULL, }; static DEFINE_IDA(bat_ida); @@ -130,17 +136,12 @@ static int w1_ds2781_add_slave(struct w1_slave *sl) if (ret) goto pdev_add_failed; - ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2781_bin_attr); - if (ret) - goto bin_attr_failed; - dev_set_drvdata(&sl->dev, pdev); return 0; -bin_attr_failed: pdev_add_failed: - platform_device_unregister(pdev); + platform_device_put(pdev); pdev_alloc_failed: ida_simple_remove(&bat_ida, id); noid: @@ -154,12 +155,12 @@ static void w1_ds2781_remove_slave(struct w1_slave *sl) platform_device_unregister(pdev); ida_simple_remove(&bat_ida, id); - sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2781_bin_attr); } static struct w1_family_ops w1_ds2781_fops = { .add_slave = w1_ds2781_add_slave, .remove_slave = w1_ds2781_remove_slave, + .groups = w1_ds2781_groups, }; static struct w1_family w1_ds2781_family = { @@ -185,3 +186,4 @@ module_exit(w1_ds2781_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Renata Sayakhova <renata@oktetlabs.ru>"); MODULE_DESCRIPTION("1-wire Driver for Maxim/Dallas DS2781 Stand-Alone Fuel Gauge IC"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2781)); diff --git a/drivers/w1/slaves/w1_ds28e04.c b/drivers/w1/slaves/w1_ds28e04.c index 98117db595b..365d6dff21d 100644 --- a/drivers/w1/slaves/w1_ds28e04.c +++ b/drivers/w1/slaves/w1_ds28e04.c @@ -27,6 +27,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Markus Franke <franke.m@sebakmt.com>, <franm@hrz.tu-chemnitz.de>"); MODULE_DESCRIPTION("w1 family 1C driver for DS28E04, 4kb EEPROM and PIO"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS28E04)); /* Allow the strong pullup to be disabled, but default to enabled. * If it was disabled a parasite powered device might not get the required @@ -117,9 +118,9 @@ static int w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data) return w1_read_block(sl->master, data, len); } -static ssize_t w1_f1C_read_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); struct w1_f1C_data *data = sl->family_data; @@ -225,9 +226,9 @@ static int w1_f1C_write(struct w1_slave *sl, int addr, int len, const u8 *data) return 0; } -static ssize_t w1_f1C_write_bin(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); @@ -279,9 +280,11 @@ out_up: return count; } -static ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE); + +static ssize_t pio_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); @@ -298,9 +301,9 @@ static ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *kobj, return ret; } -static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t pio_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, + size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); @@ -338,8 +341,10 @@ static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *kobj, return count; } -static ssize_t w1_f1C_show_crccheck(struct device *dev, - struct device_attribute *attr, char *buf) +static BIN_ATTR_RW(pio, 1); + +static ssize_t crccheck_show(struct device *dev, struct device_attribute *attr, + char *buf) { if (put_user(w1_enable_crccheck + 0x30, buf)) return -EFAULT; @@ -347,9 +352,8 @@ static ssize_t w1_f1C_show_crccheck(struct device *dev, return sizeof(w1_enable_crccheck); } -static ssize_t w1_f1C_store_crccheck(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t crccheck_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { char val; @@ -370,35 +374,31 @@ static ssize_t w1_f1C_store_crccheck(struct device *dev, return sizeof(w1_enable_crccheck); } -#define NB_SYSFS_BIN_FILES 2 -static struct bin_attribute w1_f1C_bin_attr[NB_SYSFS_BIN_FILES] = { - { - .attr = { - .name = "eeprom", - .mode = S_IRUGO | S_IWUSR, - }, - .size = W1_EEPROM_SIZE, - .read = w1_f1C_read_bin, - .write = w1_f1C_write_bin, - }, - { - .attr = { - .name = "pio", - .mode = S_IRUGO | S_IWUSR, - }, - .size = 1, - .read = w1_f1C_read_pio, - .write = w1_f1C_write_pio, - } +static DEVICE_ATTR_RW(crccheck); + +static struct attribute *w1_f1C_attrs[] = { + &dev_attr_crccheck.attr, + NULL, }; -static DEVICE_ATTR(crccheck, S_IWUSR | S_IRUGO, - w1_f1C_show_crccheck, w1_f1C_store_crccheck); +static struct bin_attribute *w1_f1C_bin_attrs[] = { + &bin_attr_eeprom, + &bin_attr_pio, + NULL, +}; + +static const struct attribute_group w1_f1C_group = { + .attrs = w1_f1C_attrs, + .bin_attrs = w1_f1C_bin_attrs, +}; + +static const struct attribute_group *w1_f1C_groups[] = { + &w1_f1C_group, + NULL, +}; static int w1_f1C_add_slave(struct w1_slave *sl) { - int err = 0; - int i; struct w1_f1C_data *data = NULL; if (w1_enable_crccheck) { @@ -408,46 +408,19 @@ static int w1_f1C_add_slave(struct w1_slave *sl) sl->family_data = data; } - /* create binary sysfs attributes */ - for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i) - err = sysfs_create_bin_file( - &sl->dev.kobj, &(w1_f1C_bin_attr[i])); - - if (!err) { - /* create device attributes */ - err = device_create_file(&sl->dev, &dev_attr_crccheck); - } - - if (err) { - /* remove binary sysfs attributes */ - for (i = 0; i < NB_SYSFS_BIN_FILES; ++i) - sysfs_remove_bin_file( - &sl->dev.kobj, &(w1_f1C_bin_attr[i])); - - kfree(data); - } - - return err; + return 0; } static void w1_f1C_remove_slave(struct w1_slave *sl) { - int i; - kfree(sl->family_data); sl->family_data = NULL; - - /* remove device attributes */ - device_remove_file(&sl->dev, &dev_attr_crccheck); - - /* remove binary sysfs attributes */ - for (i = 0; i < NB_SYSFS_BIN_FILES; ++i) - sysfs_remove_bin_file(&sl->dev.kobj, &(w1_f1C_bin_attr[i])); } static struct w1_family_ops w1_f1C_fops = { .add_slave = w1_f1C_add_slave, .remove_slave = w1_f1C_remove_slave, + .groups = w1_f1C_groups, }; static struct w1_family w1_family_1C = { diff --git a/drivers/w1/slaves/w1_smem.c b/drivers/w1/slaves/w1_smem.c index 84655625c87..ed4c87506de 100644 --- a/drivers/w1/slaves/w1_smem.c +++ b/drivers/w1/slaves/w1_smem.c @@ -34,6 +34,8 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family."); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_SMEM_01)); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_SMEM_81)); static struct w1_family w1_smem_family_01 = { .fid = W1_FAMILY_SMEM_01, diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 92d08e7fcba..1f11a20a8ab 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -27,6 +27,7 @@ #include <linux/sched.h> #include <linux/device.h> #include <linux/types.h> +#include <linux/slab.h> #include <linux/delay.h> #include "../w1.h" @@ -36,39 +37,57 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family."); +MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS18S20)); +MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS1822)); +MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS18B20)); +MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS1825)); +MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS28EA00)); /* 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. + * In case the parasite power-detection is not working (seems to be the case + * for some DS18S20) the strong pullup can also be forced, regardless of the + * power state of the devices. + * + * Summary of options: + * - strong_pullup = 0 Disable strong pullup completely + * - strong_pullup = 1 Enable automatic strong pullup detection + * - strong_pullup = 2 Force strong pullup */ 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(struct device *device, - struct device_attribute *attr, char *buf); - -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 device_create_file(&sl->dev, &w1_therm_attr); + sl->family_data = kzalloc(9, GFP_KERNEL); + if (!sl->family_data) + return -ENOMEM; + return 0; } static void w1_therm_remove_slave(struct w1_slave *sl) { - device_remove_file(&sl->dev, &w1_therm_attr); + kfree(sl->family_data); + sl->family_data = NULL; } +static ssize_t w1_slave_show(struct device *device, + struct device_attribute *attr, char *buf); + +static DEVICE_ATTR_RO(w1_slave); + +static struct attribute *w1_therm_attrs[] = { + &dev_attr_w1_slave.attr, + NULL, +}; +ATTRIBUTE_GROUPS(w1_therm); + static struct w1_family_ops w1_therm_fops = { .add_slave = w1_therm_add_slave, .remove_slave = w1_therm_remove_slave, + .groups = w1_therm_groups, }; static struct w1_family w1_therm_family_DS18S20 = { @@ -168,18 +187,8 @@ static inline int w1_convert_temp(u8 rom[9], u8 fid) return 0; } -static int w1_therm_check_rom(u8 rom[9]) -{ - int i; - - for (i=0; i<sizeof(bad_roms)/9; ++i) - if (!memcmp(bad_roms[i], rom, 9)) - return 1; - - return 0; -} -static ssize_t w1_therm_read(struct device *device, +static ssize_t w1_slave_show(struct device *device, struct device_attribute *attr, char *buf) { struct w1_slave *sl = dev_to_w1_slave(device); @@ -194,10 +203,11 @@ static ssize_t w1_therm_read(struct device *device, memset(rom, 0, sizeof(rom)); - verdict = 0; - crc = 0; - while (max_trying--) { + + verdict = 0; + crc = 0; + if (!w1_reset_select_slave(sl)) { int count = 0; unsigned int tm = 750; @@ -210,7 +220,8 @@ static ssize_t w1_therm_read(struct device *device, continue; /* 750ms strong pullup (or delay) after the convert */ - if (!external_power && w1_strong_pullup) + if (w1_strong_pullup == 2 || + (!external_power && w1_strong_pullup)) w1_next_pullup(dev, tm); w1_write_8(dev, W1_CONVERT_TEMP); @@ -249,7 +260,7 @@ static ssize_t w1_therm_read(struct device *device, } } - if (!w1_therm_check_rom(rom)) + if (verdict) break; } @@ -258,12 +269,13 @@ static ssize_t w1_therm_read(struct device *device, c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n", crc, (verdict) ? "YES" : "NO"); if (verdict) - memcpy(sl->rom, rom, sizeof(sl->rom)); + memcpy(sl->family_data, rom, sizeof(rom)); else - dev_warn(device, "18S20 doesn't respond to CONVERT_TEMP.\n"); + dev_warn(device, "Read failed CRC check\n"); for (i = 0; i < 9; ++i) - c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]); + c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", + ((u8 *)sl->family_data)[i]); c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n", w1_convert_temp(rom, sl->family->fid)); |
