Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  tsl2550.c - Linux kernel modules for ambient light sensor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define TSL2550_DRV_NAME	"tsl2550"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define DRIVER_VERSION		"1.2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * Defines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define TSL2550_POWER_DOWN		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define TSL2550_POWER_UP		0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define TSL2550_STANDARD_RANGE		0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define TSL2550_EXTENDED_RANGE		0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define TSL2550_READ_ADC0		0x43
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define TSL2550_READ_ADC1		0x83
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * Structs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) struct tsl2550_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	struct mutex update_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	unsigned int power_state:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	unsigned int operating_mode:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * Global data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static const u8 TSL2550_MODE_RANGE[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * Management functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct tsl2550_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	data->operating_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) static int tsl2550_set_power_state(struct i2c_client *client, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct tsl2550_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	if (state == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		/* On power up we should reset operating mode also... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		tsl2550_set_operating_mode(client, data->operating_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	data->power_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	ret = i2c_smbus_read_byte_data(client, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	if (!(ret & 0x80))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return ret & 0x7f;	/* remove the "valid" bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * LUX calculation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #define	TSL2550_MAX_LUX		1846
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static const u8 ratio_lut[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	100, 100, 100, 100, 100, 100, 100, 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	100, 100, 100, 100, 100, 100, 99, 99,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	99, 99, 99, 99, 99, 99, 99, 99,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	99, 99, 99, 98, 98, 98, 98, 98,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	98, 98, 97, 97, 97, 97, 97, 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	96, 96, 96, 95, 95, 95, 94, 94,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	93, 93, 93, 92, 92, 91, 91, 90,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	89, 89, 88, 87, 87, 86, 85, 84,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	83, 82, 81, 80, 79, 78, 77, 75,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	74, 73, 71, 69, 68, 66, 64, 62,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	60, 58, 56, 54, 52, 49, 47, 44,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	42, 41, 40, 40, 39, 39, 38, 38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	37, 37, 37, 36, 36, 36, 35, 35,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	35, 35, 34, 34, 34, 34, 33, 33,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	33, 33, 32, 32, 32, 32, 32, 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	31, 31, 31, 31, 30, 30, 30, 30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static const u16 count_lut[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	0, 1, 2, 3, 4, 5, 6, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	8, 9, 10, 11, 12, 13, 14, 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	16, 18, 20, 22, 24, 26, 28, 30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	32, 34, 36, 38, 40, 42, 44, 46,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	49, 53, 57, 61, 65, 69, 73, 77,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	81, 85, 89, 93, 97, 101, 105, 109,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	115, 123, 131, 139, 147, 155, 163, 171,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	179, 187, 195, 203, 211, 219, 227, 235,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	247, 263, 279, 295, 311, 327, 343, 359,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	375, 391, 407, 423, 439, 455, 471, 487,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	511, 543, 575, 607, 639, 671, 703, 735,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	767, 799, 831, 863, 895, 927, 959, 991,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * This function is described into Taos TSL2550 Designer's Notebook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * pages 2, 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	unsigned int lux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	/* Look up count from channel values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	u16 c0 = count_lut[ch0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	u16 c1 = count_lut[ch1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	/* Avoid division by 0 and count 1 cannot be greater than count 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (c1 <= c0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		if (c0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			 * Calculate ratio.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			 * Note: the "128" is a scaling factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			u8 r = c1 * 128 / c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			/* Calculate LUX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			lux = ((c0 - c1) * ratio_lut[r]) / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			lux = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	/* LUX range check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  * SysFS support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static ssize_t tsl2550_show_power_state(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	return sprintf(buf, "%u\n", data->power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static ssize_t tsl2550_store_power_state(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	struct tsl2550_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	unsigned long val = simple_strtoul(buf, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	if (val > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	ret = tsl2550_set_power_state(client, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		   tsl2550_show_power_state, tsl2550_store_power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static ssize_t tsl2550_show_operating_mode(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	return sprintf(buf, "%u\n", data->operating_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static ssize_t tsl2550_store_operating_mode(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	struct tsl2550_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	unsigned long val = simple_strtoul(buf, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	if (val > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	if (data->power_state == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	ret = tsl2550_set_operating_mode(client, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		   tsl2550_show_operating_mode, tsl2550_store_operating_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	struct tsl2550_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	u8 ch0, ch1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	ch0 = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	ch1 = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	/* Do the job */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	ret = tsl2550_calculate_lux(ch0, ch1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	if (data->operating_mode == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		ret *= 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	return sprintf(buf, "%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static ssize_t tsl2550_show_lux1_input(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	struct tsl2550_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	/* No LUX data if not operational */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (!data->power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	ret = __tsl2550_show_lux(client, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static DEVICE_ATTR(lux1_input, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		   tsl2550_show_lux1_input, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static struct attribute *tsl2550_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	&dev_attr_power_state.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	&dev_attr_operating_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	&dev_attr_lux1_input.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static const struct attribute_group tsl2550_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	.attrs = tsl2550_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  * Initialization function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static int tsl2550_init_client(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	struct tsl2550_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	 * Probe the chip. To do so we try to power up the device and then to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	 * read back the 0x03 code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	if (err != TSL2550_POWER_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	data->power_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	/* Set the default operating mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	err = i2c_smbus_write_byte(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 				   TSL2550_MODE_RANGE[data->operating_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)  * I2C init/probing/exit functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static struct i2c_driver tsl2550_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static int tsl2550_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 				   const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	struct tsl2550_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	int *opmode, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 					    | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	i2c_set_clientdata(client, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	/* Check platform data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	opmode = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	if (opmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		if (*opmode < 0 || *opmode > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			dev_err(&client->dev, "invalid operating_mode (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 					*opmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 			goto exit_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		data->operating_mode = *opmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		data->operating_mode = 0;	/* default mode is standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	dev_info(&client->dev, "%s operating mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 			data->operating_mode ? "extended" : "standard");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	/* Initialize the TSL2550 chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	err = tsl2550_init_client(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		goto exit_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	/* Register sysfs hooks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		goto exit_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) exit_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static int tsl2550_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	/* Power down the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	tsl2550_set_power_state(client, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	kfree(i2c_get_clientdata(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static int tsl2550_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	return tsl2550_set_power_state(to_i2c_client(dev), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static int tsl2550_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	return tsl2550_set_power_state(to_i2c_client(dev), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static SIMPLE_DEV_PM_OPS(tsl2550_pm_ops, tsl2550_suspend, tsl2550_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) #define TSL2550_PM_OPS (&tsl2550_pm_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) #define TSL2550_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static const struct i2c_device_id tsl2550_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	{ "tsl2550", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) MODULE_DEVICE_TABLE(i2c, tsl2550_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static const struct of_device_id tsl2550_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	{ .compatible = "taos,tsl2550" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) MODULE_DEVICE_TABLE(of, tsl2550_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static struct i2c_driver tsl2550_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		.name	= TSL2550_DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		.of_match_table = tsl2550_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		.pm	= TSL2550_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	.probe	= tsl2550_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	.remove	= tsl2550_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	.id_table = tsl2550_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) module_i2c_driver(tsl2550_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) MODULE_VERSION(DRIVER_VERSION);