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