xref: /openbmc/linux/drivers/misc/tsl2550.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
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