2 * tsl2550.c - Linux kernel modules for ambient light sensor
4 * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
5 * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/slab.h>
25 #include <linux/i2c.h>
26 #include <linux/mutex.h>
28 #define TSL2550_DRV_NAME "tsl2550"
29 #define DRIVER_VERSION "1.2"
35 #define TSL2550_POWER_DOWN 0x00
36 #define TSL2550_POWER_UP 0x03
37 #define TSL2550_STANDARD_RANGE 0x18
38 #define TSL2550_EXTENDED_RANGE 0x1d
39 #define TSL2550_READ_ADC0 0x43
40 #define TSL2550_READ_ADC1 0x83
47 struct i2c_client
*client
;
48 struct mutex update_lock
;
50 unsigned int power_state
: 1;
51 unsigned int operating_mode
: 1;
58 static const u8 TSL2550_MODE_RANGE
[2] = {
59 TSL2550_STANDARD_RANGE
, TSL2550_EXTENDED_RANGE
,
63 * Management functions
66 static int tsl2550_set_operating_mode(struct i2c_client
*client
, int mode
)
68 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
70 int ret
= i2c_smbus_write_byte(client
, TSL2550_MODE_RANGE
[mode
]);
72 data
->operating_mode
= mode
;
77 static int tsl2550_set_power_state(struct i2c_client
*client
, int state
)
79 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
83 ret
= i2c_smbus_write_byte(client
, TSL2550_POWER_DOWN
);
85 ret
= i2c_smbus_write_byte(client
, TSL2550_POWER_UP
);
87 /* On power up we should reset operating mode also... */
88 tsl2550_set_operating_mode(client
, data
->operating_mode
);
91 data
->power_state
= state
;
96 static int tsl2550_get_adc_value(struct i2c_client
*client
, u8 cmd
)
100 ret
= i2c_smbus_read_byte_data(client
, cmd
);
105 return ret
& 0x7f; /* remove the "valid" bit */
112 #define TSL2550_MAX_LUX 1846
114 static const u8 ratio_lut
[] = {
115 100, 100, 100, 100, 100, 100, 100, 100,
116 100, 100, 100, 100, 100, 100, 99, 99,
117 99, 99, 99, 99, 99, 99, 99, 99,
118 99, 99, 99, 98, 98, 98, 98, 98,
119 98, 98, 97, 97, 97, 97, 97, 96,
120 96, 96, 96, 95, 95, 95, 94, 94,
121 93, 93, 93, 92, 92, 91, 91, 90,
122 89, 89, 88, 87, 87, 86, 85, 84,
123 83, 82, 81, 80, 79, 78, 77, 75,
124 74, 73, 71, 69, 68, 66, 64, 62,
125 60, 58, 56, 54, 52, 49, 47, 44,
126 42, 41, 40, 40, 39, 39, 38, 38,
127 37, 37, 37, 36, 36, 36, 35, 35,
128 35, 35, 34, 34, 34, 34, 33, 33,
129 33, 33, 32, 32, 32, 32, 32, 31,
130 31, 31, 31, 31, 30, 30, 30, 30,
134 static const u16 count_lut
[] = {
135 0, 1, 2, 3, 4, 5, 6, 7,
136 8, 9, 10, 11, 12, 13, 14, 15,
137 16, 18, 20, 22, 24, 26, 28, 30,
138 32, 34, 36, 38, 40, 42, 44, 46,
139 49, 53, 57, 61, 65, 69, 73, 77,
140 81, 85, 89, 93, 97, 101, 105, 109,
141 115, 123, 131, 139, 147, 155, 163, 171,
142 179, 187, 195, 203, 211, 219, 227, 235,
143 247, 263, 279, 295, 311, 327, 343, 359,
144 375, 391, 407, 423, 439, 455, 471, 487,
145 511, 543, 575, 607, 639, 671, 703, 735,
146 767, 799, 831, 863, 895, 927, 959, 991,
147 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
148 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
149 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
150 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
154 * This function is described into Taos TSL2550 Designer's Notebook
157 static int tsl2550_calculate_lux(u8 ch0
, u8 ch1
)
161 /* Look up count from channel values */
162 u16 c0
= count_lut
[ch0
];
163 u16 c1
= count_lut
[ch1
];
167 * Note: the "128" is a scaling factor
171 /* Avoid division by 0 and count 1 cannot be greater than count 0 */
177 lux
= ((c0
- c1
) * ratio_lut
[r
]) / 256;
183 /* LUX range check */
184 return lux
> TSL2550_MAX_LUX
? TSL2550_MAX_LUX
: lux
;
191 static ssize_t
tsl2550_show_power_state(struct device
*dev
,
192 struct device_attribute
*attr
, char *buf
)
194 struct tsl2550_data
*data
= i2c_get_clientdata(to_i2c_client(dev
));
196 return sprintf(buf
, "%u\n", data
->power_state
);
199 static ssize_t
tsl2550_store_power_state(struct device
*dev
,
200 struct device_attribute
*attr
, const char *buf
, size_t count
)
202 struct i2c_client
*client
= to_i2c_client(dev
);
203 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
204 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
207 if (val
< 0 || val
> 1)
210 mutex_lock(&data
->update_lock
);
211 ret
= tsl2550_set_power_state(client
, val
);
212 mutex_unlock(&data
->update_lock
);
220 static DEVICE_ATTR(power_state
, S_IWUSR
| S_IRUGO
,
221 tsl2550_show_power_state
, tsl2550_store_power_state
);
223 static ssize_t
tsl2550_show_operating_mode(struct device
*dev
,
224 struct device_attribute
*attr
, char *buf
)
226 struct tsl2550_data
*data
= i2c_get_clientdata(to_i2c_client(dev
));
228 return sprintf(buf
, "%u\n", data
->operating_mode
);
231 static ssize_t
tsl2550_store_operating_mode(struct device
*dev
,
232 struct device_attribute
*attr
, const char *buf
, size_t count
)
234 struct i2c_client
*client
= to_i2c_client(dev
);
235 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
236 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
239 if (val
< 0 || val
> 1)
242 if (data
->power_state
== 0)
245 mutex_lock(&data
->update_lock
);
246 ret
= tsl2550_set_operating_mode(client
, val
);
247 mutex_unlock(&data
->update_lock
);
255 static DEVICE_ATTR(operating_mode
, S_IWUSR
| S_IRUGO
,
256 tsl2550_show_operating_mode
, tsl2550_store_operating_mode
);
258 static ssize_t
__tsl2550_show_lux(struct i2c_client
*client
, char *buf
)
263 ret
= tsl2550_get_adc_value(client
, TSL2550_READ_ADC0
);
268 ret
= tsl2550_get_adc_value(client
, TSL2550_READ_ADC1
);
274 ret
= tsl2550_calculate_lux(ch0
, ch1
);
278 return sprintf(buf
, "%d\n", ret
);
281 static ssize_t
tsl2550_show_lux1_input(struct device
*dev
,
282 struct device_attribute
*attr
, char *buf
)
284 struct i2c_client
*client
= to_i2c_client(dev
);
285 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
288 /* No LUX data if not operational */
289 if (!data
->power_state
)
292 mutex_lock(&data
->update_lock
);
293 ret
= __tsl2550_show_lux(client
, buf
);
294 mutex_unlock(&data
->update_lock
);
299 static DEVICE_ATTR(lux1_input
, S_IRUGO
,
300 tsl2550_show_lux1_input
, NULL
);
302 static struct attribute
*tsl2550_attributes
[] = {
303 &dev_attr_power_state
.attr
,
304 &dev_attr_operating_mode
.attr
,
305 &dev_attr_lux1_input
.attr
,
309 static const struct attribute_group tsl2550_attr_group
= {
310 .attrs
= tsl2550_attributes
,
314 * Initialization function
317 static int tsl2550_init_client(struct i2c_client
*client
)
319 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
323 * Probe the chip. To do so we try to power up the device and then to
324 * read back the 0x03 code
326 err
= i2c_smbus_read_byte_data(client
, TSL2550_POWER_UP
);
329 if (err
!= TSL2550_POWER_UP
)
331 data
->power_state
= 1;
333 /* Set the default operating mode */
334 err
= i2c_smbus_write_byte(client
,
335 TSL2550_MODE_RANGE
[data
->operating_mode
]);
343 * I2C init/probing/exit functions
346 static struct i2c_driver tsl2550_driver
;
347 static int __devinit
tsl2550_probe(struct i2c_client
*client
,
348 const struct i2c_device_id
*id
)
350 struct i2c_adapter
*adapter
= to_i2c_adapter(client
->dev
.parent
);
351 struct tsl2550_data
*data
;
352 int *opmode
, err
= 0;
354 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_WRITE_BYTE
355 | I2C_FUNC_SMBUS_READ_BYTE_DATA
)) {
360 data
= kzalloc(sizeof(struct tsl2550_data
), GFP_KERNEL
);
365 data
->client
= client
;
366 i2c_set_clientdata(client
, data
);
368 /* Check platform data */
369 opmode
= client
->dev
.platform_data
;
371 if (*opmode
< 0 || *opmode
> 1) {
372 dev_err(&client
->dev
, "invalid operating_mode (%d)\n",
377 data
->operating_mode
= *opmode
;
379 data
->operating_mode
= 0; /* default mode is standard */
380 dev_info(&client
->dev
, "%s operating mode\n",
381 data
->operating_mode
? "extended" : "standard");
383 mutex_init(&data
->update_lock
);
385 /* Initialize the TSL2550 chip */
386 err
= tsl2550_init_client(client
);
390 /* Register sysfs hooks */
391 err
= sysfs_create_group(&client
->dev
.kobj
, &tsl2550_attr_group
);
395 dev_info(&client
->dev
, "support ver. %s enabled\n", DRIVER_VERSION
);
405 static int __devexit
tsl2550_remove(struct i2c_client
*client
)
407 sysfs_remove_group(&client
->dev
.kobj
, &tsl2550_attr_group
);
409 /* Power down the device */
410 tsl2550_set_power_state(client
, 0);
412 kfree(i2c_get_clientdata(client
));
419 static int tsl2550_suspend(struct i2c_client
*client
, pm_message_t mesg
)
421 return tsl2550_set_power_state(client
, 0);
424 static int tsl2550_resume(struct i2c_client
*client
)
426 return tsl2550_set_power_state(client
, 1);
431 #define tsl2550_suspend NULL
432 #define tsl2550_resume NULL
434 #endif /* CONFIG_PM */
436 static const struct i2c_device_id tsl2550_id
[] = {
440 MODULE_DEVICE_TABLE(i2c
, tsl2550_id
);
442 static struct i2c_driver tsl2550_driver
= {
444 .name
= TSL2550_DRV_NAME
,
445 .owner
= THIS_MODULE
,
447 .suspend
= tsl2550_suspend
,
448 .resume
= tsl2550_resume
,
449 .probe
= tsl2550_probe
,
450 .remove
= __devexit_p(tsl2550_remove
),
451 .id_table
= tsl2550_id
,
454 static int __init
tsl2550_init(void)
456 return i2c_add_driver(&tsl2550_driver
);
459 static void __exit
tsl2550_exit(void)
461 i2c_del_driver(&tsl2550_driver
);
464 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
465 MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
466 MODULE_LICENSE("GPL");
467 MODULE_VERSION(DRIVER_VERSION
);
469 module_init(tsl2550_init
);
470 module_exit(tsl2550_exit
);