i2c: Add support for the TSL2550
[linux-2.6.git] / drivers / i2c / chips / tsl2550.c
1 /*
2  *  tsl2550.c - Linux kernel modules for ambient light sensor
3  *
4  *  Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
5  *  Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
6  *
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.
11  *
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.
16  *
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.
20  */
21
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>
28
29 #define TSL2550_DRV_NAME        "tsl2550"
30 #define DRIVER_VERSION          "1.1.0"
31
32 /*
33  * Defines
34  */
35
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
42
43 /*
44  * Structs
45  */
46
47 struct tsl2550_data {
48         struct i2c_client *client;
49         struct mutex update_lock;
50
51         unsigned int power_state : 1;
52         unsigned int operating_mode : 1;
53 };
54
55 /*
56  * Global data
57  */
58
59 static const u8 TSL2550_MODE_RANGE[2] = {
60         TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
61 };
62
63 /*
64  * Management functions
65  */
66
67 static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
68 {
69         struct tsl2550_data *data = i2c_get_clientdata(client);
70
71         int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
72
73         data->operating_mode = mode;
74
75         return ret;
76 }
77
78 static int tsl2550_set_power_state(struct i2c_client *client, int state)
79 {
80         struct tsl2550_data *data = i2c_get_clientdata(client);
81         int ret;
82
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);
87
88                 /* On power up we should reset operating mode also... */
89                 tsl2550_set_operating_mode(client, data->operating_mode);
90         }
91
92         data->power_state = state;
93
94         return ret;
95 }
96
97 static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
98 {
99         unsigned long end;
100         int loop = 0, ret = 0;
101
102         /*
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.
107          */
108         end = jiffies + msecs_to_jiffies(400);
109         while (time_before(jiffies, end)) {
110                 i2c_smbus_write_byte(client, cmd);
111
112                 if (loop++ < 5)
113                         mdelay(1);
114                 else
115                         msleep(1);
116
117                 ret = i2c_smbus_read_byte(client);
118                 if (ret < 0)
119                         return ret;
120                 else if (ret & 0x0080)
121                         break;
122         }
123         if (!(ret & 0x80))
124                 return -EIO;
125         return ret & 0x7f;      /* remove the "valid" bit */
126 }
127
128 /*
129  * LUX calculation
130  */
131
132 #define TSL2550_MAX_LUX         1846
133
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,
151         30,
152 };
153
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,
171 };
172
173 /*
174  * This function is described into Taos TSL2550 Designer's Notebook
175  * pages 2, 3.
176  */
177 static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
178 {
179         unsigned int lux;
180
181         /* Look up count from channel values */
182         u16 c0 = count_lut[ch0];
183         u16 c1 = count_lut[ch1];
184
185         /*
186          * Calculate ratio.
187          * Note: the "128" is a scaling factor
188          */
189         u8 r = 128;
190
191         /* Avoid division by 0 and count 1 cannot be greater than count 0 */
192         if (c0 && (c1 <= c0))
193                 r = c1 * 128 / c0;
194         else
195                 return -1;
196
197         /* Calculate LUX */
198         lux = ((c0 - c1) * ratio_lut[r]) / 256;
199
200         /* LUX range check */
201         return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
202 }
203
204 /*
205  * SysFS support
206  */
207
208 static ssize_t tsl2550_show_power_state(struct device *dev,
209                 struct device_attribute *attr, char *buf)
210 {
211         struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
212
213         return sprintf(buf, "%u\n", data->power_state);
214 }
215
216 static ssize_t tsl2550_store_power_state(struct device *dev,
217                 struct device_attribute *attr, const char *buf, size_t count)
218 {
219         struct i2c_client *client = to_i2c_client(dev);
220         struct tsl2550_data *data = i2c_get_clientdata(client);
221         unsigned long val = simple_strtoul(buf, NULL, 10);
222         int ret;
223
224         if (val < 0 || val > 1)
225                 return -EINVAL;
226
227         mutex_lock(&data->update_lock);
228         ret = tsl2550_set_power_state(client, val);
229         mutex_unlock(&data->update_lock);
230
231         if (ret < 0)
232                 return ret;
233
234         return count;
235 }
236
237 static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
238                    tsl2550_show_power_state, tsl2550_store_power_state);
239
240 static ssize_t tsl2550_show_operating_mode(struct device *dev,
241                 struct device_attribute *attr, char *buf)
242 {
243         struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
244
245         return sprintf(buf, "%u\n", data->operating_mode);
246 }
247
248 static ssize_t tsl2550_store_operating_mode(struct device *dev,
249                 struct device_attribute *attr, const char *buf, size_t count)
250 {
251         struct i2c_client *client = to_i2c_client(dev);
252         struct tsl2550_data *data = i2c_get_clientdata(client);
253         unsigned long val = simple_strtoul(buf, NULL, 10);
254         int ret;
255
256         if (val < 0 || val > 1)
257                 return -EINVAL;
258
259         if (data->power_state == 0)
260                 return -EBUSY;
261
262         mutex_lock(&data->update_lock);
263         ret = tsl2550_set_operating_mode(client, val);
264         mutex_unlock(&data->update_lock);
265
266         if (ret < 0)
267                 return ret;
268
269         return count;
270 }
271
272 static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
273                    tsl2550_show_operating_mode, tsl2550_store_operating_mode);
274
275 static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
276 {
277         u8 ch0, ch1;
278         int ret;
279
280         ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
281         if (ret < 0)
282                 return ret;
283         ch0 = ret;
284
285         mdelay(1);
286
287         ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
288         if (ret < 0)
289                 return ret;
290         ch1 = ret;
291
292         /* Do the job */
293         ret = tsl2550_calculate_lux(ch0, ch1);
294         if (ret < 0)
295                 return ret;
296
297         return sprintf(buf, "%d\n", ret);
298 }
299
300 static ssize_t tsl2550_show_lux1_input(struct device *dev,
301                         struct device_attribute *attr, char *buf)
302 {
303         struct i2c_client *client = to_i2c_client(dev);
304         struct tsl2550_data *data = i2c_get_clientdata(client);
305         int ret;
306
307         /* No LUX data if not operational */
308         if (!data->power_state)
309                 return -EBUSY;
310
311         mutex_lock(&data->update_lock);
312         ret = __tsl2550_show_lux(client, buf);
313         mutex_unlock(&data->update_lock);
314
315         return ret;
316 }
317
318 static DEVICE_ATTR(lux1_input, S_IRUGO,
319                    tsl2550_show_lux1_input, NULL);
320
321 static struct attribute *tsl2550_attributes[] = {
322         &dev_attr_power_state.attr,
323         &dev_attr_operating_mode.attr,
324         &dev_attr_lux1_input.attr,
325         NULL
326 };
327
328 static const struct attribute_group tsl2550_attr_group = {
329         .attrs = tsl2550_attributes,
330 };
331
332 /*
333  * Initialization function
334  */
335
336 static void tsl2550_init_client(struct i2c_client *client)
337 {
338         struct tsl2550_data *data = i2c_get_clientdata(client);
339
340         /* Power up the device and set the default operating mode */
341         tsl2550_set_power_state(client, 1);
342         tsl2550_set_operating_mode(client, data->operating_mode);
343 }
344
345 /*
346  * I2C init/probing/exit functions
347  */
348
349 static struct i2c_driver tsl2550_driver;
350 static int __devinit tsl2550_probe(struct i2c_client *client)
351 {
352         struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
353         struct tsl2550_data *data;
354         int *opmode, err = 0;
355
356         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
357                 err = -EIO;
358                 goto exit;
359         }
360
361         data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
362         if (!data) {
363                 err = -ENOMEM;
364                 goto exit;
365         }
366         data->client = client;
367         i2c_set_clientdata(client, data);
368
369         /* Check platform data */
370         opmode = client->dev.platform_data;
371         if (opmode) {
372                 if (*opmode < 0 || *opmode > 1) {
373                         dev_err(&client->dev, "invalid operating_mode (%d)\n",
374                                         *opmode);
375                         err = -EINVAL;
376                         goto exit_kfree;
377                 }
378                 data->operating_mode = *opmode;
379         } else
380                 data->operating_mode = 0;       /* default mode is standard */
381         dev_info(&client->dev, "%s operating mode\n",
382                         data->operating_mode ? "extended" : "standard");
383
384         /*
385          * Probe the chip. To do so we try to power up the device and then to
386          * read back the 0x03 code
387          */
388         err = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
389         if (err < 0)
390                 goto exit_kfree;
391         mdelay(1);
392         err = i2c_smbus_read_byte(client);
393         if (err != TSL2550_POWER_UP) {
394                 err = -ENODEV;
395                 goto exit_kfree;
396         }
397
398         mutex_init(&data->update_lock);
399
400         /* Initialize the TSL2550 chip */
401         tsl2550_init_client(client);
402
403         /* Register sysfs hooks */
404         err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
405         if (err)
406                 goto exit_kfree;
407
408         dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
409
410         return 0;
411
412 exit_kfree:
413         kfree(data);
414 exit:
415         return err;
416 }
417
418 static int __devexit tsl2550_remove(struct i2c_client *client)
419 {
420         sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
421
422         /* Power down the device */
423         tsl2550_set_power_state(client, 0);
424
425         kfree(i2c_get_clientdata(client));
426
427         return 0;
428 }
429
430 static struct i2c_driver tsl2550_driver = {
431         .driver = {
432                 .name   = TSL2550_DRV_NAME,
433                 .owner  = THIS_MODULE,
434         },
435         .probe  = tsl2550_probe,
436         .remove = __devexit_p(tsl2550_remove),
437 };
438
439 static int __init tsl2550_init(void)
440 {
441         return i2c_add_driver(&tsl2550_driver);
442 }
443
444 static void __exit tsl2550_exit(void)
445 {
446         i2c_del_driver(&tsl2550_driver);
447 }
448
449 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
450 MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
451 MODULE_LICENSE("GPL");
452
453 module_init(tsl2550_init);
454 module_exit(tsl2550_exit);