i2c/tsl2550: Fix lux value in extended mode
[linux-2.6/mini2440.git] / drivers / i2c / chips / tsl2550.c
blobec0a7cab6c8b04439e8cbb1b50cb0e8416fc07f3
1 /*
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>
27 #include <linux/delay.h>
29 #define TSL2550_DRV_NAME "tsl2550"
30 #define DRIVER_VERSION "1.1.2"
33 * Defines
36 #define TSL2550_POWER_DOWN 0x00
37 #define TSL2550_POWER_UP 0x03
38 #define TSL2550_STANDARD_RANGE 0x18
39 #define TSL2550_EXTENDED_RANGE 0x1d
40 #define TSL2550_READ_ADC0 0x43
41 #define TSL2550_READ_ADC1 0x83
44 * Structs
47 struct tsl2550_data {
48 struct i2c_client *client;
49 struct mutex update_lock;
51 unsigned int power_state : 1;
52 unsigned int operating_mode : 1;
56 * Global data
59 static const u8 TSL2550_MODE_RANGE[2] = {
60 TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
64 * Management functions
67 static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
69 struct tsl2550_data *data = i2c_get_clientdata(client);
71 int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
73 data->operating_mode = mode;
75 return ret;
78 static int tsl2550_set_power_state(struct i2c_client *client, int state)
80 struct tsl2550_data *data = i2c_get_clientdata(client);
81 int ret;
83 if (state == 0)
84 ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
85 else {
86 ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
88 /* On power up we should reset operating mode also... */
89 tsl2550_set_operating_mode(client, data->operating_mode);
92 data->power_state = state;
94 return ret;
97 static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
99 unsigned long end;
100 int loop = 0, ret = 0;
103 * Read ADC channel waiting at most 400ms (see data sheet for further
104 * info).
105 * To avoid long busy wait we spin for few milliseconds then
106 * start sleeping.
108 end = jiffies + msecs_to_jiffies(400);
109 while (time_before(jiffies, end)) {
110 i2c_smbus_write_byte(client, cmd);
112 if (loop++ < 5)
113 mdelay(1);
114 else
115 msleep(1);
117 ret = i2c_smbus_read_byte(client);
118 if (ret < 0)
119 return ret;
120 else if (ret & 0x0080)
121 break;
123 if (!(ret & 0x80))
124 return -EIO;
125 return ret & 0x7f; /* remove the "valid" bit */
129 * LUX calculation
132 #define TSL2550_MAX_LUX 1846
134 static const u8 ratio_lut[] = {
135 100, 100, 100, 100, 100, 100, 100, 100,
136 100, 100, 100, 100, 100, 100, 99, 99,
137 99, 99, 99, 99, 99, 99, 99, 99,
138 99, 99, 99, 98, 98, 98, 98, 98,
139 98, 98, 97, 97, 97, 97, 97, 96,
140 96, 96, 96, 95, 95, 95, 94, 94,
141 93, 93, 93, 92, 92, 91, 91, 90,
142 89, 89, 88, 87, 87, 86, 85, 84,
143 83, 82, 81, 80, 79, 78, 77, 75,
144 74, 73, 71, 69, 68, 66, 64, 62,
145 60, 58, 56, 54, 52, 49, 47, 44,
146 42, 41, 40, 40, 39, 39, 38, 38,
147 37, 37, 37, 36, 36, 36, 35, 35,
148 35, 35, 34, 34, 34, 34, 33, 33,
149 33, 33, 32, 32, 32, 32, 32, 31,
150 31, 31, 31, 31, 30, 30, 30, 30,
154 static const u16 count_lut[] = {
155 0, 1, 2, 3, 4, 5, 6, 7,
156 8, 9, 10, 11, 12, 13, 14, 15,
157 16, 18, 20, 22, 24, 26, 28, 30,
158 32, 34, 36, 38, 40, 42, 44, 46,
159 49, 53, 57, 61, 65, 69, 73, 77,
160 81, 85, 89, 93, 97, 101, 105, 109,
161 115, 123, 131, 139, 147, 155, 163, 171,
162 179, 187, 195, 203, 211, 219, 227, 235,
163 247, 263, 279, 295, 311, 327, 343, 359,
164 375, 391, 407, 423, 439, 455, 471, 487,
165 511, 543, 575, 607, 639, 671, 703, 735,
166 767, 799, 831, 863, 895, 927, 959, 991,
167 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
168 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
169 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
170 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
174 * This function is described into Taos TSL2550 Designer's Notebook
175 * pages 2, 3.
177 static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
179 unsigned int lux;
181 /* Look up count from channel values */
182 u16 c0 = count_lut[ch0];
183 u16 c1 = count_lut[ch1];
186 * Calculate ratio.
187 * Note: the "128" is a scaling factor
189 u8 r = 128;
191 /* Avoid division by 0 and count 1 cannot be greater than count 0 */
192 if (c1 <= c0)
193 if (c0) {
194 r = c1 * 128 / c0;
196 /* Calculate LUX */
197 lux = ((c0 - c1) * ratio_lut[r]) / 256;
198 } else
199 lux = 0;
200 else
201 return -EAGAIN;
203 /* LUX range check */
204 return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
208 * SysFS support
211 static ssize_t tsl2550_show_power_state(struct device *dev,
212 struct device_attribute *attr, char *buf)
214 struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
216 return sprintf(buf, "%u\n", data->power_state);
219 static ssize_t tsl2550_store_power_state(struct device *dev,
220 struct device_attribute *attr, const char *buf, size_t count)
222 struct i2c_client *client = to_i2c_client(dev);
223 struct tsl2550_data *data = i2c_get_clientdata(client);
224 unsigned long val = simple_strtoul(buf, NULL, 10);
225 int ret;
227 if (val < 0 || val > 1)
228 return -EINVAL;
230 mutex_lock(&data->update_lock);
231 ret = tsl2550_set_power_state(client, val);
232 mutex_unlock(&data->update_lock);
234 if (ret < 0)
235 return ret;
237 return count;
240 static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
241 tsl2550_show_power_state, tsl2550_store_power_state);
243 static ssize_t tsl2550_show_operating_mode(struct device *dev,
244 struct device_attribute *attr, char *buf)
246 struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
248 return sprintf(buf, "%u\n", data->operating_mode);
251 static ssize_t tsl2550_store_operating_mode(struct device *dev,
252 struct device_attribute *attr, const char *buf, size_t count)
254 struct i2c_client *client = to_i2c_client(dev);
255 struct tsl2550_data *data = i2c_get_clientdata(client);
256 unsigned long val = simple_strtoul(buf, NULL, 10);
257 int ret;
259 if (val < 0 || val > 1)
260 return -EINVAL;
262 if (data->power_state == 0)
263 return -EBUSY;
265 mutex_lock(&data->update_lock);
266 ret = tsl2550_set_operating_mode(client, val);
267 mutex_unlock(&data->update_lock);
269 if (ret < 0)
270 return ret;
272 return count;
275 static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
276 tsl2550_show_operating_mode, tsl2550_store_operating_mode);
278 static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
280 struct tsl2550_data *data = i2c_get_clientdata(client);
281 u8 ch0, ch1;
282 int ret;
284 ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
285 if (ret < 0)
286 return ret;
287 ch0 = ret;
289 mdelay(1);
291 ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
292 if (ret < 0)
293 return ret;
294 ch1 = ret;
296 /* Do the job */
297 ret = tsl2550_calculate_lux(ch0, ch1);
298 if (ret < 0)
299 return ret;
300 if (data->operating_mode == 1)
301 ret *= 5;
303 return sprintf(buf, "%d\n", ret);
306 static ssize_t tsl2550_show_lux1_input(struct device *dev,
307 struct device_attribute *attr, char *buf)
309 struct i2c_client *client = to_i2c_client(dev);
310 struct tsl2550_data *data = i2c_get_clientdata(client);
311 int ret;
313 /* No LUX data if not operational */
314 if (!data->power_state)
315 return -EBUSY;
317 mutex_lock(&data->update_lock);
318 ret = __tsl2550_show_lux(client, buf);
319 mutex_unlock(&data->update_lock);
321 return ret;
324 static DEVICE_ATTR(lux1_input, S_IRUGO,
325 tsl2550_show_lux1_input, NULL);
327 static struct attribute *tsl2550_attributes[] = {
328 &dev_attr_power_state.attr,
329 &dev_attr_operating_mode.attr,
330 &dev_attr_lux1_input.attr,
331 NULL
334 static const struct attribute_group tsl2550_attr_group = {
335 .attrs = tsl2550_attributes,
339 * Initialization function
342 static int tsl2550_init_client(struct i2c_client *client)
344 struct tsl2550_data *data = i2c_get_clientdata(client);
345 int err;
348 * Probe the chip. To do so we try to power up the device and then to
349 * read back the 0x03 code
351 err = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
352 if (err < 0)
353 return err;
354 mdelay(1);
355 if (i2c_smbus_read_byte(client) != TSL2550_POWER_UP)
356 return -ENODEV;
357 data->power_state = 1;
359 /* Set the default operating mode */
360 err = i2c_smbus_write_byte(client,
361 TSL2550_MODE_RANGE[data->operating_mode]);
362 if (err < 0)
363 return err;
365 return 0;
369 * I2C init/probing/exit functions
372 static struct i2c_driver tsl2550_driver;
373 static int __devinit tsl2550_probe(struct i2c_client *client,
374 const struct i2c_device_id *id)
376 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
377 struct tsl2550_data *data;
378 int *opmode, err = 0;
380 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
381 err = -EIO;
382 goto exit;
385 data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
386 if (!data) {
387 err = -ENOMEM;
388 goto exit;
390 data->client = client;
391 i2c_set_clientdata(client, data);
393 /* Check platform data */
394 opmode = client->dev.platform_data;
395 if (opmode) {
396 if (*opmode < 0 || *opmode > 1) {
397 dev_err(&client->dev, "invalid operating_mode (%d)\n",
398 *opmode);
399 err = -EINVAL;
400 goto exit_kfree;
402 data->operating_mode = *opmode;
403 } else
404 data->operating_mode = 0; /* default mode is standard */
405 dev_info(&client->dev, "%s operating mode\n",
406 data->operating_mode ? "extended" : "standard");
408 mutex_init(&data->update_lock);
410 /* Initialize the TSL2550 chip */
411 err = tsl2550_init_client(client);
412 if (err)
413 goto exit_kfree;
415 /* Register sysfs hooks */
416 err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
417 if (err)
418 goto exit_kfree;
420 dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
422 return 0;
424 exit_kfree:
425 kfree(data);
426 exit:
427 return err;
430 static int __devexit tsl2550_remove(struct i2c_client *client)
432 sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
434 /* Power down the device */
435 tsl2550_set_power_state(client, 0);
437 kfree(i2c_get_clientdata(client));
439 return 0;
442 #ifdef CONFIG_PM
444 static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg)
446 return tsl2550_set_power_state(client, 0);
449 static int tsl2550_resume(struct i2c_client *client)
451 return tsl2550_set_power_state(client, 1);
454 #else
456 #define tsl2550_suspend NULL
457 #define tsl2550_resume NULL
459 #endif /* CONFIG_PM */
461 static const struct i2c_device_id tsl2550_id[] = {
462 { "tsl2550", 0 },
465 MODULE_DEVICE_TABLE(i2c, tsl2550_id);
467 static struct i2c_driver tsl2550_driver = {
468 .driver = {
469 .name = TSL2550_DRV_NAME,
470 .owner = THIS_MODULE,
472 .suspend = tsl2550_suspend,
473 .resume = tsl2550_resume,
474 .probe = tsl2550_probe,
475 .remove = __devexit_p(tsl2550_remove),
476 .id_table = tsl2550_id,
479 static int __init tsl2550_init(void)
481 return i2c_add_driver(&tsl2550_driver);
484 static void __exit tsl2550_exit(void)
486 i2c_del_driver(&tsl2550_driver);
489 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
490 MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
491 MODULE_LICENSE("GPL");
492 MODULE_VERSION(DRIVER_VERSION);
494 module_init(tsl2550_init);
495 module_exit(tsl2550_exit);