GNU Linux-libre 4.14.266-gnu1
[releases.git] / drivers / staging / iio / light / tsl2x7x.c
1 /*
2  * Device driver for monitoring ambient light intensity in (lux)
3  * and proximity detection (prox) within the TAOS TSL2X7X family of devices.
4  *
5  * Copyright (c) 2012, TAOS Corporation.
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, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  */
17
18 #include <linux/kernel.h>
19 #include <linux/i2c.h>
20 #include <linux/errno.h>
21 #include <linux/delay.h>
22 #include <linux/mutex.h>
23 #include <linux/interrupt.h>
24 #include <linux/slab.h>
25 #include <linux/module.h>
26 #include <linux/iio/events.h>
27 #include <linux/iio/iio.h>
28 #include <linux/iio/sysfs.h>
29 #include "tsl2x7x.h"
30
31 /* Cal defs*/
32 #define PROX_STAT_CAL        0
33 #define PROX_STAT_SAMP       1
34 #define MAX_SAMPLES_CAL      200
35
36 /* TSL2X7X Device ID */
37 #define TRITON_ID    0x00
38 #define SWORDFISH_ID 0x30
39 #define HALIBUT_ID   0x20
40
41 /* Lux calculation constants */
42 #define TSL2X7X_LUX_CALC_OVER_FLOW     65535
43
44 /* TAOS Register definitions - note:
45  * depending on device, some of these register are not used and the
46  * register address is benign.
47  */
48 /* 2X7X register offsets */
49 #define TSL2X7X_MAX_CONFIG_REG         16
50
51 /* Device Registers and Masks */
52 #define TSL2X7X_CNTRL                  0x00
53 #define TSL2X7X_ALS_TIME               0X01
54 #define TSL2X7X_PRX_TIME               0x02
55 #define TSL2X7X_WAIT_TIME              0x03
56 #define TSL2X7X_ALS_MINTHRESHLO        0X04
57 #define TSL2X7X_ALS_MINTHRESHHI        0X05
58 #define TSL2X7X_ALS_MAXTHRESHLO        0X06
59 #define TSL2X7X_ALS_MAXTHRESHHI        0X07
60 #define TSL2X7X_PRX_MINTHRESHLO        0X08
61 #define TSL2X7X_PRX_MINTHRESHHI        0X09
62 #define TSL2X7X_PRX_MAXTHRESHLO        0X0A
63 #define TSL2X7X_PRX_MAXTHRESHHI        0X0B
64 #define TSL2X7X_PERSISTENCE            0x0C
65 #define TSL2X7X_PRX_CONFIG             0x0D
66 #define TSL2X7X_PRX_COUNT              0x0E
67 #define TSL2X7X_GAIN                   0x0F
68 #define TSL2X7X_NOTUSED                0x10
69 #define TSL2X7X_REVID                  0x11
70 #define TSL2X7X_CHIPID                 0x12
71 #define TSL2X7X_STATUS                 0x13
72 #define TSL2X7X_ALS_CHAN0LO            0x14
73 #define TSL2X7X_ALS_CHAN0HI            0x15
74 #define TSL2X7X_ALS_CHAN1LO            0x16
75 #define TSL2X7X_ALS_CHAN1HI            0x17
76 #define TSL2X7X_PRX_LO                 0x18
77 #define TSL2X7X_PRX_HI                 0x19
78
79 /* tsl2X7X cmd reg masks */
80 #define TSL2X7X_CMD_REG                0x80
81 #define TSL2X7X_CMD_SPL_FN             0x60
82
83 #define TSL2X7X_CMD_PROX_INT_CLR       0X05
84 #define TSL2X7X_CMD_ALS_INT_CLR        0x06
85 #define TSL2X7X_CMD_PROXALS_INT_CLR    0X07
86
87 /* tsl2X7X cntrl reg masks */
88 #define TSL2X7X_CNTL_ADC_ENBL          0x02
89 #define TSL2X7X_CNTL_PWR_ON            0x01
90
91 /* tsl2X7X status reg masks */
92 #define TSL2X7X_STA_ADC_VALID          0x01
93 #define TSL2X7X_STA_PRX_VALID          0x02
94 #define TSL2X7X_STA_ADC_PRX_VALID      (TSL2X7X_STA_ADC_VALID |\
95                                         TSL2X7X_STA_PRX_VALID)
96 #define TSL2X7X_STA_ALS_INTR           0x10
97 #define TSL2X7X_STA_PRX_INTR           0x20
98
99 /* tsl2X7X cntrl reg masks */
100 #define TSL2X7X_CNTL_REG_CLEAR         0x00
101 #define TSL2X7X_CNTL_PROX_INT_ENBL     0X20
102 #define TSL2X7X_CNTL_ALS_INT_ENBL      0X10
103 #define TSL2X7X_CNTL_WAIT_TMR_ENBL     0X08
104 #define TSL2X7X_CNTL_PROX_DET_ENBL     0X04
105 #define TSL2X7X_CNTL_PWRON             0x01
106 #define TSL2X7X_CNTL_ALSPON_ENBL       0x03
107 #define TSL2X7X_CNTL_INTALSPON_ENBL    0x13
108 #define TSL2X7X_CNTL_PROXPON_ENBL      0x0F
109 #define TSL2X7X_CNTL_INTPROXPON_ENBL   0x2F
110
111 /*Prox diode to use */
112 #define TSL2X7X_DIODE0                 0x10
113 #define TSL2X7X_DIODE1                 0x20
114 #define TSL2X7X_DIODE_BOTH             0x30
115
116 /* LED Power */
117 #define TSL2X7X_mA100                  0x00
118 #define TSL2X7X_mA50                   0x40
119 #define TSL2X7X_mA25                   0x80
120 #define TSL2X7X_mA13                   0xD0
121 #define TSL2X7X_MAX_TIMER_CNT          (0xFF)
122
123 #define TSL2X7X_MIN_ITIME 3
124
125 /* TAOS txx2x7x Device family members */
126 enum {
127         tsl2571,
128         tsl2671,
129         tmd2671,
130         tsl2771,
131         tmd2771,
132         tsl2572,
133         tsl2672,
134         tmd2672,
135         tsl2772,
136         tmd2772
137 };
138
139 enum {
140         TSL2X7X_CHIP_UNKNOWN = 0,
141         TSL2X7X_CHIP_WORKING = 1,
142         TSL2X7X_CHIP_SUSPENDED = 2
143 };
144
145 struct tsl2x7x_parse_result {
146         int integer;
147         int fract;
148 };
149
150 /* Per-device data */
151 struct tsl2x7x_als_info {
152         u16 als_ch0;
153         u16 als_ch1;
154         u16 lux;
155 };
156
157 struct tsl2x7x_prox_stat {
158         int min;
159         int max;
160         int mean;
161         unsigned long stddev;
162 };
163
164 struct tsl2x7x_chip_info {
165         int chan_table_elements;
166         struct iio_chan_spec            channel[4];
167         const struct iio_info           *info;
168 };
169
170 struct tsl2X7X_chip {
171         kernel_ulong_t id;
172         struct mutex prox_mutex;
173         struct mutex als_mutex;
174         struct i2c_client *client;
175         u16 prox_data;
176         struct tsl2x7x_als_info als_cur_info;
177         struct tsl2x7x_settings tsl2x7x_settings;
178         struct tsl2X7X_platform_data *pdata;
179         int als_time_scale;
180         int als_saturation;
181         int tsl2x7x_chip_status;
182         u8 tsl2x7x_config[TSL2X7X_MAX_CONFIG_REG];
183         const struct tsl2x7x_chip_info  *chip_info;
184         const struct iio_info *info;
185         s64 event_timestamp;
186         /*
187          * This structure is intentionally large to accommodate
188          * updates via sysfs.
189          * Sized to 9 = max 8 segments + 1 termination segment
190          */
191         struct tsl2x7x_lux tsl2x7x_device_lux[TSL2X7X_MAX_LUX_TABLE_SIZE];
192 };
193
194 /* Different devices require different coefficents */
195 static const struct tsl2x7x_lux tsl2x71_lux_table[] = {
196         { 14461,   611,   1211 },
197         { 18540,   352,    623 },
198         {     0,     0,      0 },
199 };
200
201 static const struct tsl2x7x_lux tmd2x71_lux_table[] = {
202         { 11635,   115,    256 },
203         { 15536,    87,    179 },
204         {     0,     0,      0 },
205 };
206
207 static const struct tsl2x7x_lux tsl2x72_lux_table[] = {
208         { 14013,   466,   917 },
209         { 18222,   310,   552 },
210         {     0,     0,     0 },
211 };
212
213 static const struct tsl2x7x_lux tmd2x72_lux_table[] = {
214         { 13218,   130,   262 },
215         { 17592,   92,    169 },
216         {     0,     0,     0 },
217 };
218
219 static const struct tsl2x7x_lux *tsl2x7x_default_lux_table_group[] = {
220         [tsl2571] =     tsl2x71_lux_table,
221         [tsl2671] =     tsl2x71_lux_table,
222         [tmd2671] =     tmd2x71_lux_table,
223         [tsl2771] =     tsl2x71_lux_table,
224         [tmd2771] =     tmd2x71_lux_table,
225         [tsl2572] =     tsl2x72_lux_table,
226         [tsl2672] =     tsl2x72_lux_table,
227         [tmd2672] =     tmd2x72_lux_table,
228         [tsl2772] =     tsl2x72_lux_table,
229         [tmd2772] =     tmd2x72_lux_table,
230 };
231
232 static const struct tsl2x7x_settings tsl2x7x_default_settings = {
233         .als_time = 219, /* 101 ms */
234         .als_gain = 0,
235         .prx_time = 254, /* 5.4 ms */
236         .prox_gain = 1,
237         .wait_time = 245,
238         .prox_config = 0,
239         .als_gain_trim = 1000,
240         .als_cal_target = 150,
241         .als_thresh_low = 200,
242         .als_thresh_high = 256,
243         .persistence = 255,
244         .interrupts_en = 0,
245         .prox_thres_low  = 0,
246         .prox_thres_high = 512,
247         .prox_max_samples_cal = 30,
248         .prox_pulse_count = 8
249 };
250
251 static const s16 tsl2X7X_als_gainadj[] = {
252         1,
253         8,
254         16,
255         120
256 };
257
258 static const s16 tsl2X7X_prx_gainadj[] = {
259         1,
260         2,
261         4,
262         8
263 };
264
265 /* Channel variations */
266 enum {
267         ALS,
268         PRX,
269         ALSPRX,
270         PRX2,
271         ALSPRX2,
272 };
273
274 static const u8 device_channel_config[] = {
275         ALS,
276         PRX,
277         PRX,
278         ALSPRX,
279         ALSPRX,
280         ALS,
281         PRX2,
282         PRX2,
283         ALSPRX2,
284         ALSPRX2
285 };
286
287 /**
288  * tsl2x7x_get_lux() - Reads and calculates current lux value.
289  * @indio_dev:  pointer to IIO device
290  *
291  * The raw ch0 and ch1 values of the ambient light sensed in the last
292  * integration cycle are read from the device.
293  * Time scale factor array values are adjusted based on the integration time.
294  * The raw values are multiplied by a scale factor, and device gain is obtained
295  * using gain index. Limit checks are done next, then the ratio of a multiple
296  * of ch1 value, to the ch0 value, is calculated. Array tsl2x7x_device_lux[]
297  * is then scanned to find the first ratio value that is just above the ratio
298  * we just calculated. The ch0 and ch1 multiplier constants in the array are
299  * then used along with the time scale factor array values, to calculate the
300  * lux.
301  */
302 static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
303 {
304         u16 ch0, ch1; /* separated ch0/ch1 data from device */
305         u32 lux; /* raw lux calculated from device data */
306         u64 lux64;
307         u32 ratio;
308         u8 buf[4];
309         struct tsl2x7x_lux *p;
310         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
311         int i, ret;
312         u32 ch0lux = 0;
313         u32 ch1lux = 0;
314
315         if (mutex_trylock(&chip->als_mutex) == 0)
316                 return chip->als_cur_info.lux; /* busy, so return LAST VALUE */
317
318         if (chip->tsl2x7x_chip_status != TSL2X7X_CHIP_WORKING) {
319                 /* device is not enabled */
320                 dev_err(&chip->client->dev, "%s: device is not enabled\n",
321                         __func__);
322                 ret = -EBUSY;
323                 goto out_unlock;
324         }
325
326         ret = i2c_smbus_read_byte_data(chip->client,
327                                        TSL2X7X_CMD_REG | TSL2X7X_STATUS);
328         if (ret < 0) {
329                 dev_err(&chip->client->dev,
330                         "%s: Failed to read STATUS Reg\n", __func__);
331                 goto out_unlock;
332         }
333         /* is data new & valid */
334         if (!(ret & TSL2X7X_STA_ADC_VALID)) {
335                 dev_err(&chip->client->dev,
336                         "%s: data not valid yet\n", __func__);
337                 ret = chip->als_cur_info.lux; /* return LAST VALUE */
338                 goto out_unlock;
339         }
340
341         for (i = 0; i < 4; i++) {
342                 int reg = TSL2X7X_CMD_REG | (TSL2X7X_ALS_CHAN0LO + i);
343
344                 ret = i2c_smbus_read_byte_data(chip->client, reg);
345                 if (ret < 0) {
346                         dev_err(&chip->client->dev,
347                                 "failed to read. err=%x\n", ret);
348                         goto out_unlock;
349                 }
350
351                 buf[i] = ret;
352         }
353
354         /* clear any existing interrupt status */
355         ret = i2c_smbus_write_byte(chip->client,
356                                    (TSL2X7X_CMD_REG |
357                                    TSL2X7X_CMD_SPL_FN |
358                                    TSL2X7X_CMD_ALS_INT_CLR));
359         if (ret < 0) {
360                 dev_err(&chip->client->dev,
361                         "i2c_write_command failed - err = %d\n", ret);
362                 goto out_unlock; /* have no data, so return failure */
363         }
364
365         /* extract ALS/lux data */
366         ch0 = le16_to_cpup((const __le16 *)&buf[0]);
367         ch1 = le16_to_cpup((const __le16 *)&buf[2]);
368
369         chip->als_cur_info.als_ch0 = ch0;
370         chip->als_cur_info.als_ch1 = ch1;
371
372         if ((ch0 >= chip->als_saturation) || (ch1 >= chip->als_saturation)) {
373                 lux = TSL2X7X_LUX_CALC_OVER_FLOW;
374                 goto return_max;
375         }
376
377         if (!ch0) {
378                 /* have no data, so return LAST VALUE */
379                 ret = chip->als_cur_info.lux;
380                 goto out_unlock;
381         }
382         /* calculate ratio */
383         ratio = (ch1 << 15) / ch0;
384         /* convert to unscaled lux using the pointer to the table */
385         p = (struct tsl2x7x_lux *)chip->tsl2x7x_device_lux;
386         while (p->ratio != 0 && p->ratio < ratio)
387                 p++;
388
389         if (p->ratio == 0) {
390                 lux = 0;
391         } else {
392                 ch0lux = DIV_ROUND_UP(ch0 * p->ch0,
393                         tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]);
394                 ch1lux = DIV_ROUND_UP(ch1 * p->ch1,
395                         tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]);
396                 lux = ch0lux - ch1lux;
397         }
398
399         /* note: lux is 31 bit max at this point */
400         if (ch1lux > ch0lux) {
401                 dev_dbg(&chip->client->dev, "ch1lux > ch0lux-return last value\n");
402                 ret = chip->als_cur_info.lux;
403                 goto out_unlock;
404         }
405
406         /* adjust for active time scale */
407         if (chip->als_time_scale == 0)
408                 lux = 0;
409         else
410                 lux = (lux + (chip->als_time_scale >> 1)) /
411                         chip->als_time_scale;
412
413         /* adjust for active gain scale
414          * The tsl2x7x_device_lux tables have a factor of 256 built-in.
415          * User-specified gain provides a multiplier.
416          * Apply user-specified gain before shifting right to retain precision.
417          * Use 64 bits to avoid overflow on multiplication.
418          * Then go back to 32 bits before division to avoid using div_u64().
419          */
420
421         lux64 = lux;
422         lux64 = lux64 * chip->tsl2x7x_settings.als_gain_trim;
423         lux64 >>= 8;
424         lux = lux64;
425         lux = (lux + 500) / 1000;
426
427         if (lux > TSL2X7X_LUX_CALC_OVER_FLOW) /* check for overflow */
428                 lux = TSL2X7X_LUX_CALC_OVER_FLOW;
429
430         /* Update the structure with the latest lux. */
431 return_max:
432         chip->als_cur_info.lux = lux;
433         ret = lux;
434
435 out_unlock:
436         mutex_unlock(&chip->als_mutex);
437
438         return ret;
439 }
440
441 /**
442  * tsl2x7x_get_prox() - Reads proximity data registers and updates
443  *                      chip->prox_data.
444  *
445  * @indio_dev:  pointer to IIO device
446  */
447 static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
448 {
449         int i;
450         int ret;
451         u8 chdata[2];
452         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
453
454         if (mutex_trylock(&chip->prox_mutex) == 0) {
455                 dev_err(&chip->client->dev,
456                         "%s: Can't get prox mutex\n", __func__);
457                 return -EBUSY;
458         }
459
460         ret = i2c_smbus_read_byte_data(chip->client,
461                                        TSL2X7X_CMD_REG | TSL2X7X_STATUS);
462         if (ret < 0) {
463                 dev_err(&chip->client->dev, "i2c err=%d\n", ret);
464                 goto prox_poll_err;
465         }
466
467         switch (chip->id) {
468         case tsl2571:
469         case tsl2671:
470         case tmd2671:
471         case tsl2771:
472         case tmd2771:
473                 if (!(ret & TSL2X7X_STA_ADC_VALID))
474                         goto prox_poll_err;
475         break;
476         case tsl2572:
477         case tsl2672:
478         case tmd2672:
479         case tsl2772:
480         case tmd2772:
481                 if (!(ret & TSL2X7X_STA_PRX_VALID))
482                         goto prox_poll_err;
483         break;
484         }
485
486         for (i = 0; i < 2; i++) {
487                 int reg = TSL2X7X_CMD_REG | (TSL2X7X_PRX_LO + i);
488
489                 ret = i2c_smbus_read_byte_data(chip->client, reg);
490                 if (ret < 0)
491                         goto prox_poll_err;
492
493                 chdata[i] = ret;
494         }
495
496         chip->prox_data =
497                         le16_to_cpup((const __le16 *)&chdata[0]);
498
499 prox_poll_err:
500
501         mutex_unlock(&chip->prox_mutex);
502
503         return chip->prox_data;
504 }
505
506 /**
507  * tsl2x7x_defaults() - Populates the device nominal operating parameters
508  *                      with those provided by a 'platform' data struct or
509  *                      with prefined defaults.
510  *
511  * @chip:               pointer to device structure.
512  */
513 static void tsl2x7x_defaults(struct tsl2X7X_chip *chip)
514 {
515         /* If Operational settings defined elsewhere.. */
516         if (chip->pdata && chip->pdata->platform_default_settings)
517                 memcpy(&chip->tsl2x7x_settings,
518                        chip->pdata->platform_default_settings,
519                        sizeof(tsl2x7x_default_settings));
520         else
521                 memcpy(&chip->tsl2x7x_settings,
522                        &tsl2x7x_default_settings,
523                        sizeof(tsl2x7x_default_settings));
524
525         /* Load up the proper lux table. */
526         if (chip->pdata && chip->pdata->platform_lux_table[0].ratio != 0)
527                 memcpy(chip->tsl2x7x_device_lux,
528                        chip->pdata->platform_lux_table,
529                        sizeof(chip->pdata->platform_lux_table));
530         else
531                 memcpy(chip->tsl2x7x_device_lux,
532                 (struct tsl2x7x_lux *)tsl2x7x_default_lux_table_group[chip->id],
533                                 MAX_DEFAULT_TABLE_BYTES);
534 }
535
536 /**
537  * tsl2x7x_als_calibrate() -    Obtain single reading and calculate
538  *                              the als_gain_trim.
539  *
540  * @indio_dev:  pointer to IIO device
541  */
542 static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev)
543 {
544         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
545         int gain_trim_val;
546         int ret;
547         int lux_val;
548
549         ret = i2c_smbus_read_byte_data(chip->client,
550                                        TSL2X7X_CMD_REG | TSL2X7X_CNTRL);
551         if (ret < 0) {
552                 dev_err(&chip->client->dev,
553                         "%s: failed to read from the CNTRL register\n",
554                         __func__);
555                 return ret;
556         }
557
558         if ((ret & (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON))
559                         != (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) {
560                 dev_err(&chip->client->dev,
561                         "%s: Device is not powered on and/or ADC is not enabled\n",
562                         __func__);
563                 return -EINVAL;
564         } else if ((ret & TSL2X7X_STA_ADC_VALID) != TSL2X7X_STA_ADC_VALID) {
565                 dev_err(&chip->client->dev,
566                         "%s: The two ADC channels have not completed an integration cycle\n",
567                         __func__);
568                 return -ENODATA;
569         }
570
571         lux_val = tsl2x7x_get_lux(indio_dev);
572         if (lux_val < 0) {
573                 dev_err(&chip->client->dev,
574                         "%s: failed to get lux\n", __func__);
575                 return lux_val;
576         }
577
578         gain_trim_val =  ((chip->tsl2x7x_settings.als_cal_target)
579                         * chip->tsl2x7x_settings.als_gain_trim) / lux_val;
580         if ((gain_trim_val < 250) || (gain_trim_val > 4000))
581                 return -ERANGE;
582
583         chip->tsl2x7x_settings.als_gain_trim = gain_trim_val;
584         dev_info(&chip->client->dev,
585                  "%s als_calibrate completed\n", chip->client->name);
586
587         return (int)gain_trim_val;
588 }
589
590 static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
591 {
592         int i;
593         int ret = 0;
594         u8 *dev_reg;
595         u8 utmp;
596         int als_count;
597         int als_time;
598         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
599         u8 reg_val = 0;
600
601         if (chip->pdata && chip->pdata->power_on)
602                 chip->pdata->power_on(indio_dev);
603
604         /* Non calculated parameters */
605         chip->tsl2x7x_config[TSL2X7X_PRX_TIME] =
606                         chip->tsl2x7x_settings.prx_time;
607         chip->tsl2x7x_config[TSL2X7X_WAIT_TIME] =
608                         chip->tsl2x7x_settings.wait_time;
609         chip->tsl2x7x_config[TSL2X7X_PRX_CONFIG] =
610                         chip->tsl2x7x_settings.prox_config;
611
612         chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHLO] =
613                 (chip->tsl2x7x_settings.als_thresh_low) & 0xFF;
614         chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHHI] =
615                 (chip->tsl2x7x_settings.als_thresh_low >> 8) & 0xFF;
616         chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHLO] =
617                 (chip->tsl2x7x_settings.als_thresh_high) & 0xFF;
618         chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHHI] =
619                 (chip->tsl2x7x_settings.als_thresh_high >> 8) & 0xFF;
620         chip->tsl2x7x_config[TSL2X7X_PERSISTENCE] =
621                 chip->tsl2x7x_settings.persistence;
622
623         chip->tsl2x7x_config[TSL2X7X_PRX_COUNT] =
624                         chip->tsl2x7x_settings.prox_pulse_count;
625         chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHLO] =
626                         (chip->tsl2x7x_settings.prox_thres_low) & 0xFF;
627         chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHHI] =
628                         (chip->tsl2x7x_settings.prox_thres_low >> 8) & 0xFF;
629         chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHLO] =
630                         (chip->tsl2x7x_settings.prox_thres_high) & 0xFF;
631         chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHHI] =
632                         (chip->tsl2x7x_settings.prox_thres_high >> 8) & 0xFF;
633
634         /* and make sure we're not already on */
635         if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
636                 /* if forcing a register update - turn off, then on */
637                 dev_info(&chip->client->dev, "device is already enabled\n");
638                 return -EINVAL;
639         }
640
641         /* determine als integration register */
642         als_count = (chip->tsl2x7x_settings.als_time * 100 + 135) / 270;
643         if (!als_count)
644                 als_count = 1; /* ensure at least one cycle */
645
646         /* convert back to time (encompasses overrides) */
647         als_time = (als_count * 27 + 5) / 10;
648         chip->tsl2x7x_config[TSL2X7X_ALS_TIME] = 256 - als_count;
649
650         /* Set the gain based on tsl2x7x_settings struct */
651         chip->tsl2x7x_config[TSL2X7X_GAIN] =
652                 chip->tsl2x7x_settings.als_gain |
653                         (TSL2X7X_mA100 | TSL2X7X_DIODE1)
654                         | ((chip->tsl2x7x_settings.prox_gain) << 2);
655
656         /* set chip struct re scaling and saturation */
657         chip->als_saturation = als_count * 922; /* 90% of full scale */
658         chip->als_time_scale = (als_time + 25) / 50;
659
660         /*
661          * TSL2X7X Specific power-on / adc enable sequence
662          * Power on the device 1st.
663          */
664         utmp = TSL2X7X_CNTL_PWR_ON;
665         ret = i2c_smbus_write_byte_data(chip->client,
666                                         TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp);
667         if (ret < 0) {
668                 dev_err(&chip->client->dev,
669                         "%s: failed on CNTRL reg.\n", __func__);
670                 return ret;
671         }
672
673         /*
674          * Use the following shadow copy for our delay before enabling ADC.
675          * Write all the registers.
676          */
677         for (i = 0, dev_reg = chip->tsl2x7x_config;
678                         i < TSL2X7X_MAX_CONFIG_REG; i++) {
679                 ret = i2c_smbus_write_byte_data(chip->client,
680                                                 TSL2X7X_CMD_REG + i,
681                                                 *dev_reg++);
682                 if (ret < 0) {
683                         dev_err(&chip->client->dev,
684                                 "failed on write to reg %d.\n", i);
685                         return ret;
686                 }
687         }
688
689         /* Power-on settling time */
690         usleep_range(3000, 3500);
691
692         /*
693          * NOW enable the ADC
694          * initialize the desired mode of operation
695          */
696         utmp = TSL2X7X_CNTL_PWR_ON |
697                         TSL2X7X_CNTL_ADC_ENBL |
698                         TSL2X7X_CNTL_PROX_DET_ENBL;
699         ret = i2c_smbus_write_byte_data(chip->client,
700                                         TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp);
701         if (ret < 0) {
702                 dev_err(&chip->client->dev,
703                         "%s: failed on 2nd CTRL reg.\n", __func__);
704                 return ret;
705         }
706
707         chip->tsl2x7x_chip_status = TSL2X7X_CHIP_WORKING;
708
709         if (chip->tsl2x7x_settings.interrupts_en != 0) {
710                 dev_info(&chip->client->dev, "Setting Up Interrupt(s)\n");
711
712                 reg_val = TSL2X7X_CNTL_PWR_ON | TSL2X7X_CNTL_ADC_ENBL;
713                 if ((chip->tsl2x7x_settings.interrupts_en == 0x20) ||
714                     (chip->tsl2x7x_settings.interrupts_en == 0x30))
715                         reg_val |= TSL2X7X_CNTL_PROX_DET_ENBL;
716
717                 reg_val |= chip->tsl2x7x_settings.interrupts_en;
718                 ret = i2c_smbus_write_byte_data(chip->client,
719                                                 (TSL2X7X_CMD_REG |
720                                                 TSL2X7X_CNTRL), reg_val);
721                 if (ret < 0)
722                         dev_err(&chip->client->dev,
723                                 "%s: failed in tsl2x7x_IOCTL_INT_SET.\n",
724                                 __func__);
725
726                 /* Clear out any initial interrupts  */
727                 ret = i2c_smbus_write_byte(chip->client,
728                                            TSL2X7X_CMD_REG |
729                                            TSL2X7X_CMD_SPL_FN |
730                                            TSL2X7X_CMD_PROXALS_INT_CLR);
731                 if (ret < 0) {
732                         dev_err(&chip->client->dev,
733                                 "%s: Failed to clear Int status\n",
734                                 __func__);
735                 return ret;
736                 }
737         }
738
739         return ret;
740 }
741
742 static int tsl2x7x_chip_off(struct iio_dev *indio_dev)
743 {
744         int ret;
745         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
746
747         /* turn device off */
748         chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED;
749
750         ret = i2c_smbus_write_byte_data(chip->client,
751                                         TSL2X7X_CMD_REG | TSL2X7X_CNTRL, 0x00);
752
753         if (chip->pdata && chip->pdata->power_off)
754                 chip->pdata->power_off(chip->client);
755
756         return ret;
757 }
758
759 /**
760  * tsl2x7x_invoke_change
761  * @indio_dev:  pointer to IIO device
762  *
763  * Obtain and lock both ALS and PROX resources,
764  * determine and save device state (On/Off),
765  * cycle device to implement updated parameter,
766  * put device back into proper state, and unlock
767  * resource.
768  */
769 static
770 int tsl2x7x_invoke_change(struct iio_dev *indio_dev)
771 {
772         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
773         int device_status = chip->tsl2x7x_chip_status;
774         int ret;
775
776         mutex_lock(&chip->als_mutex);
777         mutex_lock(&chip->prox_mutex);
778
779         if (device_status == TSL2X7X_CHIP_WORKING) {
780                 ret = tsl2x7x_chip_off(indio_dev);
781                 if (ret < 0)
782                         goto unlock;
783         }
784
785         ret = tsl2x7x_chip_on(indio_dev);
786
787 unlock:
788         mutex_unlock(&chip->prox_mutex);
789         mutex_unlock(&chip->als_mutex);
790
791         return ret;
792 }
793
794 static
795 void tsl2x7x_prox_calculate(int *data, int length,
796                             struct tsl2x7x_prox_stat *statP)
797 {
798         int i;
799         int sample_sum;
800         int tmp;
801
802         if (!length)
803                 length = 1;
804
805         sample_sum = 0;
806         statP->min = INT_MAX;
807         statP->max = INT_MIN;
808         for (i = 0; i < length; i++) {
809                 sample_sum += data[i];
810                 statP->min = min(statP->min, data[i]);
811                 statP->max = max(statP->max, data[i]);
812         }
813
814         statP->mean = sample_sum / length;
815         sample_sum = 0;
816         for (i = 0; i < length; i++) {
817                 tmp = data[i] - statP->mean;
818                 sample_sum += tmp * tmp;
819         }
820         statP->stddev = int_sqrt((long)sample_sum / length);
821 }
822
823 /**
824  * tsl2x7x_prox_cal() - Calculates std. and sets thresholds.
825  * @indio_dev:  pointer to IIO device
826  *
827  * Calculates a standard deviation based on the samples,
828  * and sets the threshold accordingly.
829  */
830 static void tsl2x7x_prox_cal(struct iio_dev *indio_dev)
831 {
832         int prox_history[MAX_SAMPLES_CAL + 1];
833         int i;
834         struct tsl2x7x_prox_stat prox_stat_data[2];
835         struct tsl2x7x_prox_stat *calP;
836         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
837         u8 tmp_irq_settings;
838         u8 current_state = chip->tsl2x7x_chip_status;
839
840         if (chip->tsl2x7x_settings.prox_max_samples_cal > MAX_SAMPLES_CAL) {
841                 dev_err(&chip->client->dev,
842                         "max prox samples cal is too big: %d\n",
843                         chip->tsl2x7x_settings.prox_max_samples_cal);
844                 chip->tsl2x7x_settings.prox_max_samples_cal = MAX_SAMPLES_CAL;
845         }
846
847         /* have to stop to change settings */
848         tsl2x7x_chip_off(indio_dev);
849
850         /* Enable proximity detection save just in case prox not wanted yet*/
851         tmp_irq_settings = chip->tsl2x7x_settings.interrupts_en;
852         chip->tsl2x7x_settings.interrupts_en |= TSL2X7X_CNTL_PROX_INT_ENBL;
853
854         /*turn on device if not already on*/
855         tsl2x7x_chip_on(indio_dev);
856
857         /*gather the samples*/
858         for (i = 0; i < chip->tsl2x7x_settings.prox_max_samples_cal; i++) {
859                 usleep_range(15000, 17500);
860                 tsl2x7x_get_prox(indio_dev);
861                 prox_history[i] = chip->prox_data;
862                 dev_info(&chip->client->dev, "2 i=%d prox data= %d\n",
863                          i, chip->prox_data);
864         }
865
866         tsl2x7x_chip_off(indio_dev);
867         calP = &prox_stat_data[PROX_STAT_CAL];
868         tsl2x7x_prox_calculate(prox_history,
869                                chip->tsl2x7x_settings.prox_max_samples_cal,
870                                calP);
871         chip->tsl2x7x_settings.prox_thres_high = (calP->max << 1) - calP->mean;
872
873         dev_info(&chip->client->dev, " cal min=%d mean=%d max=%d\n",
874                  calP->min, calP->mean, calP->max);
875         dev_info(&chip->client->dev,
876                  "%s proximity threshold set to %d\n",
877                  chip->client->name, chip->tsl2x7x_settings.prox_thres_high);
878
879         /* back to the way they were */
880         chip->tsl2x7x_settings.interrupts_en = tmp_irq_settings;
881         if (current_state == TSL2X7X_CHIP_WORKING)
882                 tsl2x7x_chip_on(indio_dev);
883 }
884
885 static ssize_t in_illuminance0_calibscale_available_show(struct device *dev,
886                                            struct device_attribute *attr,
887                                            char *buf)
888 {
889         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
890
891         switch (chip->id) {
892         case tsl2571:
893         case tsl2671:
894         case tmd2671:
895         case tsl2771:
896         case tmd2771:
897                 return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128");
898         }
899
900         return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
901 }
902
903 static ssize_t in_proximity0_calibscale_available_show(struct device *dev,
904                                                 struct device_attribute *attr,
905                                                 char *buf)
906 {
907                 return snprintf(buf, PAGE_SIZE, "%s\n", "1 2 4 8");
908 }
909
910 static ssize_t in_illuminance0_integration_time_show(struct device *dev,
911                                      struct device_attribute *attr,
912                                      char *buf)
913 {
914         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
915         int y, z;
916
917         y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
918         z = y * TSL2X7X_MIN_ITIME;
919         y /= 1000;
920         z %= 1000;
921
922         return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
923 }
924
925 static ssize_t in_illuminance0_integration_time_store(struct device *dev,
926                                       struct device_attribute *attr,
927                                       const char *buf, size_t len)
928 {
929         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
930         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
931         struct tsl2x7x_parse_result result;
932         int ret;
933
934         ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
935         if (ret)
936                 return ret;
937
938         result.fract /= 3;
939         chip->tsl2x7x_settings.als_time =
940                         TSL2X7X_MAX_TIMER_CNT - (u8)result.fract;
941
942         dev_info(&chip->client->dev, "%s: als time = %d",
943                  __func__, chip->tsl2x7x_settings.als_time);
944
945         tsl2x7x_invoke_change(indio_dev);
946
947         return IIO_VAL_INT_PLUS_MICRO;
948 }
949
950 static IIO_CONST_ATTR(in_illuminance0_integration_time_available,
951                 ".00272 - .696");
952
953 static ssize_t in_illuminance0_target_input_show(struct device *dev,
954                                            struct device_attribute *attr,
955                                            char *buf)
956 {
957         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
958
959         return snprintf(buf, PAGE_SIZE, "%d\n",
960                         chip->tsl2x7x_settings.als_cal_target);
961 }
962
963 static ssize_t in_illuminance0_target_input_store(struct device *dev,
964                                             struct device_attribute *attr,
965                                             const char *buf, size_t len)
966 {
967         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
968         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
969         unsigned long value;
970         int ret;
971
972         if (kstrtoul(buf, 0, &value))
973                 return -EINVAL;
974
975         if (value)
976                 chip->tsl2x7x_settings.als_cal_target = value;
977
978         ret = tsl2x7x_invoke_change(indio_dev);
979         if (ret < 0)
980                 return ret;
981
982         return len;
983 }
984
985 /* persistence settings */
986 static ssize_t in_intensity0_thresh_period_show(struct device *dev,
987                                             struct device_attribute *attr,
988                                             char *buf)
989 {
990         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
991         int y, z, filter_delay;
992
993         /* Determine integration time */
994         y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
995         z = y * TSL2X7X_MIN_ITIME;
996         filter_delay = z * (chip->tsl2x7x_settings.persistence & 0x0F);
997         y = filter_delay / 1000;
998         z = filter_delay % 1000;
999
1000         return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
1001 }
1002
1003 static ssize_t in_intensity0_thresh_period_store(struct device *dev,
1004                                              struct device_attribute *attr,
1005                                              const char *buf, size_t len)
1006 {
1007         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1008         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1009         struct tsl2x7x_parse_result result;
1010         int y, z, filter_delay;
1011         int ret;
1012
1013         ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
1014         if (ret)
1015                 return ret;
1016
1017         y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
1018         z = y * TSL2X7X_MIN_ITIME;
1019
1020         filter_delay =
1021                 DIV_ROUND_UP((result.integer * 1000) + result.fract, z);
1022
1023         chip->tsl2x7x_settings.persistence &= 0xF0;
1024         chip->tsl2x7x_settings.persistence |= (filter_delay & 0x0F);
1025
1026         dev_info(&chip->client->dev, "%s: als persistence = %d",
1027                  __func__, filter_delay);
1028
1029         ret = tsl2x7x_invoke_change(indio_dev);
1030         if (ret < 0)
1031                 return ret;
1032
1033         return IIO_VAL_INT_PLUS_MICRO;
1034 }
1035
1036 static ssize_t in_proximity0_thresh_period_show(struct device *dev,
1037                                              struct device_attribute *attr,
1038                                              char *buf)
1039 {
1040         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
1041         int y, z, filter_delay;
1042
1043         /* Determine integration time */
1044         y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1;
1045         z = y * TSL2X7X_MIN_ITIME;
1046         filter_delay = z * ((chip->tsl2x7x_settings.persistence & 0xF0) >> 4);
1047         y = filter_delay / 1000;
1048         z = filter_delay % 1000;
1049
1050         return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
1051 }
1052
1053 static ssize_t in_proximity0_thresh_period_store(struct device *dev,
1054                                               struct device_attribute *attr,
1055                                               const char *buf, size_t len)
1056 {
1057         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1058         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1059         struct tsl2x7x_parse_result result;
1060         int y, z, filter_delay;
1061         int ret;
1062
1063         ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
1064         if (ret)
1065                 return ret;
1066
1067         y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1;
1068         z = y * TSL2X7X_MIN_ITIME;
1069
1070         filter_delay =
1071                 DIV_ROUND_UP((result.integer * 1000) + result.fract, z);
1072
1073         chip->tsl2x7x_settings.persistence &= 0x0F;
1074         chip->tsl2x7x_settings.persistence |= ((filter_delay << 4) & 0xF0);
1075
1076         dev_info(&chip->client->dev, "%s: prox persistence = %d",
1077                  __func__, filter_delay);
1078
1079         ret = tsl2x7x_invoke_change(indio_dev);
1080         if (ret < 0)
1081                 return ret;
1082
1083
1084         return IIO_VAL_INT_PLUS_MICRO;
1085 }
1086
1087 static ssize_t in_illuminance0_calibrate_store(struct device *dev,
1088                                     struct device_attribute *attr,
1089                                     const char *buf, size_t len)
1090 {
1091         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1092         bool value;
1093         int ret;
1094
1095         if (strtobool(buf, &value))
1096                 return -EINVAL;
1097
1098         if (value)
1099                 tsl2x7x_als_calibrate(indio_dev);
1100
1101         ret = tsl2x7x_invoke_change(indio_dev);
1102         if (ret < 0)
1103                 return ret;
1104
1105         return len;
1106 }
1107
1108 static ssize_t in_illuminance0_lux_table_show(struct device *dev,
1109                                      struct device_attribute *attr,
1110                                      char *buf)
1111 {
1112         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
1113         int i = 0;
1114         int offset = 0;
1115
1116         while (i < (TSL2X7X_MAX_LUX_TABLE_SIZE * 3)) {
1117                 offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,%u,",
1118                         chip->tsl2x7x_device_lux[i].ratio,
1119                         chip->tsl2x7x_device_lux[i].ch0,
1120                         chip->tsl2x7x_device_lux[i].ch1);
1121                 if (chip->tsl2x7x_device_lux[i].ratio == 0) {
1122                         /*
1123                          * We just printed the first "0" entry.
1124                          * Now get rid of the extra "," and break.
1125                          */
1126                         offset--;
1127                         break;
1128                 }
1129                 i++;
1130         }
1131
1132         offset += snprintf(buf + offset, PAGE_SIZE, "\n");
1133         return offset;
1134 }
1135
1136 static ssize_t in_illuminance0_lux_table_store(struct device *dev,
1137                                       struct device_attribute *attr,
1138                                       const char *buf, size_t len)
1139 {
1140         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1141         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1142         int value[ARRAY_SIZE(chip->tsl2x7x_device_lux) * 3 + 1];
1143         int n, ret;
1144
1145         get_options(buf, ARRAY_SIZE(value), value);
1146
1147         /* We now have an array of ints starting at value[1], and
1148          * enumerated by value[0].
1149          * We expect each group of three ints is one table entry,
1150          * and the last table entry is all 0.
1151          */
1152         n = value[0];
1153         if ((n % 3) || n < 6 ||
1154             n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 3)) {
1155                 dev_info(dev, "LUX TABLE INPUT ERROR 1 Value[0]=%d\n", n);
1156                 return -EINVAL;
1157         }
1158
1159         if ((value[(n - 2)] | value[(n - 1)] | value[n]) != 0) {
1160                 dev_info(dev, "LUX TABLE INPUT ERROR 2 Value[0]=%d\n", n);
1161                 return -EINVAL;
1162         }
1163
1164         if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING)
1165                 tsl2x7x_chip_off(indio_dev);
1166
1167         /* Zero out the table */
1168         memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux));
1169         memcpy(chip->tsl2x7x_device_lux, &value[1], (value[0] * 4));
1170
1171         ret = tsl2x7x_invoke_change(indio_dev);
1172         if (ret < 0)
1173                 return ret;
1174
1175         return len;
1176 }
1177
1178 static ssize_t in_proximity0_calibrate_store(struct device *dev,
1179                                          struct device_attribute *attr,
1180                                          const char *buf, size_t len)
1181 {
1182         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1183         bool value;
1184         int ret;
1185
1186         if (strtobool(buf, &value))
1187                 return -EINVAL;
1188
1189         if (value)
1190                 tsl2x7x_prox_cal(indio_dev);
1191
1192         ret = tsl2x7x_invoke_change(indio_dev);
1193         if (ret < 0)
1194                 return ret;
1195
1196         return len;
1197 }
1198
1199 static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
1200                                          const struct iio_chan_spec *chan,
1201                                          enum iio_event_type type,
1202                                          enum iio_event_direction dir)
1203 {
1204         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1205         int ret;
1206
1207         if (chan->type == IIO_INTENSITY)
1208                 ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x10);
1209         else
1210                 ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x20);
1211
1212         return ret;
1213 }
1214
1215 static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
1216                                           const struct iio_chan_spec *chan,
1217                                           enum iio_event_type type,
1218                                           enum iio_event_direction dir,
1219                                           int val)
1220 {
1221         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1222         int ret;
1223
1224         if (chan->type == IIO_INTENSITY) {
1225                 if (val)
1226                         chip->tsl2x7x_settings.interrupts_en |= 0x10;
1227                 else
1228                         chip->tsl2x7x_settings.interrupts_en &= 0x20;
1229         } else {
1230                 if (val)
1231                         chip->tsl2x7x_settings.interrupts_en |= 0x20;
1232                 else
1233                         chip->tsl2x7x_settings.interrupts_en &= 0x10;
1234         }
1235
1236         ret = tsl2x7x_invoke_change(indio_dev);
1237         if (ret < 0)
1238                 return ret;
1239
1240         return 0;
1241 }
1242
1243 static int tsl2x7x_write_event_value(struct iio_dev *indio_dev,
1244                                      const struct iio_chan_spec *chan,
1245                                      enum iio_event_type type,
1246                                      enum iio_event_direction dir,
1247                                      enum iio_event_info info,
1248                                      int val, int val2)
1249 {
1250         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1251         int ret = -EINVAL;
1252
1253         switch (info) {
1254         case IIO_EV_INFO_VALUE:
1255                 if (chan->type == IIO_INTENSITY) {
1256                         switch (dir) {
1257                         case IIO_EV_DIR_RISING:
1258                                 chip->tsl2x7x_settings.als_thresh_high = val;
1259                                 ret = 0;
1260                                 break;
1261                         case IIO_EV_DIR_FALLING:
1262                                 chip->tsl2x7x_settings.als_thresh_low = val;
1263                                 ret = 0;
1264                                 break;
1265                         default:
1266                                 break;
1267                         }
1268                 } else {
1269                         switch (dir) {
1270                         case IIO_EV_DIR_RISING:
1271                                 chip->tsl2x7x_settings.prox_thres_high = val;
1272                                 ret = 0;
1273                                 break;
1274                         case IIO_EV_DIR_FALLING:
1275                                 chip->tsl2x7x_settings.prox_thres_low = val;
1276                                 ret = 0;
1277                                 break;
1278                         default:
1279                                 break;
1280                         }
1281                 }
1282                 break;
1283         default:
1284                 break;
1285         }
1286
1287         if (ret < 0)
1288                 return ret;
1289
1290         return tsl2x7x_invoke_change(indio_dev);
1291 }
1292
1293 static int tsl2x7x_read_event_value(struct iio_dev *indio_dev,
1294                                     const struct iio_chan_spec *chan,
1295                                     enum iio_event_type type,
1296                                     enum iio_event_direction dir,
1297                                     enum iio_event_info info,
1298                                     int *val, int *val2)
1299 {
1300         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1301         int ret = -EINVAL;
1302
1303         switch (info) {
1304         case IIO_EV_INFO_VALUE:
1305                 if (chan->type == IIO_INTENSITY) {
1306                         switch (dir) {
1307                         case IIO_EV_DIR_RISING:
1308                                 *val = chip->tsl2x7x_settings.als_thresh_high;
1309                                 ret = IIO_VAL_INT;
1310                                 break;
1311                         case IIO_EV_DIR_FALLING:
1312                                 *val = chip->tsl2x7x_settings.als_thresh_low;
1313                                 ret = IIO_VAL_INT;
1314                                 break;
1315                         default:
1316                                 break;
1317                         }
1318                 } else {
1319                         switch (dir) {
1320                         case IIO_EV_DIR_RISING:
1321                                 *val = chip->tsl2x7x_settings.prox_thres_high;
1322                                 ret = IIO_VAL_INT;
1323                                 break;
1324                         case IIO_EV_DIR_FALLING:
1325                                 *val = chip->tsl2x7x_settings.prox_thres_low;
1326                                 ret = IIO_VAL_INT;
1327                                 break;
1328                         default:
1329                                 break;
1330                         }
1331                 }
1332                 break;
1333         default:
1334                 break;
1335         }
1336
1337         return ret;
1338 }
1339
1340 static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
1341                             struct iio_chan_spec const *chan,
1342                             int *val,
1343                             int *val2,
1344                             long mask)
1345 {
1346         int ret = -EINVAL;
1347         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1348
1349         switch (mask) {
1350         case IIO_CHAN_INFO_PROCESSED:
1351                 switch (chan->type) {
1352                 case IIO_LIGHT:
1353                         tsl2x7x_get_lux(indio_dev);
1354                         *val = chip->als_cur_info.lux;
1355                         ret = IIO_VAL_INT;
1356                         break;
1357                 default:
1358                         return -EINVAL;
1359                 }
1360                 break;
1361         case IIO_CHAN_INFO_RAW:
1362                 switch (chan->type) {
1363                 case IIO_INTENSITY:
1364                         tsl2x7x_get_lux(indio_dev);
1365                         if (chan->channel == 0)
1366                                 *val = chip->als_cur_info.als_ch0;
1367                         else
1368                                 *val = chip->als_cur_info.als_ch1;
1369                         ret = IIO_VAL_INT;
1370                         break;
1371                 case IIO_PROXIMITY:
1372                         tsl2x7x_get_prox(indio_dev);
1373                         *val = chip->prox_data;
1374                         ret = IIO_VAL_INT;
1375                         break;
1376                 default:
1377                         return -EINVAL;
1378                 }
1379                 break;
1380         case IIO_CHAN_INFO_CALIBSCALE:
1381                 if (chan->type == IIO_LIGHT)
1382                         *val =
1383                         tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain];
1384                 else
1385                         *val =
1386                         tsl2X7X_prx_gainadj[chip->tsl2x7x_settings.prox_gain];
1387                 ret = IIO_VAL_INT;
1388                 break;
1389         case IIO_CHAN_INFO_CALIBBIAS:
1390                 *val = chip->tsl2x7x_settings.als_gain_trim;
1391                 ret = IIO_VAL_INT;
1392                 break;
1393
1394         default:
1395                 ret = -EINVAL;
1396         }
1397
1398         return ret;
1399 }
1400
1401 static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
1402                              struct iio_chan_spec const *chan,
1403                              int val,
1404                              int val2,
1405                              long mask)
1406 {
1407         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1408
1409         switch (mask) {
1410         case IIO_CHAN_INFO_CALIBSCALE:
1411                 if (chan->type == IIO_INTENSITY) {
1412                         switch (val) {
1413                         case 1:
1414                                 chip->tsl2x7x_settings.als_gain = 0;
1415                                 break;
1416                         case 8:
1417                                 chip->tsl2x7x_settings.als_gain = 1;
1418                                 break;
1419                         case 16:
1420                                 chip->tsl2x7x_settings.als_gain = 2;
1421                                 break;
1422                         case 120:
1423                                 switch (chip->id) {
1424                                 case tsl2572:
1425                                 case tsl2672:
1426                                 case tmd2672:
1427                                 case tsl2772:
1428                                 case tmd2772:
1429                                         return -EINVAL;
1430                                 }
1431                                 chip->tsl2x7x_settings.als_gain = 3;
1432                                 break;
1433                         case 128:
1434                                 switch (chip->id) {
1435                                 case tsl2571:
1436                                 case tsl2671:
1437                                 case tmd2671:
1438                                 case tsl2771:
1439                                 case tmd2771:
1440                                         return -EINVAL;
1441                                 }
1442                                 chip->tsl2x7x_settings.als_gain = 3;
1443                                 break;
1444                         default:
1445                                 return -EINVAL;
1446                         }
1447                 } else {
1448                         switch (val) {
1449                         case 1:
1450                                 chip->tsl2x7x_settings.prox_gain = 0;
1451                                 break;
1452                         case 2:
1453                                 chip->tsl2x7x_settings.prox_gain = 1;
1454                                 break;
1455                         case 4:
1456                                 chip->tsl2x7x_settings.prox_gain = 2;
1457                                 break;
1458                         case 8:
1459                                 chip->tsl2x7x_settings.prox_gain = 3;
1460                                 break;
1461                         default:
1462                                 return -EINVAL;
1463                         }
1464                 }
1465                 break;
1466         case IIO_CHAN_INFO_CALIBBIAS:
1467                 chip->tsl2x7x_settings.als_gain_trim = val;
1468                 break;
1469
1470         default:
1471                 return -EINVAL;
1472         }
1473
1474         return tsl2x7x_invoke_change(indio_dev);
1475 }
1476
1477 static DEVICE_ATTR_RO(in_proximity0_calibscale_available);
1478
1479 static DEVICE_ATTR_RO(in_illuminance0_calibscale_available);
1480
1481 static DEVICE_ATTR_RW(in_illuminance0_integration_time);
1482
1483 static DEVICE_ATTR_RW(in_illuminance0_target_input);
1484
1485 static DEVICE_ATTR_WO(in_illuminance0_calibrate);
1486
1487 static DEVICE_ATTR_WO(in_proximity0_calibrate);
1488
1489 static DEVICE_ATTR_RW(in_illuminance0_lux_table);
1490
1491 static DEVICE_ATTR_RW(in_intensity0_thresh_period);
1492
1493 static DEVICE_ATTR_RW(in_proximity0_thresh_period);
1494
1495 /* Use the default register values to identify the Taos device */
1496 static int tsl2x7x_device_id(int *id, int target)
1497 {
1498         switch (target) {
1499         case tsl2571:
1500         case tsl2671:
1501         case tsl2771:
1502                 return (*id & 0xf0) == TRITON_ID;
1503         case tmd2671:
1504         case tmd2771:
1505                 return (*id & 0xf0) == HALIBUT_ID;
1506         case tsl2572:
1507         case tsl2672:
1508         case tmd2672:
1509         case tsl2772:
1510         case tmd2772:
1511                 return (*id & 0xf0) == SWORDFISH_ID;
1512         }
1513
1514         return -EINVAL;
1515 }
1516
1517 static irqreturn_t tsl2x7x_event_handler(int irq, void *private)
1518 {
1519         struct iio_dev *indio_dev = private;
1520         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1521         s64 timestamp = iio_get_time_ns(indio_dev);
1522         int ret;
1523         u8 value;
1524
1525         value = i2c_smbus_read_byte_data(chip->client,
1526                                          TSL2X7X_CMD_REG | TSL2X7X_STATUS);
1527
1528         /* What type of interrupt do we need to process */
1529         if (value & TSL2X7X_STA_PRX_INTR) {
1530                 tsl2x7x_get_prox(indio_dev); /* freshen data for ABI */
1531                 iio_push_event(indio_dev,
1532                                IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
1533                                                     0,
1534                                                     IIO_EV_TYPE_THRESH,
1535                                                     IIO_EV_DIR_EITHER),
1536                                                     timestamp);
1537         }
1538
1539         if (value & TSL2X7X_STA_ALS_INTR) {
1540                 tsl2x7x_get_lux(indio_dev); /* freshen data for ABI */
1541                 iio_push_event(indio_dev,
1542                                IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
1543                                                     0,
1544                                                     IIO_EV_TYPE_THRESH,
1545                                                     IIO_EV_DIR_EITHER),
1546                                timestamp);
1547         }
1548         /* Clear interrupt now that we have handled it. */
1549         ret = i2c_smbus_write_byte(chip->client,
1550                                    TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN |
1551                                    TSL2X7X_CMD_PROXALS_INT_CLR);
1552         if (ret < 0)
1553                 dev_err(&chip->client->dev,
1554                         "Failed to clear irq from event handler. err = %d\n",
1555                         ret);
1556
1557         return IRQ_HANDLED;
1558 }
1559
1560 static struct attribute *tsl2x7x_ALS_device_attrs[] = {
1561         &dev_attr_in_illuminance0_calibscale_available.attr,
1562         &dev_attr_in_illuminance0_integration_time.attr,
1563         &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr,
1564         &dev_attr_in_illuminance0_target_input.attr,
1565         &dev_attr_in_illuminance0_calibrate.attr,
1566         &dev_attr_in_illuminance0_lux_table.attr,
1567         NULL
1568 };
1569
1570 static struct attribute *tsl2x7x_PRX_device_attrs[] = {
1571         &dev_attr_in_proximity0_calibrate.attr,
1572         NULL
1573 };
1574
1575 static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = {
1576         &dev_attr_in_illuminance0_calibscale_available.attr,
1577         &dev_attr_in_illuminance0_integration_time.attr,
1578         &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr,
1579         &dev_attr_in_illuminance0_target_input.attr,
1580         &dev_attr_in_illuminance0_calibrate.attr,
1581         &dev_attr_in_illuminance0_lux_table.attr,
1582         &dev_attr_in_proximity0_calibrate.attr,
1583         NULL
1584 };
1585
1586 static struct attribute *tsl2x7x_PRX2_device_attrs[] = {
1587         &dev_attr_in_proximity0_calibrate.attr,
1588         &dev_attr_in_proximity0_calibscale_available.attr,
1589         NULL
1590 };
1591
1592 static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = {
1593         &dev_attr_in_illuminance0_calibscale_available.attr,
1594         &dev_attr_in_illuminance0_integration_time.attr,
1595         &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr,
1596         &dev_attr_in_illuminance0_target_input.attr,
1597         &dev_attr_in_illuminance0_calibrate.attr,
1598         &dev_attr_in_illuminance0_lux_table.attr,
1599         &dev_attr_in_proximity0_calibrate.attr,
1600         &dev_attr_in_proximity0_calibscale_available.attr,
1601         NULL
1602 };
1603
1604 static struct attribute *tsl2X7X_ALS_event_attrs[] = {
1605         &dev_attr_in_intensity0_thresh_period.attr,
1606         NULL,
1607 };
1608
1609 static struct attribute *tsl2X7X_PRX_event_attrs[] = {
1610         &dev_attr_in_proximity0_thresh_period.attr,
1611         NULL,
1612 };
1613
1614 static struct attribute *tsl2X7X_ALSPRX_event_attrs[] = {
1615         &dev_attr_in_intensity0_thresh_period.attr,
1616         &dev_attr_in_proximity0_thresh_period.attr,
1617         NULL,
1618 };
1619
1620 static const struct attribute_group tsl2X7X_device_attr_group_tbl[] = {
1621         [ALS] = {
1622                 .attrs = tsl2x7x_ALS_device_attrs,
1623         },
1624         [PRX] = {
1625                 .attrs = tsl2x7x_PRX_device_attrs,
1626         },
1627         [ALSPRX] = {
1628                 .attrs = tsl2x7x_ALSPRX_device_attrs,
1629         },
1630         [PRX2] = {
1631                 .attrs = tsl2x7x_PRX2_device_attrs,
1632         },
1633         [ALSPRX2] = {
1634                 .attrs = tsl2x7x_ALSPRX2_device_attrs,
1635         },
1636 };
1637
1638 static const struct attribute_group tsl2X7X_event_attr_group_tbl[] = {
1639         [ALS] = {
1640                 .attrs = tsl2X7X_ALS_event_attrs,
1641                 .name = "events",
1642         },
1643         [PRX] = {
1644                 .attrs = tsl2X7X_PRX_event_attrs,
1645                 .name = "events",
1646         },
1647         [ALSPRX] = {
1648                 .attrs = tsl2X7X_ALSPRX_event_attrs,
1649                 .name = "events",
1650         },
1651 };
1652
1653 static const struct iio_info tsl2X7X_device_info[] = {
1654         [ALS] = {
1655                 .attrs = &tsl2X7X_device_attr_group_tbl[ALS],
1656                 .event_attrs = &tsl2X7X_event_attr_group_tbl[ALS],
1657                 .driver_module = THIS_MODULE,
1658                 .read_raw = &tsl2x7x_read_raw,
1659                 .write_raw = &tsl2x7x_write_raw,
1660                 .read_event_value = &tsl2x7x_read_event_value,
1661                 .write_event_value = &tsl2x7x_write_event_value,
1662                 .read_event_config = &tsl2x7x_read_interrupt_config,
1663                 .write_event_config = &tsl2x7x_write_interrupt_config,
1664         },
1665         [PRX] = {
1666                 .attrs = &tsl2X7X_device_attr_group_tbl[PRX],
1667                 .event_attrs = &tsl2X7X_event_attr_group_tbl[PRX],
1668                 .driver_module = THIS_MODULE,
1669                 .read_raw = &tsl2x7x_read_raw,
1670                 .write_raw = &tsl2x7x_write_raw,
1671                 .read_event_value = &tsl2x7x_read_event_value,
1672                 .write_event_value = &tsl2x7x_write_event_value,
1673                 .read_event_config = &tsl2x7x_read_interrupt_config,
1674                 .write_event_config = &tsl2x7x_write_interrupt_config,
1675         },
1676         [ALSPRX] = {
1677                 .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX],
1678                 .event_attrs = &tsl2X7X_event_attr_group_tbl[ALSPRX],
1679                 .driver_module = THIS_MODULE,
1680                 .read_raw = &tsl2x7x_read_raw,
1681                 .write_raw = &tsl2x7x_write_raw,
1682                 .read_event_value = &tsl2x7x_read_event_value,
1683                 .write_event_value = &tsl2x7x_write_event_value,
1684                 .read_event_config = &tsl2x7x_read_interrupt_config,
1685                 .write_event_config = &tsl2x7x_write_interrupt_config,
1686         },
1687         [PRX2] = {
1688                 .attrs = &tsl2X7X_device_attr_group_tbl[PRX2],
1689                 .event_attrs = &tsl2X7X_event_attr_group_tbl[PRX],
1690                 .driver_module = THIS_MODULE,
1691                 .read_raw = &tsl2x7x_read_raw,
1692                 .write_raw = &tsl2x7x_write_raw,
1693                 .read_event_value = &tsl2x7x_read_event_value,
1694                 .write_event_value = &tsl2x7x_write_event_value,
1695                 .read_event_config = &tsl2x7x_read_interrupt_config,
1696                 .write_event_config = &tsl2x7x_write_interrupt_config,
1697         },
1698         [ALSPRX2] = {
1699                 .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2],
1700                 .event_attrs = &tsl2X7X_event_attr_group_tbl[ALSPRX],
1701                 .driver_module = THIS_MODULE,
1702                 .read_raw = &tsl2x7x_read_raw,
1703                 .write_raw = &tsl2x7x_write_raw,
1704                 .read_event_value = &tsl2x7x_read_event_value,
1705                 .write_event_value = &tsl2x7x_write_event_value,
1706                 .read_event_config = &tsl2x7x_read_interrupt_config,
1707                 .write_event_config = &tsl2x7x_write_interrupt_config,
1708         },
1709 };
1710
1711 static const struct iio_event_spec tsl2x7x_events[] = {
1712         {
1713                 .type = IIO_EV_TYPE_THRESH,
1714                 .dir = IIO_EV_DIR_RISING,
1715                 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
1716                         BIT(IIO_EV_INFO_ENABLE),
1717         }, {
1718                 .type = IIO_EV_TYPE_THRESH,
1719                 .dir = IIO_EV_DIR_FALLING,
1720                 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
1721                         BIT(IIO_EV_INFO_ENABLE),
1722         },
1723 };
1724
1725 static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
1726         [ALS] = {
1727                 .channel = {
1728                         {
1729                         .type = IIO_LIGHT,
1730                         .indexed = 1,
1731                         .channel = 0,
1732                         .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1733                         }, {
1734                         .type = IIO_INTENSITY,
1735                         .indexed = 1,
1736                         .channel = 0,
1737                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1738                                 BIT(IIO_CHAN_INFO_CALIBSCALE) |
1739                                 BIT(IIO_CHAN_INFO_CALIBBIAS),
1740                         .event_spec = tsl2x7x_events,
1741                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1742                         }, {
1743                         .type = IIO_INTENSITY,
1744                         .indexed = 1,
1745                         .channel = 1,
1746                         },
1747                 },
1748         .chan_table_elements = 3,
1749         .info = &tsl2X7X_device_info[ALS],
1750         },
1751         [PRX] = {
1752                 .channel = {
1753                         {
1754                         .type = IIO_PROXIMITY,
1755                         .indexed = 1,
1756                         .channel = 0,
1757                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1758                         .event_spec = tsl2x7x_events,
1759                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1760                         },
1761                 },
1762         .chan_table_elements = 1,
1763         .info = &tsl2X7X_device_info[PRX],
1764         },
1765         [ALSPRX] = {
1766                 .channel = {
1767                         {
1768                         .type = IIO_LIGHT,
1769                         .indexed = 1,
1770                         .channel = 0,
1771                         .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED)
1772                         }, {
1773                         .type = IIO_INTENSITY,
1774                         .indexed = 1,
1775                         .channel = 0,
1776                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1777                                 BIT(IIO_CHAN_INFO_CALIBSCALE) |
1778                                 BIT(IIO_CHAN_INFO_CALIBBIAS),
1779                         .event_spec = tsl2x7x_events,
1780                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1781                         }, {
1782                         .type = IIO_INTENSITY,
1783                         .indexed = 1,
1784                         .channel = 1,
1785                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1786                         }, {
1787                         .type = IIO_PROXIMITY,
1788                         .indexed = 1,
1789                         .channel = 0,
1790                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1791                         .event_spec = tsl2x7x_events,
1792                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1793                         },
1794                 },
1795         .chan_table_elements = 4,
1796         .info = &tsl2X7X_device_info[ALSPRX],
1797         },
1798         [PRX2] = {
1799                 .channel = {
1800                         {
1801                         .type = IIO_PROXIMITY,
1802                         .indexed = 1,
1803                         .channel = 0,
1804                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1805                                 BIT(IIO_CHAN_INFO_CALIBSCALE),
1806                         .event_spec = tsl2x7x_events,
1807                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1808                         },
1809                 },
1810         .chan_table_elements = 1,
1811         .info = &tsl2X7X_device_info[PRX2],
1812         },
1813         [ALSPRX2] = {
1814                 .channel = {
1815                         {
1816                         .type = IIO_LIGHT,
1817                         .indexed = 1,
1818                         .channel = 0,
1819                         .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1820                         }, {
1821                         .type = IIO_INTENSITY,
1822                         .indexed = 1,
1823                         .channel = 0,
1824                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1825                                 BIT(IIO_CHAN_INFO_CALIBSCALE) |
1826                                 BIT(IIO_CHAN_INFO_CALIBBIAS),
1827                         .event_spec = tsl2x7x_events,
1828                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1829                         }, {
1830                         .type = IIO_INTENSITY,
1831                         .indexed = 1,
1832                         .channel = 1,
1833                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1834                         }, {
1835                         .type = IIO_PROXIMITY,
1836                         .indexed = 1,
1837                         .channel = 0,
1838                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1839                                 BIT(IIO_CHAN_INFO_CALIBSCALE),
1840                         .event_spec = tsl2x7x_events,
1841                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1842                         },
1843                 },
1844         .chan_table_elements = 4,
1845         .info = &tsl2X7X_device_info[ALSPRX2],
1846         },
1847 };
1848
1849 static int tsl2x7x_probe(struct i2c_client *clientp,
1850                          const struct i2c_device_id *id)
1851 {
1852         int ret;
1853         struct iio_dev *indio_dev;
1854         struct tsl2X7X_chip *chip;
1855
1856         indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
1857         if (!indio_dev)
1858                 return -ENOMEM;
1859
1860         chip = iio_priv(indio_dev);
1861         chip->client = clientp;
1862         i2c_set_clientdata(clientp, indio_dev);
1863
1864         ret = i2c_smbus_read_byte_data(chip->client,
1865                                        TSL2X7X_CMD_REG | TSL2X7X_CHIPID);
1866         if (ret < 0)
1867                 return ret;
1868
1869         if ((!tsl2x7x_device_id(&ret, id->driver_data)) ||
1870             (tsl2x7x_device_id(&ret, id->driver_data) == -EINVAL)) {
1871                 dev_info(&chip->client->dev,
1872                          "%s: i2c device found does not match expected id\n",
1873                                 __func__);
1874                 return -EINVAL;
1875         }
1876
1877         ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
1878         if (ret < 0) {
1879                 dev_err(&clientp->dev, "write to cmd reg failed. err = %d\n",
1880                         ret);
1881                 return ret;
1882         }
1883
1884         /*
1885          * ALS and PROX functions can be invoked via user space poll
1886          * or H/W interrupt. If busy return last sample.
1887          */
1888         mutex_init(&chip->als_mutex);
1889         mutex_init(&chip->prox_mutex);
1890
1891         chip->tsl2x7x_chip_status = TSL2X7X_CHIP_UNKNOWN;
1892         chip->pdata = dev_get_platdata(&clientp->dev);
1893         chip->id = id->driver_data;
1894         chip->chip_info =
1895                 &tsl2x7x_chip_info_tbl[device_channel_config[id->driver_data]];
1896
1897         indio_dev->info = chip->chip_info->info;
1898         indio_dev->dev.parent = &clientp->dev;
1899         indio_dev->modes = INDIO_DIRECT_MODE;
1900         indio_dev->name = chip->client->name;
1901         indio_dev->channels = chip->chip_info->channel;
1902         indio_dev->num_channels = chip->chip_info->chan_table_elements;
1903
1904         if (clientp->irq) {
1905                 ret = devm_request_threaded_irq(&clientp->dev, clientp->irq,
1906                                                 NULL,
1907                                                 &tsl2x7x_event_handler,
1908                                                 IRQF_TRIGGER_RISING |
1909                                                 IRQF_ONESHOT,
1910                                                 "TSL2X7X_event",
1911                                                 indio_dev);
1912                 if (ret) {
1913                         dev_err(&clientp->dev,
1914                                 "%s: irq request failed", __func__);
1915                         return ret;
1916                 }
1917         }
1918
1919         /* Load up the defaults */
1920         tsl2x7x_defaults(chip);
1921         /* Make sure the chip is on */
1922         tsl2x7x_chip_on(indio_dev);
1923
1924         ret = iio_device_register(indio_dev);
1925         if (ret) {
1926                 dev_err(&clientp->dev,
1927                         "%s: iio registration failed\n", __func__);
1928                 return ret;
1929         }
1930
1931         dev_info(&clientp->dev, "%s Light sensor found.\n", id->name);
1932
1933         return 0;
1934 }
1935
1936 static int tsl2x7x_suspend(struct device *dev)
1937 {
1938         struct iio_dev *indio_dev = dev_get_drvdata(dev);
1939         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1940         int ret = 0;
1941
1942         if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
1943                 ret = tsl2x7x_chip_off(indio_dev);
1944                 chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED;
1945         }
1946
1947         if (chip->pdata && chip->pdata->platform_power) {
1948                 pm_message_t pmm = {PM_EVENT_SUSPEND};
1949
1950                 chip->pdata->platform_power(dev, pmm);
1951         }
1952
1953         return ret;
1954 }
1955
1956 static int tsl2x7x_resume(struct device *dev)
1957 {
1958         struct iio_dev *indio_dev = dev_get_drvdata(dev);
1959         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1960         int ret = 0;
1961
1962         if (chip->pdata && chip->pdata->platform_power) {
1963                 pm_message_t pmm = {PM_EVENT_RESUME};
1964
1965                 chip->pdata->platform_power(dev, pmm);
1966         }
1967
1968         if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_SUSPENDED)
1969                 ret = tsl2x7x_chip_on(indio_dev);
1970
1971         return ret;
1972 }
1973
1974 static int tsl2x7x_remove(struct i2c_client *client)
1975 {
1976         struct iio_dev *indio_dev = i2c_get_clientdata(client);
1977
1978         tsl2x7x_chip_off(indio_dev);
1979
1980         iio_device_unregister(indio_dev);
1981
1982         return 0;
1983 }
1984
1985 static struct i2c_device_id tsl2x7x_idtable[] = {
1986         { "tsl2571", tsl2571 },
1987         { "tsl2671", tsl2671 },
1988         { "tmd2671", tmd2671 },
1989         { "tsl2771", tsl2771 },
1990         { "tmd2771", tmd2771 },
1991         { "tsl2572", tsl2572 },
1992         { "tsl2672", tsl2672 },
1993         { "tmd2672", tmd2672 },
1994         { "tsl2772", tsl2772 },
1995         { "tmd2772", tmd2772 },
1996         {}
1997 };
1998
1999 MODULE_DEVICE_TABLE(i2c, tsl2x7x_idtable);
2000
2001 static const struct of_device_id tsl2x7x_of_match[] = {
2002         { .compatible = "amstaos,tsl2571" },
2003         { .compatible = "amstaos,tsl2671" },
2004         { .compatible = "amstaos,tmd2671" },
2005         { .compatible = "amstaos,tsl2771" },
2006         { .compatible = "amstaos,tmd2771" },
2007         { .compatible = "amstaos,tsl2572" },
2008         { .compatible = "amstaos,tsl2672" },
2009         { .compatible = "amstaos,tmd2672" },
2010         { .compatible = "amstaos,tsl2772" },
2011         { .compatible = "amstaos,tmd2772" },
2012         {}
2013 };
2014 MODULE_DEVICE_TABLE(of, tsl2x7x_of_match);
2015
2016 static const struct dev_pm_ops tsl2x7x_pm_ops = {
2017         .suspend = tsl2x7x_suspend,
2018         .resume  = tsl2x7x_resume,
2019 };
2020
2021 /* Driver definition */
2022 static struct i2c_driver tsl2x7x_driver = {
2023         .driver = {
2024                 .name = "tsl2x7x",
2025                 .of_match_table = tsl2x7x_of_match,
2026                 .pm = &tsl2x7x_pm_ops,
2027         },
2028         .id_table = tsl2x7x_idtable,
2029         .probe = tsl2x7x_probe,
2030         .remove = tsl2x7x_remove,
2031 };
2032
2033 module_i2c_driver(tsl2x7x_driver);
2034
2035 MODULE_AUTHOR("J. August Brenner<jbrenner@taosinc.com>");
2036 MODULE_DESCRIPTION("TAOS tsl2x7x ambient and proximity light sensor driver");
2037 MODULE_LICENSE("GPL");