Merge git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/linux-2.6-nsfd
[pandora-kernel.git] / drivers / staging / iio / light / isl29018.c
1 /*
2  * A iio driver for the light sensor ISL 29018.
3  *
4  * IIO driver for monitoring ambient light intensity in luxi, proximity
5  * sensing and infrared sensing.
6  *
7  * Copyright (c) 2010, NVIDIA Corporation.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17  * more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22  */
23
24 #include <linux/module.h>
25 #include <linux/i2c.h>
26 #include <linux/err.h>
27 #include <linux/mutex.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include "../iio.h"
31
32 #define CONVERSION_TIME_MS              100
33
34 #define ISL29018_REG_ADD_COMMAND1       0x00
35 #define COMMMAND1_OPMODE_SHIFT          5
36 #define COMMMAND1_OPMODE_MASK           (7 << COMMMAND1_OPMODE_SHIFT)
37 #define COMMMAND1_OPMODE_POWER_DOWN     0
38 #define COMMMAND1_OPMODE_ALS_ONCE       1
39 #define COMMMAND1_OPMODE_IR_ONCE        2
40 #define COMMMAND1_OPMODE_PROX_ONCE      3
41
42 #define ISL29018_REG_ADD_COMMANDII      0x01
43 #define COMMANDII_RESOLUTION_SHIFT      2
44 #define COMMANDII_RESOLUTION_MASK       (0x3 << COMMANDII_RESOLUTION_SHIFT)
45
46 #define COMMANDII_RANGE_SHIFT           0
47 #define COMMANDII_RANGE_MASK            (0x3 << COMMANDII_RANGE_SHIFT)
48
49 #define COMMANDII_SCHEME_SHIFT          7
50 #define COMMANDII_SCHEME_MASK           (0x1 << COMMANDII_SCHEME_SHIFT)
51
52 #define ISL29018_REG_ADD_DATA_LSB       0x02
53 #define ISL29018_REG_ADD_DATA_MSB       0x03
54 #define ISL29018_MAX_REGS               ISL29018_REG_ADD_DATA_MSB
55
56 struct isl29018_chip {
57         struct iio_dev          *indio_dev;
58         struct i2c_client       *client;
59         struct mutex            lock;
60         unsigned int            range;
61         unsigned int            adc_bit;
62         int                     prox_scheme;
63         u8                      reg_cache[ISL29018_MAX_REGS];
64 };
65
66 static int isl29018_write_data(struct i2c_client *client, u8 reg,
67                         u8 val, u8 mask, u8 shift)
68 {
69         u8 regval;
70         int ret = 0;
71         struct isl29018_chip *chip = i2c_get_clientdata(client);
72
73         regval = chip->reg_cache[reg];
74         regval &= ~mask;
75         regval |= val << shift;
76
77         ret = i2c_smbus_write_byte_data(client, reg, regval);
78         if (ret) {
79                 dev_err(&client->dev, "Write to device fails status %x\n", ret);
80                 return ret;
81         }
82         chip->reg_cache[reg] = regval;
83
84         return 0;
85 }
86
87 static int isl29018_set_range(struct i2c_client *client, unsigned long range,
88                 unsigned int *new_range)
89 {
90         static const unsigned long supp_ranges[] = {1000, 4000, 16000, 64000};
91         int i;
92
93         for (i = 0; i < ARRAY_SIZE(supp_ranges); ++i) {
94                 if (range <= supp_ranges[i]) {
95                         *new_range = (unsigned int)supp_ranges[i];
96                         break;
97                 }
98         }
99
100         if (i >= ARRAY_SIZE(supp_ranges))
101                 return -EINVAL;
102
103         return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII,
104                         i, COMMANDII_RANGE_MASK, COMMANDII_RANGE_SHIFT);
105 }
106
107 static int isl29018_set_resolution(struct i2c_client *client,
108                         unsigned long adcbit, unsigned int *conf_adc_bit)
109 {
110         static const unsigned long supp_adcbit[] = {16, 12, 8, 4};
111         int i;
112
113         for (i = 0; i < ARRAY_SIZE(supp_adcbit); ++i) {
114                 if (adcbit >= supp_adcbit[i]) {
115                         *conf_adc_bit = (unsigned int)supp_adcbit[i];
116                         break;
117                 }
118         }
119
120         if (i >= ARRAY_SIZE(supp_adcbit))
121                 return -EINVAL;
122
123         return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII,
124                         i, COMMANDII_RESOLUTION_MASK,
125                         COMMANDII_RESOLUTION_SHIFT);
126 }
127
128 static int isl29018_read_sensor_input(struct i2c_client *client, int mode)
129 {
130         int status;
131         int lsb;
132         int msb;
133
134         /* Set mode */
135         status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1,
136                         mode, COMMMAND1_OPMODE_MASK, COMMMAND1_OPMODE_SHIFT);
137         if (status) {
138                 dev_err(&client->dev, "Error in setting operating mode\n");
139                 return status;
140         }
141         msleep(CONVERSION_TIME_MS);
142         lsb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_LSB);
143         if (lsb < 0) {
144                 dev_err(&client->dev, "Error in reading LSB DATA\n");
145                 return lsb;
146         }
147
148         msb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_MSB);
149         if (msb < 0) {
150                 dev_err(&client->dev, "Error in reading MSB DATA\n");
151                 return msb;
152         }
153         dev_vdbg(&client->dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb);
154
155         return (msb << 8) | lsb;
156 }
157
158 static int isl29018_read_lux(struct i2c_client *client, int *lux)
159 {
160         int lux_data;
161         struct isl29018_chip *chip = i2c_get_clientdata(client);
162
163         lux_data = isl29018_read_sensor_input(client,
164                                 COMMMAND1_OPMODE_ALS_ONCE);
165
166         if (lux_data < 0)
167                 return lux_data;
168
169         *lux = (lux_data * chip->range) >> chip->adc_bit;
170
171         return 0;
172 }
173
174 static int isl29018_read_ir(struct i2c_client *client, int *ir)
175 {
176         int ir_data;
177
178         ir_data = isl29018_read_sensor_input(client, COMMMAND1_OPMODE_IR_ONCE);
179
180         if (ir_data < 0)
181                 return ir_data;
182
183         *ir = ir_data;
184
185         return 0;
186 }
187
188 static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme,
189                 int *near_ir)
190 {
191         int status;
192         int prox_data = -1;
193         int ir_data = -1;
194
195         /* Do proximity sensing with required scheme */
196         status = isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII,
197                         scheme, COMMANDII_SCHEME_MASK, COMMANDII_SCHEME_SHIFT);
198         if (status) {
199                 dev_err(&client->dev, "Error in setting operating mode\n");
200                 return status;
201         }
202
203         prox_data = isl29018_read_sensor_input(client,
204                                         COMMMAND1_OPMODE_PROX_ONCE);
205         if (prox_data < 0)
206                 return prox_data;
207
208         if (scheme == 1) {
209                 *near_ir = prox_data;
210                 return 0;
211         }
212
213         ir_data = isl29018_read_sensor_input(client,
214                                 COMMMAND1_OPMODE_IR_ONCE);
215
216         if (ir_data < 0)
217                 return ir_data;
218
219         if (prox_data >= ir_data)
220                 *near_ir = prox_data - ir_data;
221         else
222                 *near_ir = 0;
223
224         return 0;
225 }
226
227 static ssize_t get_sensor_data(struct device *dev, char *buf, int mode)
228 {
229         struct iio_dev *indio_dev = dev_get_drvdata(dev);
230         struct isl29018_chip *chip = indio_dev->dev_data;
231         struct i2c_client *client = chip->client;
232         int value = 0;
233         int status;
234
235         mutex_lock(&chip->lock);
236         switch (mode) {
237         case COMMMAND1_OPMODE_PROX_ONCE:
238                 status = isl29018_read_proximity_ir(client,
239                                 chip->prox_scheme, &value);
240                 break;
241
242         case COMMMAND1_OPMODE_ALS_ONCE:
243                 status = isl29018_read_lux(client, &value);
244                 break;
245
246         case COMMMAND1_OPMODE_IR_ONCE:
247                 status = isl29018_read_ir(client, &value);
248                 break;
249
250         default:
251                 dev_err(&client->dev, "Mode %d is not supported\n", mode);
252                 mutex_unlock(&chip->lock);
253                 return -EBUSY;
254         }
255         if (status < 0) {
256                 dev_err(&client->dev, "Error in Reading data");
257                 mutex_unlock(&chip->lock);
258                 return status;
259         }
260
261         mutex_unlock(&chip->lock);
262
263         return sprintf(buf, "%d\n", value);
264 }
265
266 /* Sysfs interface */
267 /* range */
268 static ssize_t show_range(struct device *dev,
269                         struct device_attribute *attr, char *buf)
270 {
271         struct iio_dev *indio_dev = dev_get_drvdata(dev);
272         struct isl29018_chip *chip = indio_dev->dev_data;
273
274         return sprintf(buf, "%u\n", chip->range);
275 }
276
277 static ssize_t store_range(struct device *dev,
278                 struct device_attribute *attr, const char *buf, size_t count)
279 {
280         struct iio_dev *indio_dev = dev_get_drvdata(dev);
281         struct isl29018_chip *chip = indio_dev->dev_data;
282         struct i2c_client *client = chip->client;
283         int status;
284         unsigned long lval;
285         unsigned int new_range;
286
287         if (strict_strtoul(buf, 10, &lval))
288                 return -EINVAL;
289
290         if (!(lval == 1000UL || lval == 4000UL ||
291                         lval == 16000UL || lval == 64000UL)) {
292                 dev_err(dev, "The range is not supported\n");
293                 return -EINVAL;
294         }
295
296         mutex_lock(&chip->lock);
297         status = isl29018_set_range(client, lval, &new_range);
298         if (status < 0) {
299                 mutex_unlock(&chip->lock);
300                 dev_err(dev, "Error in setting max range\n");
301                 return status;
302         }
303         chip->range = new_range;
304         mutex_unlock(&chip->lock);
305
306         return count;
307 }
308
309 /* resolution */
310 static ssize_t show_resolution(struct device *dev,
311                         struct device_attribute *attr, char *buf)
312 {
313         struct iio_dev *indio_dev = dev_get_drvdata(dev);
314         struct isl29018_chip *chip = indio_dev->dev_data;
315
316         return sprintf(buf, "%u\n", chip->adc_bit);
317 }
318
319 static ssize_t store_resolution(struct device *dev,
320                 struct device_attribute *attr, const char *buf, size_t count)
321 {
322         struct iio_dev *indio_dev = dev_get_drvdata(dev);
323         struct isl29018_chip *chip = indio_dev->dev_data;
324         struct i2c_client *client = chip->client;
325         int status;
326         unsigned long lval;
327         unsigned int new_adc_bit;
328
329         if (strict_strtoul(buf, 10, &lval))
330                 return -EINVAL;
331         if (!(lval == 4 || lval == 8 || lval == 12 || lval == 16)) {
332                 dev_err(dev, "The resolution is not supported\n");
333                 return -EINVAL;
334         }
335
336         mutex_lock(&chip->lock);
337         status = isl29018_set_resolution(client, lval, &new_adc_bit);
338         if (status < 0) {
339                 mutex_unlock(&chip->lock);
340                 dev_err(dev, "Error in setting resolution\n");
341                 return status;
342         }
343         chip->adc_bit = new_adc_bit;
344         mutex_unlock(&chip->lock);
345
346         return count;
347 }
348
349 /* proximity scheme */
350 static ssize_t show_prox_infrared_supression(struct device *dev,
351                         struct device_attribute *attr, char *buf)
352 {
353         struct iio_dev *indio_dev = dev_get_drvdata(dev);
354         struct isl29018_chip *chip = indio_dev->dev_data;
355
356         /* return the "proximity scheme" i.e. if the chip does on chip
357         infrared supression (1 means perform on chip supression) */
358         return sprintf(buf, "%d\n", chip->prox_scheme);
359 }
360
361 static ssize_t store_prox_infrared_supression(struct device *dev,
362                 struct device_attribute *attr, const char *buf, size_t count)
363 {
364         struct iio_dev *indio_dev = dev_get_drvdata(dev);
365         struct isl29018_chip *chip = indio_dev->dev_data;
366         unsigned long lval;
367
368         if (strict_strtoul(buf, 10, &lval))
369                 return -EINVAL;
370         if (!(lval == 0UL || lval == 1UL)) {
371                 dev_err(dev, "The mode is not supported\n");
372                 return -EINVAL;
373         }
374
375         /* get the  "proximity scheme" i.e. if the chip does on chip
376         infrared supression (1 means perform on chip supression) */
377         mutex_lock(&chip->lock);
378         chip->prox_scheme = (int)lval;
379         mutex_unlock(&chip->lock);
380
381         return count;
382 }
383
384 /* Read lux */
385 static ssize_t show_lux(struct device *dev,
386                 struct device_attribute *devattr, char *buf)
387 {
388         return get_sensor_data(dev, buf, COMMMAND1_OPMODE_ALS_ONCE);
389 }
390
391 /* Read ir */
392 static ssize_t show_ir(struct device *dev,
393                 struct device_attribute *devattr, char *buf)
394 {
395         return get_sensor_data(dev, buf, COMMMAND1_OPMODE_IR_ONCE);
396 }
397
398 /* Read nearest ir */
399 static ssize_t show_proxim_ir(struct device *dev,
400                 struct device_attribute *devattr, char *buf)
401 {
402         return get_sensor_data(dev, buf, COMMMAND1_OPMODE_PROX_ONCE);
403 }
404
405 static IIO_DEVICE_ATTR(range, S_IRUGO | S_IWUSR, show_range, store_range, 0);
406 static IIO_CONST_ATTR(range_available, "1000 4000 16000 64000");
407 static IIO_CONST_ATTR(adc_resolution_available, "4 8 12 16");
408 static IIO_DEVICE_ATTR(adc_resolution, S_IRUGO | S_IWUSR,
409                                         show_resolution, store_resolution, 0);
410 static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_supression,
411                                         S_IRUGO | S_IWUSR,
412                                         show_prox_infrared_supression,
413                                         store_prox_infrared_supression, 0);
414 static IIO_DEVICE_ATTR(illuminance0_input, S_IRUGO, show_lux, NULL, 0);
415 static IIO_DEVICE_ATTR(intensity_infrared_raw, S_IRUGO, show_ir, NULL, 0);
416 static IIO_DEVICE_ATTR(proximity_raw, S_IRUGO, show_proxim_ir, NULL, 0);
417
418 #define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr)
419 #define ISL29018_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
420 static struct attribute *isl29018_attributes[] = {
421         ISL29018_DEV_ATTR(range),
422         ISL29018_CONST_ATTR(range_available),
423         ISL29018_DEV_ATTR(adc_resolution),
424         ISL29018_CONST_ATTR(adc_resolution_available),
425         ISL29018_DEV_ATTR(proximity_on_chip_ambient_infrared_supression),
426         ISL29018_DEV_ATTR(illuminance0_input),
427         ISL29018_DEV_ATTR(intensity_infrared_raw),
428         ISL29018_DEV_ATTR(proximity_raw),
429         NULL
430 };
431
432 static const struct attribute_group isl29108_group = {
433         .attrs = isl29018_attributes,
434 };
435
436 static int isl29018_chip_init(struct i2c_client *client)
437 {
438         struct isl29018_chip *chip = i2c_get_clientdata(client);
439         int status;
440         int new_adc_bit;
441         unsigned int new_range;
442
443         memset(chip->reg_cache, 0, sizeof(chip->reg_cache));
444
445         /* set defaults */
446         status = isl29018_set_range(client, chip->range, &new_range);
447         if (status < 0) {
448                 dev_err(&client->dev, "Init of isl29018 fails\n");
449                 return status;
450         }
451
452         status = isl29018_set_resolution(client, chip->adc_bit,
453                                                 &new_adc_bit);
454
455         return 0;
456 }
457
458 static const struct iio_info isl29108_info = {
459         .attrs = &isl29108_group,
460         .driver_module = THIS_MODULE,
461 };
462
463 static int __devinit isl29018_probe(struct i2c_client *client,
464                          const struct i2c_device_id *id)
465 {
466         struct isl29018_chip *chip;
467         int err;
468
469         chip = kzalloc(sizeof(struct isl29018_chip), GFP_KERNEL);
470         if (!chip) {
471                 dev_err(&client->dev, "Memory allocation fails\n");
472                 err = -ENOMEM;
473                 goto exit;
474         }
475
476         i2c_set_clientdata(client, chip);
477         chip->client = client;
478
479         mutex_init(&chip->lock);
480
481         chip->range = 1000;
482         chip->adc_bit = 16;
483
484         err = isl29018_chip_init(client);
485         if (err)
486                 goto exit_free;
487
488         chip->indio_dev = iio_allocate_device(0);
489         if (!chip->indio_dev) {
490                 dev_err(&client->dev, "iio allocation fails\n");
491                 goto exit_free;
492         }
493         chip->indio_dev->info = &isl29108_info;
494         chip->indio_dev->name = id->name;
495         chip->indio_dev->dev.parent = &client->dev;
496         chip->indio_dev->dev_data = (void *)(chip);
497         chip->indio_dev->modes = INDIO_DIRECT_MODE;
498         err = iio_device_register(chip->indio_dev);
499         if (err) {
500                 dev_err(&client->dev, "iio registration fails\n");
501                 goto exit_iio_free;
502         }
503
504         return 0;
505 exit_iio_free:
506         iio_free_device(chip->indio_dev);
507 exit_free:
508         kfree(chip);
509 exit:
510         return err;
511 }
512
513 static int __devexit isl29018_remove(struct i2c_client *client)
514 {
515         struct isl29018_chip *chip = i2c_get_clientdata(client);
516
517         dev_dbg(&client->dev, "%s()\n", __func__);
518         iio_device_unregister(chip->indio_dev);
519         kfree(chip);
520
521         return 0;
522 }
523
524 static const struct i2c_device_id isl29018_id[] = {
525         {"isl29018", 0},
526         {}
527 };
528
529 MODULE_DEVICE_TABLE(i2c, isl29018_id);
530
531 static struct i2c_driver isl29018_driver = {
532         .class  = I2C_CLASS_HWMON,
533         .driver  = {
534                         .name = "isl29018",
535                         .owner = THIS_MODULE,
536                     },
537         .probe   = isl29018_probe,
538         .remove  = __devexit_p(isl29018_remove),
539         .id_table = isl29018_id,
540 };
541
542 static int __init isl29018_init(void)
543 {
544         return i2c_add_driver(&isl29018_driver);
545 }
546
547 static void __exit isl29018_exit(void)
548 {
549         i2c_del_driver(&isl29018_driver);
550 }
551
552 module_init(isl29018_init);
553 module_exit(isl29018_exit);
554
555 MODULE_DESCRIPTION("ISL29018 Ambient Light Sensor driver");
556 MODULE_LICENSE("GPL");