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/slab.h>
24 #include <linux/i2c.h>
25 #include <linux/mutex.h>
27 #define TSL2550_DRV_NAME "tsl2550"
28 #define DRIVER_VERSION "1.2"
34 #define TSL2550_POWER_DOWN 0x00
35 #define TSL2550_POWER_UP 0x03
36 #define TSL2550_STANDARD_RANGE 0x18
37 #define TSL2550_EXTENDED_RANGE 0x1d
38 #define TSL2550_READ_ADC0 0x43
39 #define TSL2550_READ_ADC1 0x83
46 struct i2c_client
*client
;
47 struct mutex update_lock
;
49 unsigned int power_state
:1;
50 unsigned int operating_mode
:1;
57 static const u8 TSL2550_MODE_RANGE
[2] = {
58 TSL2550_STANDARD_RANGE
, TSL2550_EXTENDED_RANGE
,
62 * Management functions
65 static int tsl2550_set_operating_mode(struct i2c_client
*client
, int mode
)
67 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
69 int ret
= i2c_smbus_write_byte(client
, TSL2550_MODE_RANGE
[mode
]);
71 data
->operating_mode
= mode
;
76 static int tsl2550_set_power_state(struct i2c_client
*client
, int state
)
78 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
82 ret
= i2c_smbus_write_byte(client
, TSL2550_POWER_DOWN
);
84 ret
= i2c_smbus_write_byte(client
, TSL2550_POWER_UP
);
86 /* On power up we should reset operating mode also... */
87 tsl2550_set_operating_mode(client
, data
->operating_mode
);
90 data
->power_state
= state
;
95 static int tsl2550_get_adc_value(struct i2c_client
*client
, u8 cmd
)
99 ret
= i2c_smbus_read_byte_data(client
, cmd
);
104 return ret
& 0x7f; /* remove the "valid" bit */
111 #define TSL2550_MAX_LUX 1846
113 static const u8 ratio_lut
[] = {
114 100, 100, 100, 100, 100, 100, 100, 100,
115 100, 100, 100, 100, 100, 100, 99, 99,
116 99, 99, 99, 99, 99, 99, 99, 99,
117 99, 99, 99, 98, 98, 98, 98, 98,
118 98, 98, 97, 97, 97, 97, 97, 96,
119 96, 96, 96, 95, 95, 95, 94, 94,
120 93, 93, 93, 92, 92, 91, 91, 90,
121 89, 89, 88, 87, 87, 86, 85, 84,
122 83, 82, 81, 80, 79, 78, 77, 75,
123 74, 73, 71, 69, 68, 66, 64, 62,
124 60, 58, 56, 54, 52, 49, 47, 44,
125 42, 41, 40, 40, 39, 39, 38, 38,
126 37, 37, 37, 36, 36, 36, 35, 35,
127 35, 35, 34, 34, 34, 34, 33, 33,
128 33, 33, 32, 32, 32, 32, 32, 31,
129 31, 31, 31, 31, 30, 30, 30, 30,
133 static const u16 count_lut
[] = {
134 0, 1, 2, 3, 4, 5, 6, 7,
135 8, 9, 10, 11, 12, 13, 14, 15,
136 16, 18, 20, 22, 24, 26, 28, 30,
137 32, 34, 36, 38, 40, 42, 44, 46,
138 49, 53, 57, 61, 65, 69, 73, 77,
139 81, 85, 89, 93, 97, 101, 105, 109,
140 115, 123, 131, 139, 147, 155, 163, 171,
141 179, 187, 195, 203, 211, 219, 227, 235,
142 247, 263, 279, 295, 311, 327, 343, 359,
143 375, 391, 407, 423, 439, 455, 471, 487,
144 511, 543, 575, 607, 639, 671, 703, 735,
145 767, 799, 831, 863, 895, 927, 959, 991,
146 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
147 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
148 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
149 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
153 * This function is described into Taos TSL2550 Designer's Notebook
156 static int tsl2550_calculate_lux(u8 ch0
, u8 ch1
)
160 /* Look up count from channel values */
161 u16 c0
= count_lut
[ch0
];
162 u16 c1
= count_lut
[ch1
];
166 * Note: the "128" is a scaling factor
170 /* Avoid division by 0 and count 1 cannot be greater than count 0 */
176 lux
= ((c0
- c1
) * ratio_lut
[r
]) / 256;
182 /* LUX range check */
183 return lux
> TSL2550_MAX_LUX
? TSL2550_MAX_LUX
: lux
;
190 static ssize_t
tsl2550_show_power_state(struct device
*dev
,
191 struct device_attribute
*attr
, char *buf
)
193 struct tsl2550_data
*data
= i2c_get_clientdata(to_i2c_client(dev
));
195 return sprintf(buf
, "%u\n", data
->power_state
);
198 static ssize_t
tsl2550_store_power_state(struct device
*dev
,
199 struct device_attribute
*attr
, const char *buf
, size_t count
)
201 struct i2c_client
*client
= to_i2c_client(dev
);
202 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
203 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
209 mutex_lock(&data
->update_lock
);
210 ret
= tsl2550_set_power_state(client
, val
);
211 mutex_unlock(&data
->update_lock
);
219 static DEVICE_ATTR(power_state
, S_IWUSR
| S_IRUGO
,
220 tsl2550_show_power_state
, tsl2550_store_power_state
);
222 static ssize_t
tsl2550_show_operating_mode(struct device
*dev
,
223 struct device_attribute
*attr
, char *buf
)
225 struct tsl2550_data
*data
= i2c_get_clientdata(to_i2c_client(dev
));
227 return sprintf(buf
, "%u\n", data
->operating_mode
);
230 static ssize_t
tsl2550_store_operating_mode(struct device
*dev
,
231 struct device_attribute
*attr
, const char *buf
, size_t count
)
233 struct i2c_client
*client
= to_i2c_client(dev
);
234 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
235 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
241 if (data
->power_state
== 0)
244 mutex_lock(&data
->update_lock
);
245 ret
= tsl2550_set_operating_mode(client
, val
);
246 mutex_unlock(&data
->update_lock
);
254 static DEVICE_ATTR(operating_mode
, S_IWUSR
| S_IRUGO
,
255 tsl2550_show_operating_mode
, tsl2550_store_operating_mode
);
257 static ssize_t
__tsl2550_show_lux(struct i2c_client
*client
, char *buf
)
259 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
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
);
277 if (data
->operating_mode
== 1)
280 return sprintf(buf
, "%d\n", ret
);
283 static ssize_t
tsl2550_show_lux1_input(struct device
*dev
,
284 struct device_attribute
*attr
, char *buf
)
286 struct i2c_client
*client
= to_i2c_client(dev
);
287 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
290 /* No LUX data if not operational */
291 if (!data
->power_state
)
294 mutex_lock(&data
->update_lock
);
295 ret
= __tsl2550_show_lux(client
, buf
);
296 mutex_unlock(&data
->update_lock
);
301 static DEVICE_ATTR(lux1_input
, S_IRUGO
,
302 tsl2550_show_lux1_input
, NULL
);
304 static struct attribute
*tsl2550_attributes
[] = {
305 &dev_attr_power_state
.attr
,
306 &dev_attr_operating_mode
.attr
,
307 &dev_attr_lux1_input
.attr
,
311 static const struct attribute_group tsl2550_attr_group
= {
312 .attrs
= tsl2550_attributes
,
316 * Initialization function
319 static int tsl2550_init_client(struct i2c_client
*client
)
321 struct tsl2550_data
*data
= i2c_get_clientdata(client
);
325 * Probe the chip. To do so we try to power up the device and then to
326 * read back the 0x03 code
328 err
= i2c_smbus_read_byte_data(client
, TSL2550_POWER_UP
);
331 if (err
!= TSL2550_POWER_UP
)
333 data
->power_state
= 1;
335 /* Set the default operating mode */
336 err
= i2c_smbus_write_byte(client
,
337 TSL2550_MODE_RANGE
[data
->operating_mode
]);
345 * I2C init/probing/exit functions
348 static struct i2c_driver tsl2550_driver
;
349 static int tsl2550_probe(struct i2c_client
*client
,
350 const struct i2c_device_id
*id
)
352 struct i2c_adapter
*adapter
= to_i2c_adapter(client
->dev
.parent
);
353 struct tsl2550_data
*data
;
354 int *opmode
, err
= 0;
356 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_WRITE_BYTE
357 | I2C_FUNC_SMBUS_READ_BYTE_DATA
)) {
362 data
= kzalloc(sizeof(struct tsl2550_data
), GFP_KERNEL
);
367 data
->client
= client
;
368 i2c_set_clientdata(client
, data
);
370 /* Check platform data */
371 opmode
= client
->dev
.platform_data
;
373 if (*opmode
< 0 || *opmode
> 1) {
374 dev_err(&client
->dev
, "invalid operating_mode (%d)\n",
379 data
->operating_mode
= *opmode
;
381 data
->operating_mode
= 0; /* default mode is standard */
382 dev_info(&client
->dev
, "%s operating mode\n",
383 data
->operating_mode
? "extended" : "standard");
385 mutex_init(&data
->update_lock
);
387 /* Initialize the TSL2550 chip */
388 err
= tsl2550_init_client(client
);
392 /* Register sysfs hooks */
393 err
= sysfs_create_group(&client
->dev
.kobj
, &tsl2550_attr_group
);
397 dev_info(&client
->dev
, "support ver. %s enabled\n", DRIVER_VERSION
);
407 static int tsl2550_remove(struct i2c_client
*client
)
409 sysfs_remove_group(&client
->dev
.kobj
, &tsl2550_attr_group
);
411 /* Power down the device */
412 tsl2550_set_power_state(client
, 0);
414 kfree(i2c_get_clientdata(client
));
419 #ifdef CONFIG_PM_SLEEP
421 static int tsl2550_suspend(struct device
*dev
)
423 return tsl2550_set_power_state(to_i2c_client(dev
), 0);
426 static int tsl2550_resume(struct device
*dev
)
428 return tsl2550_set_power_state(to_i2c_client(dev
), 1);
431 static SIMPLE_DEV_PM_OPS(tsl2550_pm_ops
, tsl2550_suspend
, tsl2550_resume
);
432 #define TSL2550_PM_OPS (&tsl2550_pm_ops)
436 #define TSL2550_PM_OPS NULL
438 #endif /* CONFIG_PM_SLEEP */
440 static const struct i2c_device_id tsl2550_id
[] = {
444 MODULE_DEVICE_TABLE(i2c
, tsl2550_id
);
446 static struct i2c_driver tsl2550_driver
= {
448 .name
= TSL2550_DRV_NAME
,
449 .pm
= TSL2550_PM_OPS
,
451 .probe
= tsl2550_probe
,
452 .remove
= tsl2550_remove
,
453 .id_table
= tsl2550_id
,
456 module_i2c_driver(tsl2550_driver
);
458 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
459 MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
460 MODULE_LICENSE("GPL");
461 MODULE_VERSION(DRIVER_VERSION
);