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