174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
26a9bccedSJean Delvare /*
36a9bccedSJean Delvare * tsl2550.c - Linux kernel modules for ambient light sensor
46a9bccedSJean Delvare *
56a9bccedSJean Delvare * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
66a9bccedSJean Delvare * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
76a9bccedSJean Delvare */
86a9bccedSJean Delvare
96a9bccedSJean Delvare #include <linux/module.h>
106a9bccedSJean Delvare #include <linux/slab.h>
116a9bccedSJean Delvare #include <linux/i2c.h>
126a9bccedSJean Delvare #include <linux/mutex.h>
136a9bccedSJean Delvare
146a9bccedSJean Delvare #define TSL2550_DRV_NAME "tsl2550"
156a9bccedSJean Delvare #define DRIVER_VERSION "1.2"
166a9bccedSJean Delvare
176a9bccedSJean Delvare /*
186a9bccedSJean Delvare * Defines
196a9bccedSJean Delvare */
206a9bccedSJean Delvare
216a9bccedSJean Delvare #define TSL2550_POWER_DOWN 0x00
226a9bccedSJean Delvare #define TSL2550_POWER_UP 0x03
236a9bccedSJean Delvare #define TSL2550_STANDARD_RANGE 0x18
246a9bccedSJean Delvare #define TSL2550_EXTENDED_RANGE 0x1d
256a9bccedSJean Delvare #define TSL2550_READ_ADC0 0x43
266a9bccedSJean Delvare #define TSL2550_READ_ADC1 0x83
276a9bccedSJean Delvare
286a9bccedSJean Delvare /*
296a9bccedSJean Delvare * Structs
306a9bccedSJean Delvare */
316a9bccedSJean Delvare
326a9bccedSJean Delvare struct tsl2550_data {
336a9bccedSJean Delvare struct i2c_client *client;
346a9bccedSJean Delvare struct mutex update_lock;
356a9bccedSJean Delvare
366a9bccedSJean Delvare unsigned int power_state:1;
376a9bccedSJean Delvare unsigned int operating_mode:1;
386a9bccedSJean Delvare };
396a9bccedSJean Delvare
406a9bccedSJean Delvare /*
416a9bccedSJean Delvare * Global data
426a9bccedSJean Delvare */
436a9bccedSJean Delvare
446a9bccedSJean Delvare static const u8 TSL2550_MODE_RANGE[2] = {
456a9bccedSJean Delvare TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
466a9bccedSJean Delvare };
476a9bccedSJean Delvare
486a9bccedSJean Delvare /*
496a9bccedSJean Delvare * Management functions
506a9bccedSJean Delvare */
516a9bccedSJean Delvare
tsl2550_set_operating_mode(struct i2c_client * client,int mode)526a9bccedSJean Delvare static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
536a9bccedSJean Delvare {
546a9bccedSJean Delvare struct tsl2550_data *data = i2c_get_clientdata(client);
556a9bccedSJean Delvare
566a9bccedSJean Delvare int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
576a9bccedSJean Delvare
586a9bccedSJean Delvare data->operating_mode = mode;
596a9bccedSJean Delvare
606a9bccedSJean Delvare return ret;
616a9bccedSJean Delvare }
626a9bccedSJean Delvare
tsl2550_set_power_state(struct i2c_client * client,int state)636a9bccedSJean Delvare static int tsl2550_set_power_state(struct i2c_client *client, int state)
646a9bccedSJean Delvare {
656a9bccedSJean Delvare struct tsl2550_data *data = i2c_get_clientdata(client);
666a9bccedSJean Delvare int ret;
676a9bccedSJean Delvare
686a9bccedSJean Delvare if (state == 0)
696a9bccedSJean Delvare ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
706a9bccedSJean Delvare else {
716a9bccedSJean Delvare ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
726a9bccedSJean Delvare
736a9bccedSJean Delvare /* On power up we should reset operating mode also... */
746a9bccedSJean Delvare tsl2550_set_operating_mode(client, data->operating_mode);
756a9bccedSJean Delvare }
766a9bccedSJean Delvare
776a9bccedSJean Delvare data->power_state = state;
786a9bccedSJean Delvare
796a9bccedSJean Delvare return ret;
806a9bccedSJean Delvare }
816a9bccedSJean Delvare
tsl2550_get_adc_value(struct i2c_client * client,u8 cmd)826a9bccedSJean Delvare static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
836a9bccedSJean Delvare {
846a9bccedSJean Delvare int ret;
856a9bccedSJean Delvare
866a9bccedSJean Delvare ret = i2c_smbus_read_byte_data(client, cmd);
876a9bccedSJean Delvare if (ret < 0)
886a9bccedSJean Delvare return ret;
896a9bccedSJean Delvare if (!(ret & 0x80))
906a9bccedSJean Delvare return -EAGAIN;
916a9bccedSJean Delvare return ret & 0x7f; /* remove the "valid" bit */
926a9bccedSJean Delvare }
936a9bccedSJean Delvare
946a9bccedSJean Delvare /*
956a9bccedSJean Delvare * LUX calculation
966a9bccedSJean Delvare */
976a9bccedSJean Delvare
986a9bccedSJean Delvare #define TSL2550_MAX_LUX 1846
996a9bccedSJean Delvare
1006a9bccedSJean Delvare static const u8 ratio_lut[] = {
1016a9bccedSJean Delvare 100, 100, 100, 100, 100, 100, 100, 100,
1026a9bccedSJean Delvare 100, 100, 100, 100, 100, 100, 99, 99,
1036a9bccedSJean Delvare 99, 99, 99, 99, 99, 99, 99, 99,
1046a9bccedSJean Delvare 99, 99, 99, 98, 98, 98, 98, 98,
1056a9bccedSJean Delvare 98, 98, 97, 97, 97, 97, 97, 96,
1066a9bccedSJean Delvare 96, 96, 96, 95, 95, 95, 94, 94,
1076a9bccedSJean Delvare 93, 93, 93, 92, 92, 91, 91, 90,
1086a9bccedSJean Delvare 89, 89, 88, 87, 87, 86, 85, 84,
1096a9bccedSJean Delvare 83, 82, 81, 80, 79, 78, 77, 75,
1106a9bccedSJean Delvare 74, 73, 71, 69, 68, 66, 64, 62,
1116a9bccedSJean Delvare 60, 58, 56, 54, 52, 49, 47, 44,
1126a9bccedSJean Delvare 42, 41, 40, 40, 39, 39, 38, 38,
1136a9bccedSJean Delvare 37, 37, 37, 36, 36, 36, 35, 35,
1146a9bccedSJean Delvare 35, 35, 34, 34, 34, 34, 33, 33,
1156a9bccedSJean Delvare 33, 33, 32, 32, 32, 32, 32, 31,
1166a9bccedSJean Delvare 31, 31, 31, 31, 30, 30, 30, 30,
1176a9bccedSJean Delvare 30,
1186a9bccedSJean Delvare };
1196a9bccedSJean Delvare
1206a9bccedSJean Delvare static const u16 count_lut[] = {
1216a9bccedSJean Delvare 0, 1, 2, 3, 4, 5, 6, 7,
1226a9bccedSJean Delvare 8, 9, 10, 11, 12, 13, 14, 15,
1236a9bccedSJean Delvare 16, 18, 20, 22, 24, 26, 28, 30,
1246a9bccedSJean Delvare 32, 34, 36, 38, 40, 42, 44, 46,
1256a9bccedSJean Delvare 49, 53, 57, 61, 65, 69, 73, 77,
1266a9bccedSJean Delvare 81, 85, 89, 93, 97, 101, 105, 109,
1276a9bccedSJean Delvare 115, 123, 131, 139, 147, 155, 163, 171,
1286a9bccedSJean Delvare 179, 187, 195, 203, 211, 219, 227, 235,
1296a9bccedSJean Delvare 247, 263, 279, 295, 311, 327, 343, 359,
1306a9bccedSJean Delvare 375, 391, 407, 423, 439, 455, 471, 487,
1316a9bccedSJean Delvare 511, 543, 575, 607, 639, 671, 703, 735,
1326a9bccedSJean Delvare 767, 799, 831, 863, 895, 927, 959, 991,
1336a9bccedSJean Delvare 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
1346a9bccedSJean Delvare 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
1356a9bccedSJean Delvare 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
1366a9bccedSJean Delvare 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
1376a9bccedSJean Delvare };
1386a9bccedSJean Delvare
1396a9bccedSJean Delvare /*
1406a9bccedSJean Delvare * This function is described into Taos TSL2550 Designer's Notebook
1416a9bccedSJean Delvare * pages 2, 3.
1426a9bccedSJean Delvare */
tsl2550_calculate_lux(u8 ch0,u8 ch1)1436a9bccedSJean Delvare static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
1446a9bccedSJean Delvare {
1456a9bccedSJean Delvare unsigned int lux;
1466a9bccedSJean Delvare
1476a9bccedSJean Delvare /* Look up count from channel values */
1486a9bccedSJean Delvare u16 c0 = count_lut[ch0];
1496a9bccedSJean Delvare u16 c1 = count_lut[ch1];
1506a9bccedSJean Delvare
151f896ee51SColin Ian King /* Avoid division by 0 and count 1 cannot be greater than count 0 */
152f896ee51SColin Ian King if (c1 <= c0)
153f896ee51SColin Ian King if (c0) {
1546a9bccedSJean Delvare /*
1556a9bccedSJean Delvare * Calculate ratio.
1566a9bccedSJean Delvare * Note: the "128" is a scaling factor
1576a9bccedSJean Delvare */
158f896ee51SColin Ian King u8 r = c1 * 128 / c0;
1596a9bccedSJean Delvare
1606a9bccedSJean Delvare /* Calculate LUX */
1616a9bccedSJean Delvare lux = ((c0 - c1) * ratio_lut[r]) / 256;
1626a9bccedSJean Delvare } else
1636a9bccedSJean Delvare lux = 0;
1646a9bccedSJean Delvare else
165ce054546SMatt Ranostay return 0;
1666a9bccedSJean Delvare
1676a9bccedSJean Delvare /* LUX range check */
1686a9bccedSJean Delvare return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
1696a9bccedSJean Delvare }
1706a9bccedSJean Delvare
1716a9bccedSJean Delvare /*
1726a9bccedSJean Delvare * SysFS support
1736a9bccedSJean Delvare */
1746a9bccedSJean Delvare
tsl2550_show_power_state(struct device * dev,struct device_attribute * attr,char * buf)1756a9bccedSJean Delvare static ssize_t tsl2550_show_power_state(struct device *dev,
1766a9bccedSJean Delvare struct device_attribute *attr, char *buf)
1776a9bccedSJean Delvare {
1786a9bccedSJean Delvare struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
1796a9bccedSJean Delvare
1806a9bccedSJean Delvare return sprintf(buf, "%u\n", data->power_state);
1816a9bccedSJean Delvare }
1826a9bccedSJean Delvare
tsl2550_store_power_state(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1836a9bccedSJean Delvare static ssize_t tsl2550_store_power_state(struct device *dev,
1846a9bccedSJean Delvare struct device_attribute *attr, const char *buf, size_t count)
1856a9bccedSJean Delvare {
1866a9bccedSJean Delvare struct i2c_client *client = to_i2c_client(dev);
1876a9bccedSJean Delvare struct tsl2550_data *data = i2c_get_clientdata(client);
1886a9bccedSJean Delvare unsigned long val = simple_strtoul(buf, NULL, 10);
1896a9bccedSJean Delvare int ret;
1906a9bccedSJean Delvare
191ae8a35aeSChen Gang if (val > 1)
1926a9bccedSJean Delvare return -EINVAL;
1936a9bccedSJean Delvare
1946a9bccedSJean Delvare mutex_lock(&data->update_lock);
1956a9bccedSJean Delvare ret = tsl2550_set_power_state(client, val);
1966a9bccedSJean Delvare mutex_unlock(&data->update_lock);
1976a9bccedSJean Delvare
1986a9bccedSJean Delvare if (ret < 0)
1996a9bccedSJean Delvare return ret;
2006a9bccedSJean Delvare
2016a9bccedSJean Delvare return count;
2026a9bccedSJean Delvare }
2036a9bccedSJean Delvare
2046a9bccedSJean Delvare static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
2056a9bccedSJean Delvare tsl2550_show_power_state, tsl2550_store_power_state);
2066a9bccedSJean Delvare
tsl2550_show_operating_mode(struct device * dev,struct device_attribute * attr,char * buf)2076a9bccedSJean Delvare static ssize_t tsl2550_show_operating_mode(struct device *dev,
2086a9bccedSJean Delvare struct device_attribute *attr, char *buf)
2096a9bccedSJean Delvare {
2106a9bccedSJean Delvare struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
2116a9bccedSJean Delvare
2126a9bccedSJean Delvare return sprintf(buf, "%u\n", data->operating_mode);
2136a9bccedSJean Delvare }
2146a9bccedSJean Delvare
tsl2550_store_operating_mode(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)2156a9bccedSJean Delvare static ssize_t tsl2550_store_operating_mode(struct device *dev,
2166a9bccedSJean Delvare struct device_attribute *attr, const char *buf, size_t count)
2176a9bccedSJean Delvare {
2186a9bccedSJean Delvare struct i2c_client *client = to_i2c_client(dev);
2196a9bccedSJean Delvare struct tsl2550_data *data = i2c_get_clientdata(client);
2206a9bccedSJean Delvare unsigned long val = simple_strtoul(buf, NULL, 10);
2216a9bccedSJean Delvare int ret;
2226a9bccedSJean Delvare
223ae8a35aeSChen Gang if (val > 1)
2246a9bccedSJean Delvare return -EINVAL;
2256a9bccedSJean Delvare
2266a9bccedSJean Delvare if (data->power_state == 0)
2276a9bccedSJean Delvare return -EBUSY;
2286a9bccedSJean Delvare
2296a9bccedSJean Delvare mutex_lock(&data->update_lock);
2306a9bccedSJean Delvare ret = tsl2550_set_operating_mode(client, val);
2316a9bccedSJean Delvare mutex_unlock(&data->update_lock);
2326a9bccedSJean Delvare
2336a9bccedSJean Delvare if (ret < 0)
2346a9bccedSJean Delvare return ret;
2356a9bccedSJean Delvare
2366a9bccedSJean Delvare return count;
2376a9bccedSJean Delvare }
2386a9bccedSJean Delvare
2396a9bccedSJean Delvare static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
2406a9bccedSJean Delvare tsl2550_show_operating_mode, tsl2550_store_operating_mode);
2416a9bccedSJean Delvare
__tsl2550_show_lux(struct i2c_client * client,char * buf)2426a9bccedSJean Delvare static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
2436a9bccedSJean Delvare {
2446a9bccedSJean Delvare struct tsl2550_data *data = i2c_get_clientdata(client);
2456a9bccedSJean Delvare u8 ch0, ch1;
2466a9bccedSJean Delvare int ret;
2476a9bccedSJean Delvare
2486a9bccedSJean Delvare ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
2496a9bccedSJean Delvare if (ret < 0)
2506a9bccedSJean Delvare return ret;
2516a9bccedSJean Delvare ch0 = ret;
2526a9bccedSJean Delvare
2536a9bccedSJean Delvare ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
2546a9bccedSJean Delvare if (ret < 0)
2556a9bccedSJean Delvare return ret;
2566a9bccedSJean Delvare ch1 = ret;
2576a9bccedSJean Delvare
2586a9bccedSJean Delvare /* Do the job */
2596a9bccedSJean Delvare ret = tsl2550_calculate_lux(ch0, ch1);
2606a9bccedSJean Delvare if (ret < 0)
2616a9bccedSJean Delvare return ret;
2626a9bccedSJean Delvare if (data->operating_mode == 1)
2636a9bccedSJean Delvare ret *= 5;
2646a9bccedSJean Delvare
2656a9bccedSJean Delvare return sprintf(buf, "%d\n", ret);
2666a9bccedSJean Delvare }
2676a9bccedSJean Delvare
tsl2550_show_lux1_input(struct device * dev,struct device_attribute * attr,char * buf)2686a9bccedSJean Delvare static ssize_t tsl2550_show_lux1_input(struct device *dev,
2696a9bccedSJean Delvare struct device_attribute *attr, char *buf)
2706a9bccedSJean Delvare {
2716a9bccedSJean Delvare struct i2c_client *client = to_i2c_client(dev);
2726a9bccedSJean Delvare struct tsl2550_data *data = i2c_get_clientdata(client);
2736a9bccedSJean Delvare int ret;
2746a9bccedSJean Delvare
2756a9bccedSJean Delvare /* No LUX data if not operational */
2766a9bccedSJean Delvare if (!data->power_state)
2776a9bccedSJean Delvare return -EBUSY;
2786a9bccedSJean Delvare
2796a9bccedSJean Delvare mutex_lock(&data->update_lock);
2806a9bccedSJean Delvare ret = __tsl2550_show_lux(client, buf);
2816a9bccedSJean Delvare mutex_unlock(&data->update_lock);
2826a9bccedSJean Delvare
2836a9bccedSJean Delvare return ret;
2846a9bccedSJean Delvare }
2856a9bccedSJean Delvare
2866a9bccedSJean Delvare static DEVICE_ATTR(lux1_input, S_IRUGO,
2876a9bccedSJean Delvare tsl2550_show_lux1_input, NULL);
2886a9bccedSJean Delvare
2896a9bccedSJean Delvare static struct attribute *tsl2550_attributes[] = {
2906a9bccedSJean Delvare &dev_attr_power_state.attr,
2916a9bccedSJean Delvare &dev_attr_operating_mode.attr,
2926a9bccedSJean Delvare &dev_attr_lux1_input.attr,
2936a9bccedSJean Delvare NULL
2946a9bccedSJean Delvare };
2956a9bccedSJean Delvare
2966a9bccedSJean Delvare static const struct attribute_group tsl2550_attr_group = {
2976a9bccedSJean Delvare .attrs = tsl2550_attributes,
2986a9bccedSJean Delvare };
2996a9bccedSJean Delvare
3006a9bccedSJean Delvare /*
3016a9bccedSJean Delvare * Initialization function
3026a9bccedSJean Delvare */
3036a9bccedSJean Delvare
tsl2550_init_client(struct i2c_client * client)3046a9bccedSJean Delvare static int tsl2550_init_client(struct i2c_client *client)
3056a9bccedSJean Delvare {
3066a9bccedSJean Delvare struct tsl2550_data *data = i2c_get_clientdata(client);
3076a9bccedSJean Delvare int err;
3086a9bccedSJean Delvare
3096a9bccedSJean Delvare /*
3106a9bccedSJean Delvare * Probe the chip. To do so we try to power up the device and then to
3116a9bccedSJean Delvare * read back the 0x03 code
3126a9bccedSJean Delvare */
3136a9bccedSJean Delvare err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
3146a9bccedSJean Delvare if (err < 0)
3156a9bccedSJean Delvare return err;
3166a9bccedSJean Delvare if (err != TSL2550_POWER_UP)
3176a9bccedSJean Delvare return -ENODEV;
3186a9bccedSJean Delvare data->power_state = 1;
3196a9bccedSJean Delvare
3206a9bccedSJean Delvare /* Set the default operating mode */
3216a9bccedSJean Delvare err = i2c_smbus_write_byte(client,
3226a9bccedSJean Delvare TSL2550_MODE_RANGE[data->operating_mode]);
3236a9bccedSJean Delvare if (err < 0)
3246a9bccedSJean Delvare return err;
3256a9bccedSJean Delvare
3266a9bccedSJean Delvare return 0;
3276a9bccedSJean Delvare }
3286a9bccedSJean Delvare
3296a9bccedSJean Delvare /*
3306a9bccedSJean Delvare * I2C init/probing/exit functions
3316a9bccedSJean Delvare */
3326a9bccedSJean Delvare
3336a9bccedSJean Delvare static struct i2c_driver tsl2550_driver;
tsl2550_probe(struct i2c_client * client)3348427bd8bSUwe Kleine-König static int tsl2550_probe(struct i2c_client *client)
3356a9bccedSJean Delvare {
3363cc2deccSWolfram Sang struct i2c_adapter *adapter = client->adapter;
3376a9bccedSJean Delvare struct tsl2550_data *data;
3386a9bccedSJean Delvare int *opmode, err = 0;
3396a9bccedSJean Delvare
3406a9bccedSJean Delvare if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
3416a9bccedSJean Delvare | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
3426a9bccedSJean Delvare err = -EIO;
3436a9bccedSJean Delvare goto exit;
3446a9bccedSJean Delvare }
3456a9bccedSJean Delvare
3466a9bccedSJean Delvare data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
3476a9bccedSJean Delvare if (!data) {
3486a9bccedSJean Delvare err = -ENOMEM;
3496a9bccedSJean Delvare goto exit;
3506a9bccedSJean Delvare }
3516a9bccedSJean Delvare data->client = client;
3526a9bccedSJean Delvare i2c_set_clientdata(client, data);
3536a9bccedSJean Delvare
3546a9bccedSJean Delvare /* Check platform data */
3556a9bccedSJean Delvare opmode = client->dev.platform_data;
3566a9bccedSJean Delvare if (opmode) {
3576a9bccedSJean Delvare if (*opmode < 0 || *opmode > 1) {
3586a9bccedSJean Delvare dev_err(&client->dev, "invalid operating_mode (%d)\n",
3596a9bccedSJean Delvare *opmode);
3606a9bccedSJean Delvare err = -EINVAL;
3616a9bccedSJean Delvare goto exit_kfree;
3626a9bccedSJean Delvare }
3636a9bccedSJean Delvare data->operating_mode = *opmode;
3646a9bccedSJean Delvare } else
3656a9bccedSJean Delvare data->operating_mode = 0; /* default mode is standard */
3666a9bccedSJean Delvare dev_info(&client->dev, "%s operating mode\n",
3676a9bccedSJean Delvare data->operating_mode ? "extended" : "standard");
3686a9bccedSJean Delvare
3696a9bccedSJean Delvare mutex_init(&data->update_lock);
3706a9bccedSJean Delvare
3716a9bccedSJean Delvare /* Initialize the TSL2550 chip */
3726a9bccedSJean Delvare err = tsl2550_init_client(client);
3736a9bccedSJean Delvare if (err)
3746a9bccedSJean Delvare goto exit_kfree;
3756a9bccedSJean Delvare
3766a9bccedSJean Delvare /* Register sysfs hooks */
3776a9bccedSJean Delvare err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
3786a9bccedSJean Delvare if (err)
3796a9bccedSJean Delvare goto exit_kfree;
3806a9bccedSJean Delvare
3816a9bccedSJean Delvare dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
3826a9bccedSJean Delvare
3836a9bccedSJean Delvare return 0;
3846a9bccedSJean Delvare
3856a9bccedSJean Delvare exit_kfree:
3866a9bccedSJean Delvare kfree(data);
3876a9bccedSJean Delvare exit:
3886a9bccedSJean Delvare return err;
3896a9bccedSJean Delvare }
3906a9bccedSJean Delvare
tsl2550_remove(struct i2c_client * client)391ed5c2f5fSUwe Kleine-König static void tsl2550_remove(struct i2c_client *client)
3926a9bccedSJean Delvare {
3936a9bccedSJean Delvare sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
3946a9bccedSJean Delvare
3956a9bccedSJean Delvare /* Power down the device */
3966a9bccedSJean Delvare tsl2550_set_power_state(client, 0);
3976a9bccedSJean Delvare
3986a9bccedSJean Delvare kfree(i2c_get_clientdata(client));
3996a9bccedSJean Delvare }
4006a9bccedSJean Delvare
401a7761027SLars-Peter Clausen #ifdef CONFIG_PM_SLEEP
4026a9bccedSJean Delvare
tsl2550_suspend(struct device * dev)403a7761027SLars-Peter Clausen static int tsl2550_suspend(struct device *dev)
4046a9bccedSJean Delvare {
405a7761027SLars-Peter Clausen return tsl2550_set_power_state(to_i2c_client(dev), 0);
4066a9bccedSJean Delvare }
4076a9bccedSJean Delvare
tsl2550_resume(struct device * dev)408a7761027SLars-Peter Clausen static int tsl2550_resume(struct device *dev)
4096a9bccedSJean Delvare {
410a7761027SLars-Peter Clausen return tsl2550_set_power_state(to_i2c_client(dev), 1);
4116a9bccedSJean Delvare }
4126a9bccedSJean Delvare
413a7761027SLars-Peter Clausen static SIMPLE_DEV_PM_OPS(tsl2550_pm_ops, tsl2550_suspend, tsl2550_resume);
414a7761027SLars-Peter Clausen #define TSL2550_PM_OPS (&tsl2550_pm_ops)
415a7761027SLars-Peter Clausen
4166a9bccedSJean Delvare #else
4176a9bccedSJean Delvare
418a7761027SLars-Peter Clausen #define TSL2550_PM_OPS NULL
4196a9bccedSJean Delvare
420a7761027SLars-Peter Clausen #endif /* CONFIG_PM_SLEEP */
4216a9bccedSJean Delvare
4226a9bccedSJean Delvare static const struct i2c_device_id tsl2550_id[] = {
4236a9bccedSJean Delvare { "tsl2550", 0 },
4246a9bccedSJean Delvare { }
4256a9bccedSJean Delvare };
4266a9bccedSJean Delvare MODULE_DEVICE_TABLE(i2c, tsl2550_id);
4276a9bccedSJean Delvare
428d2ce8d6fSJavier Martinez Canillas static const struct of_device_id tsl2550_of_match[] = {
429d2ce8d6fSJavier Martinez Canillas { .compatible = "taos,tsl2550" },
430d2ce8d6fSJavier Martinez Canillas { }
431d2ce8d6fSJavier Martinez Canillas };
432d2ce8d6fSJavier Martinez Canillas MODULE_DEVICE_TABLE(of, tsl2550_of_match);
433d2ce8d6fSJavier Martinez Canillas
4346a9bccedSJean Delvare static struct i2c_driver tsl2550_driver = {
4356a9bccedSJean Delvare .driver = {
4366a9bccedSJean Delvare .name = TSL2550_DRV_NAME,
437d2ce8d6fSJavier Martinez Canillas .of_match_table = tsl2550_of_match,
438a7761027SLars-Peter Clausen .pm = TSL2550_PM_OPS,
4396a9bccedSJean Delvare },
440*f050bb8fSUwe Kleine-König .probe = tsl2550_probe,
4412d6bed9cSBill Pemberton .remove = tsl2550_remove,
4426a9bccedSJean Delvare .id_table = tsl2550_id,
4436a9bccedSJean Delvare };
4446a9bccedSJean Delvare
445a64fe2edSAxel Lin module_i2c_driver(tsl2550_driver);
4466a9bccedSJean Delvare
4476a9bccedSJean Delvare MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
4486a9bccedSJean Delvare MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
4496a9bccedSJean Delvare MODULE_LICENSE("GPL");
4506a9bccedSJean Delvare MODULE_VERSION(DRIVER_VERSION);
451