1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * tsl2550.c - Linux kernel modules for ambient light sensor
5 * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
6 * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/i2c.h>
12 #include <linux/mutex.h>
14 #define TSL2550_DRV_NAME "tsl2550"
15 #define DRIVER_VERSION "1.2"
21 #define TSL2550_POWER_DOWN 0x00
22 #define TSL2550_POWER_UP 0x03
23 #define TSL2550_STANDARD_RANGE 0x18
24 #define TSL2550_EXTENDED_RANGE 0x1d
25 #define TSL2550_READ_ADC0 0x43
26 #define TSL2550_READ_ADC1 0x83
33 struct i2c_client
*client
;
34 struct mutex update_lock
;
36 unsigned int power_state
:1;
37 unsigned int operating_mode
:1;
44 static const u8 TSL2550_MODE_RANGE
[2] = {
45 TSL2550_STANDARD_RANGE
, TSL2550_EXTENDED_RANGE
,
49 * Management functions
52 static int tsl2550_set_operating_mode(struct i2c_client
*client
, int mode
)
54 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
56 int ret
= i2c_smbus_write_byte(client
, TSL2550_MODE_RANGE
[mode
]);
58 data
->operating_mode
= mode
;
63 static int tsl2550_set_power_state(struct i2c_client
*client
, int state
)
65 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
69 ret
= i2c_smbus_write_byte(client
, TSL2550_POWER_DOWN
);
71 ret
= i2c_smbus_write_byte(client
, TSL2550_POWER_UP
);
73 /* On power up we should reset operating mode also... */
74 tsl2550_set_operating_mode(client
, data
->operating_mode
);
77 data
->power_state
= state
;
82 static int tsl2550_get_adc_value(struct i2c_client
*client
, u8 cmd
)
86 ret
= i2c_smbus_read_byte_data(client
, cmd
);
91 return ret
& 0x7f; /* remove the "valid" bit */
98 #define TSL2550_MAX_LUX 1846
100 static const u8 ratio_lut
[] = {
101 100, 100, 100, 100, 100, 100, 100, 100,
102 100, 100, 100, 100, 100, 100, 99, 99,
103 99, 99, 99, 99, 99, 99, 99, 99,
104 99, 99, 99, 98, 98, 98, 98, 98,
105 98, 98, 97, 97, 97, 97, 97, 96,
106 96, 96, 96, 95, 95, 95, 94, 94,
107 93, 93, 93, 92, 92, 91, 91, 90,
108 89, 89, 88, 87, 87, 86, 85, 84,
109 83, 82, 81, 80, 79, 78, 77, 75,
110 74, 73, 71, 69, 68, 66, 64, 62,
111 60, 58, 56, 54, 52, 49, 47, 44,
112 42, 41, 40, 40, 39, 39, 38, 38,
113 37, 37, 37, 36, 36, 36, 35, 35,
114 35, 35, 34, 34, 34, 34, 33, 33,
115 33, 33, 32, 32, 32, 32, 32, 31,
116 31, 31, 31, 31, 30, 30, 30, 30,
120 static const u16 count_lut
[] = {
121 0, 1, 2, 3, 4, 5, 6, 7,
122 8, 9, 10, 11, 12, 13, 14, 15,
123 16, 18, 20, 22, 24, 26, 28, 30,
124 32, 34, 36, 38, 40, 42, 44, 46,
125 49, 53, 57, 61, 65, 69, 73, 77,
126 81, 85, 89, 93, 97, 101, 105, 109,
127 115, 123, 131, 139, 147, 155, 163, 171,
128 179, 187, 195, 203, 211, 219, 227, 235,
129 247, 263, 279, 295, 311, 327, 343, 359,
130 375, 391, 407, 423, 439, 455, 471, 487,
131 511, 543, 575, 607, 639, 671, 703, 735,
132 767, 799, 831, 863, 895, 927, 959, 991,
133 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
134 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
135 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
136 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
140 * This function is described into Taos TSL2550 Designer's Notebook
143 static int tsl2550_calculate_lux(u8 ch0
, u8 ch1
)
147 /* Look up count from channel values */
148 u16 c0
= count_lut
[ch0
];
149 u16 c1
= count_lut
[ch1
];
151 /* Avoid division by 0 and count 1 cannot be greater than count 0 */
156 * Note: the "128" is a scaling factor
158 u8 r
= c1
* 128 / c0
;
161 lux
= ((c0
- c1
) * ratio_lut
[r
]) / 256;
167 /* LUX range check */
168 return lux
> TSL2550_MAX_LUX
? TSL2550_MAX_LUX
: lux
;
175 static ssize_t
tsl2550_show_power_state(struct device
*dev
,
176 struct device_attribute
*attr
, char *buf
)
178 struct tsl2550_data
*data
= i2c_get_clientdata(to_i2c_client(dev
));
180 return sprintf(buf
, "%u\n", data
->power_state
);
183 static ssize_t
tsl2550_store_power_state(struct device
*dev
,
184 struct device_attribute
*attr
, const char *buf
, size_t count
)
186 struct i2c_client
*client
= to_i2c_client(dev
);
187 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
188 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
194 mutex_lock(&data
->update_lock
);
195 ret
= tsl2550_set_power_state(client
, val
);
196 mutex_unlock(&data
->update_lock
);
204 static DEVICE_ATTR(power_state
, S_IWUSR
| S_IRUGO
,
205 tsl2550_show_power_state
, tsl2550_store_power_state
);
207 static ssize_t
tsl2550_show_operating_mode(struct device
*dev
,
208 struct device_attribute
*attr
, char *buf
)
210 struct tsl2550_data
*data
= i2c_get_clientdata(to_i2c_client(dev
));
212 return sprintf(buf
, "%u\n", data
->operating_mode
);
215 static ssize_t
tsl2550_store_operating_mode(struct device
*dev
,
216 struct device_attribute
*attr
, const char *buf
, size_t count
)
218 struct i2c_client
*client
= to_i2c_client(dev
);
219 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
220 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
226 if (data
->power_state
== 0)
229 mutex_lock(&data
->update_lock
);
230 ret
= tsl2550_set_operating_mode(client
, val
);
231 mutex_unlock(&data
->update_lock
);
239 static DEVICE_ATTR(operating_mode
, S_IWUSR
| S_IRUGO
,
240 tsl2550_show_operating_mode
, tsl2550_store_operating_mode
);
242 static ssize_t
__tsl2550_show_lux(struct i2c_client
*client
, char *buf
)
244 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
248 ret
= tsl2550_get_adc_value(client
, TSL2550_READ_ADC0
);
253 ret
= tsl2550_get_adc_value(client
, TSL2550_READ_ADC1
);
259 ret
= tsl2550_calculate_lux(ch0
, ch1
);
262 if (data
->operating_mode
== 1)
265 return sprintf(buf
, "%d\n", ret
);
268 static ssize_t
tsl2550_show_lux1_input(struct device
*dev
,
269 struct device_attribute
*attr
, char *buf
)
271 struct i2c_client
*client
= to_i2c_client(dev
);
272 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
275 /* No LUX data if not operational */
276 if (!data
->power_state
)
279 mutex_lock(&data
->update_lock
);
280 ret
= __tsl2550_show_lux(client
, buf
);
281 mutex_unlock(&data
->update_lock
);
286 static DEVICE_ATTR(lux1_input
, S_IRUGO
,
287 tsl2550_show_lux1_input
, NULL
);
289 static struct attribute
*tsl2550_attributes
[] = {
290 &dev_attr_power_state
.attr
,
291 &dev_attr_operating_mode
.attr
,
292 &dev_attr_lux1_input
.attr
,
296 static const struct attribute_group tsl2550_attr_group
= {
297 .attrs
= tsl2550_attributes
,
301 * Initialization function
304 static int tsl2550_init_client(struct i2c_client
*client
)
306 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
310 * Probe the chip. To do so we try to power up the device and then to
311 * read back the 0x03 code
313 err
= i2c_smbus_read_byte_data(client
, TSL2550_POWER_UP
);
316 if (err
!= TSL2550_POWER_UP
)
318 data
->power_state
= 1;
320 /* Set the default operating mode */
321 err
= i2c_smbus_write_byte(client
,
322 TSL2550_MODE_RANGE
[data
->operating_mode
]);
330 * I2C init/probing/exit functions
333 static struct i2c_driver tsl2550_driver
;
334 static int tsl2550_probe(struct i2c_client
*client
,
335 const struct i2c_device_id
*id
)
337 struct i2c_adapter
*adapter
= client
->adapter
;
338 struct tsl2550_data
*data
;
339 int *opmode
, err
= 0;
341 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_WRITE_BYTE
342 | I2C_FUNC_SMBUS_READ_BYTE_DATA
)) {
347 data
= kzalloc(sizeof(struct tsl2550_data
), GFP_KERNEL
);
352 data
->client
= client
;
353 i2c_set_clientdata(client
, data
);
355 /* Check platform data */
356 opmode
= client
->dev
.platform_data
;
358 if (*opmode
< 0 || *opmode
> 1) {
359 dev_err(&client
->dev
, "invalid operating_mode (%d)\n",
364 data
->operating_mode
= *opmode
;
366 data
->operating_mode
= 0; /* default mode is standard */
367 dev_info(&client
->dev
, "%s operating mode\n",
368 data
->operating_mode
? "extended" : "standard");
370 mutex_init(&data
->update_lock
);
372 /* Initialize the TSL2550 chip */
373 err
= tsl2550_init_client(client
);
377 /* Register sysfs hooks */
378 err
= sysfs_create_group(&client
->dev
.kobj
, &tsl2550_attr_group
);
382 dev_info(&client
->dev
, "support ver. %s enabled\n", DRIVER_VERSION
);
392 static int tsl2550_remove(struct i2c_client
*client
)
394 sysfs_remove_group(&client
->dev
.kobj
, &tsl2550_attr_group
);
396 /* Power down the device */
397 tsl2550_set_power_state(client
, 0);
399 kfree(i2c_get_clientdata(client
));
404 #ifdef CONFIG_PM_SLEEP
406 static int tsl2550_suspend(struct device
*dev
)
408 return tsl2550_set_power_state(to_i2c_client(dev
), 0);
411 static int tsl2550_resume(struct device
*dev
)
413 return tsl2550_set_power_state(to_i2c_client(dev
), 1);
416 static SIMPLE_DEV_PM_OPS(tsl2550_pm_ops
, tsl2550_suspend
, tsl2550_resume
);
417 #define TSL2550_PM_OPS (&tsl2550_pm_ops)
421 #define TSL2550_PM_OPS NULL
423 #endif /* CONFIG_PM_SLEEP */
425 static const struct i2c_device_id tsl2550_id
[] = {
429 MODULE_DEVICE_TABLE(i2c
, tsl2550_id
);
431 static const struct of_device_id tsl2550_of_match
[] = {
432 { .compatible
= "taos,tsl2550" },
435 MODULE_DEVICE_TABLE(of
, tsl2550_of_match
);
437 static struct i2c_driver tsl2550_driver
= {
439 .name
= TSL2550_DRV_NAME
,
440 .of_match_table
= tsl2550_of_match
,
441 .pm
= TSL2550_PM_OPS
,
443 .probe
= tsl2550_probe
,
444 .remove
= tsl2550_remove
,
445 .id_table
= tsl2550_id
,
448 module_i2c_driver(tsl2550_driver
);
450 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
451 MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
452 MODULE_LICENSE("GPL");
453 MODULE_VERSION(DRIVER_VERSION
);