Prev: tsl2550: Move form i2c/chips to als and update interfaces
Next: [PATCH] netdev: remove HAVE_ leftovers
From: Jonathan Cameron on 26 Jan 2010 13:50 Signed-off-by: Jonathan Cameron <jic23(a)cam.ac.uk> --- Simple changes to meet all of Jean's comments. Made formatting changes, removed the defined maximum lux value and separated out the crushing of drivers/i2c/chips. If Jean is happy with fixes I would propose taking this through the ALS tree. Attached is a full patch without git move detection. Documentation/ABI/testing/sysfs-class-als | 9 +++ drivers/als/Kconfig | 14 ++++ drivers/als/Makefile | 2 + drivers/{i2c/chips => als}/tsl2550.c | 101 +++++++++++++++++----------- drivers/i2c/Kconfig | 1 - drivers/i2c/Makefile | 2 +- drivers/i2c/chips/Kconfig | 10 --- drivers/i2c/chips/Makefile | 2 - 8 files changed, 87 insertions(+), 54 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-als b/Documentation/ABI/testing/sysfs-class-als index d3b33f3..732f449 100644 --- a/Documentation/ABI/testing/sysfs-class-als +++ b/Documentation/ABI/testing/sysfs-class-als @@ -7,3 +7,12 @@ Description: Current Ambient Light Illuminance reported by Unit: lux (lumens per square meter) RO +What: /sys/class/als/.../exposure_time[n] +Date: Dec. 2009 +KernelVersion: 2.6.32 +Contact: Jonathan Cameron <jic23(a)cam.ac.uk> +Description: Sensor exposure time. In some devices this + corresponds to the combined time needed to + to internally read several different sensors. + Unit: microseconds + RW diff --git a/drivers/als/Kconfig b/drivers/als/Kconfig index 200c52b..1564ffc 100644 --- a/drivers/als/Kconfig +++ b/drivers/als/Kconfig @@ -8,3 +8,17 @@ menuconfig ALS This framework provides a generic sysfs I/F for Ambient Light Sensor devices. If you want this support, you should say Y or M here. + +if ALS + +config ALS_TSL2550 + tristate "Taos TSL2550 ambient light sensor" + depends on EXPERIMENTAL && I2C + help + If you say yes here you get support for the Taos TSL2550 + ambient light sensor. + + This driver can also be built as a module. If so, the module + will be called tsl2550. + +endif #ALS diff --git a/drivers/als/Makefile b/drivers/als/Makefile index a527197..7be5631 100644 --- a/drivers/als/Makefile +++ b/drivers/als/Makefile @@ -3,3 +3,5 @@ # obj-$(CONFIG_ALS) += als_sys.o + +obj-$(CONFIG_ALS_TSL2550) += tsl2550.o \ No newline at end of file diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/als/tsl2550.c similarity index 81% rename from drivers/i2c/chips/tsl2550.c rename to drivers/als/tsl2550.c index a0702f3..8d5f2a1 100644 --- a/drivers/i2c/chips/tsl2550.c +++ b/drivers/als/tsl2550.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007 Rodolfo Giometti <giometti(a)linux.it> * Copyright (C) 2007 Eurotech S.p.A. <info(a)eurotech.it> + * Copyright (C) 2009 Jonathan Cameron <jic23(a)cam.ac.uk> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,9 +25,11 @@ #include <linux/slab.h> #include <linux/i2c.h> #include <linux/mutex.h> +#include <linux/err.h> +#include <linux/als_sys.h> #define TSL2550_DRV_NAME "tsl2550" -#define DRIVER_VERSION "1.2" +#define DRIVER_VERSION "2.0" /* * Defines @@ -44,11 +47,12 @@ */ struct tsl2550_data { + struct device *classdev; struct i2c_client *client; struct mutex update_lock; - unsigned int power_state : 1; - unsigned int operating_mode : 1; + unsigned int power_state:1; + unsigned int operating_mode:1; }; /* @@ -102,15 +106,16 @@ static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd) return ret; if (!(ret & 0x80)) return -EAGAIN; + if (ret == 0x7f) + return -ERANGE; return ret & 0x7f; /* remove the "valid" bit */ } /* - * LUX calculation + * LUX calculation - note the range is dependent on combination + * of infrared level and visible light levels. */ -#define TSL2550_MAX_LUX 1846 - static const u8 ratio_lut[] = { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 99, 99, @@ -180,8 +185,7 @@ static int tsl2550_calculate_lux(u8 ch0, u8 ch1) else return -EAGAIN; - /* LUX range check */ - return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux; + return lux; } /* @@ -191,7 +195,8 @@ static int tsl2550_calculate_lux(u8 ch0, u8 ch1) static ssize_t tsl2550_show_power_state(struct device *dev, struct device_attribute *attr, char *buf) { - struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev)); + struct i2c_client *client = to_i2c_client(dev->parent); + struct tsl2550_data *data = i2c_get_clientdata(client); return sprintf(buf, "%u\n", data->power_state); } @@ -199,12 +204,12 @@ static ssize_t tsl2550_show_power_state(struct device *dev, static ssize_t tsl2550_store_power_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); + struct i2c_client *client = to_i2c_client(dev->parent); struct tsl2550_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); - int ret; + unsigned long val; + int ret = strict_strtoul(buf, 10, &val); - if (val < 0 || val > 1) + if (val < 0 || val > 1 || ret) return -EINVAL; mutex_lock(&data->update_lock); @@ -220,40 +225,45 @@ static ssize_t tsl2550_store_power_state(struct device *dev, static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO, tsl2550_show_power_state, tsl2550_store_power_state); -static ssize_t tsl2550_show_operating_mode(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t tsl2550_show_exposure(struct device *dev, + struct device_attribute *attr, + char *buf) { - struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev)); - - return sprintf(buf, "%u\n", data->operating_mode); + struct i2c_client *client = to_i2c_client(dev->parent); + struct tsl2550_data *data = i2c_get_clientdata(client); + if (data->operating_mode) + return sprintf(buf, "160000\n"); + else + return sprintf(buf, "800000\n"); } -static ssize_t tsl2550_store_operating_mode(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) +static ssize_t tsl2550_store_exposure(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) { - struct i2c_client *client = to_i2c_client(dev); + struct i2c_client *client = to_i2c_client(dev->parent); struct tsl2550_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); - int ret; - - if (val < 0 || val > 1) - return -EINVAL; + unsigned long val; - if (data->power_state == 0) - return -EBUSY; + int ret = strict_strtoul(buf, 10, &val); + if (ret) + return -EINVAL; mutex_lock(&data->update_lock); - ret = tsl2550_set_operating_mode(client, val); + if (val >= 800000) + ret = tsl2550_set_operating_mode(client, 0); + else + ret = tsl2550_set_operating_mode(client, 1); mutex_unlock(&data->update_lock); - if (ret < 0) return ret; return count; } -static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO, - tsl2550_show_operating_mode, tsl2550_store_operating_mode); +static DEVICE_ATTR(exposure_time0, S_IWUSR | S_IRUGO, + tsl2550_show_exposure, tsl2550_store_exposure); static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) { @@ -284,7 +294,7 @@ static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) static ssize_t tsl2550_show_lux1_input(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); + struct i2c_client *client = to_i2c_client(dev->parent); struct tsl2550_data *data = i2c_get_clientdata(client); int ret; @@ -299,13 +309,13 @@ static ssize_t tsl2550_show_lux1_input(struct device *dev, return ret; } -static DEVICE_ATTR(lux1_input, S_IRUGO, +static DEVICE_ATTR(illuminance0, S_IRUGO, tsl2550_show_lux1_input, NULL); static struct attribute *tsl2550_attributes[] = { &dev_attr_power_state.attr, - &dev_attr_operating_mode.attr, - &dev_attr_lux1_input.attr, + &dev_attr_exposure_time0.attr, + &dev_attr_illuminance0.attr, NULL }; @@ -391,14 +401,22 @@ static int __devinit tsl2550_probe(struct i2c_client *client, goto exit_kfree; /* Register sysfs hooks */ - err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group); - if (err) + data->classdev = als_device_register(&client->dev); + if (IS_ERR(data->classdev)) { + err = PTR_ERR(data->classdev); goto exit_kfree; + } + + err = sysfs_create_group(&data->classdev->kobj, &tsl2550_attr_group); + if (err) + goto exit_unreg; dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION); return 0; +exit_unreg: + als_device_unregister(data->classdev); exit_kfree: kfree(data); exit: @@ -407,12 +425,15 @@ exit: static int __devexit tsl2550_remove(struct i2c_client *client) { - sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group); + struct tsl2550_data *data = i2c_get_clientdata(client); + + sysfs_remove_group(&data->classdev->kobj, &tsl2550_attr_group); + als_device_unregister(data->classdev); /* Power down the device */ tsl2550_set_power_state(client, 0); - kfree(i2c_get_clientdata(client)); + kfree(data); return 0; } diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 8d8a00e..5c33a71 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -63,7 +63,6 @@ config I2C_HELPER_AUTO source drivers/i2c/algos/Kconfig source drivers/i2c/busses/Kconfig -source drivers/i2c/chips/Kconfig config I2C_DEBUG_CORE bool "I2C Core debugging messages" diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index ba26e6c..ce5fd62 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o -obj-y += busses/ chips/ algos/ +obj-y += busses/ algos/ ifeq ($(CONFIG_I2C_DEBUG_CORE),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index ae4539d..c11f8d6 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -6,14 +6,4 @@ menu "Miscellaneous I2C Chip support" -config SENSORS_TSL2550 - tristate "Taos TSL2550 ambient light sensor" - depends on EXPERIMENTAL - help - If you say yes here you get support for the Taos TSL2550 - ambient light sensor. - - This driver can also be built as a module. If so, the module - will be called tsl2550. - endmenu diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index fe0af0f..ffde18d 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -10,8 +10,6 @@ # * I/O expander drivers go to drivers/gpio # -obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o - ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG endif -- 1.6.4.4 |