Merge branch 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
[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) & 0xFF;
671         chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHHI] =
672                         (chip->tsl2x7x_settings.prox_thres_low >> 8) & 0xFF;
673         chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHLO] =
674                         (chip->tsl2x7x_settings.prox_thres_high) & 0xFF;
675         chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHHI] =
676                         (chip->tsl2x7x_settings.prox_thres_high >> 8) & 0xFF;
677
678         /* and make sure we're not already on */
679         if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
680                 /* if forcing a register update - turn off, then on */
681                 dev_info(&chip->client->dev, "device is already enabled\n");
682                 return -EINVAL;
683         }
684
685         /* determine als integration register */
686         als_count = (chip->tsl2x7x_settings.als_time * 100 + 135) / 270;
687         if (als_count == 0)
688                 als_count = 1; /* ensure at least one cycle */
689
690         /* convert back to time (encompasses overrides) */
691         als_time = (als_count * 27 + 5) / 10;
692         chip->tsl2x7x_config[TSL2X7X_ALS_TIME] = 256 - als_count;
693
694         /* Set the gain based on tsl2x7x_settings struct */
695         chip->tsl2x7x_config[TSL2X7X_GAIN] =
696                 (chip->tsl2x7x_settings.als_gain |
697                         (TSL2X7X_mA100 | TSL2X7X_DIODE1)
698                         | ((chip->tsl2x7x_settings.prox_gain) << 2));
699
700         /* set chip struct re scaling and saturation */
701         chip->als_saturation = als_count * 922; /* 90% of full scale */
702         chip->als_time_scale = (als_time + 25) / 50;
703
704         /* TSL2X7X Specific power-on / adc enable sequence
705          * Power on the device 1st. */
706         utmp = TSL2X7X_CNTL_PWR_ON;
707         ret = i2c_smbus_write_byte_data(chip->client,
708                 TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp);
709         if (ret < 0) {
710                 dev_err(&chip->client->dev,
711                         "%s: failed on CNTRL reg.\n", __func__);
712                 return ret;
713         }
714
715         /* Use the following shadow copy for our delay before enabling ADC.
716          * Write all the registers. */
717         for (i = 0, dev_reg = chip->tsl2x7x_config;
718                         i < TSL2X7X_MAX_CONFIG_REG; i++) {
719                 ret = i2c_smbus_write_byte_data(chip->client,
720                                 TSL2X7X_CMD_REG + i, *dev_reg++);
721                 if (ret < 0) {
722                         dev_err(&chip->client->dev,
723                         "%s: failed on write to reg %d.\n", __func__, i);
724                         return ret;
725                 }
726         }
727
728         mdelay(3);      /* Power-on settling time */
729
730         /* NOW enable the ADC
731          * initialize the desired mode of operation */
732         utmp = TSL2X7X_CNTL_PWR_ON |
733                         TSL2X7X_CNTL_ADC_ENBL |
734                         TSL2X7X_CNTL_PROX_DET_ENBL;
735         ret = i2c_smbus_write_byte_data(chip->client,
736                         TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp);
737         if (ret < 0) {
738                 dev_err(&chip->client->dev,
739                         "%s: failed on 2nd CTRL reg.\n", __func__);
740                 return ret;
741         }
742
743         chip->tsl2x7x_chip_status = TSL2X7X_CHIP_WORKING;
744
745         if (chip->tsl2x7x_settings.interrupts_en != 0) {
746                 dev_info(&chip->client->dev, "Setting Up Interrupt(s)\n");
747
748                 reg_val = TSL2X7X_CNTL_PWR_ON | TSL2X7X_CNTL_ADC_ENBL;
749                 if ((chip->tsl2x7x_settings.interrupts_en == 0x20) ||
750                         (chip->tsl2x7x_settings.interrupts_en == 0x30))
751                         reg_val |= TSL2X7X_CNTL_PROX_DET_ENBL;
752
753                 reg_val |= chip->tsl2x7x_settings.interrupts_en;
754                 ret = i2c_smbus_write_byte_data(chip->client,
755                         (TSL2X7X_CMD_REG | TSL2X7X_CNTRL), reg_val);
756                 if (ret < 0)
757                         dev_err(&chip->client->dev,
758                                 "%s: failed in tsl2x7x_IOCTL_INT_SET.\n",
759                                 __func__);
760
761                 /* Clear out any initial interrupts  */
762                 ret = i2c_smbus_write_byte(chip->client,
763                         TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN |
764                         TSL2X7X_CMD_PROXALS_INT_CLR);
765                 if (ret < 0) {
766                         dev_err(&chip->client->dev,
767                                 "%s: Failed to clear Int status\n",
768                                 __func__);
769                 return ret;
770                 }
771         }
772
773         return ret;
774 }
775
776 static int tsl2x7x_chip_off(struct iio_dev *indio_dev)
777 {
778         int ret;
779         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
780
781         /* turn device off */
782         chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED;
783
784         ret = i2c_smbus_write_byte_data(chip->client,
785                 TSL2X7X_CMD_REG | TSL2X7X_CNTRL, 0x00);
786
787         if (chip->pdata && chip->pdata->power_off)
788                 chip->pdata->power_off(chip->client);
789
790         return ret;
791 }
792
793 /**
794  * tsl2x7x_invoke_change
795  * @indio_dev:  pointer to IIO device
796  *
797  * Obtain and lock both ALS and PROX resources,
798  * determine and save device state (On/Off),
799  * cycle device to implement updated parameter,
800  * put device back into proper state, and unlock
801  * resource.
802  */
803 static
804 int tsl2x7x_invoke_change(struct iio_dev *indio_dev)
805 {
806         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
807         int device_status = chip->tsl2x7x_chip_status;
808
809         mutex_lock(&chip->als_mutex);
810         mutex_lock(&chip->prox_mutex);
811
812         if (device_status == TSL2X7X_CHIP_WORKING)
813                 tsl2x7x_chip_off(indio_dev);
814
815         tsl2x7x_chip_on(indio_dev);
816
817         if (device_status != TSL2X7X_CHIP_WORKING)
818                 tsl2x7x_chip_off(indio_dev);
819
820         mutex_unlock(&chip->prox_mutex);
821         mutex_unlock(&chip->als_mutex);
822
823         return 0;
824 }
825
826 static
827 void tsl2x7x_prox_calculate(int *data, int length,
828                 struct tsl2x7x_prox_stat *statP)
829 {
830         int i;
831         int sample_sum;
832         int tmp;
833
834         if (length == 0)
835                 length = 1;
836
837         sample_sum = 0;
838         statP->min = INT_MAX;
839         statP->max = INT_MIN;
840         for (i = 0; i < length; i++) {
841                 sample_sum += data[i];
842                 statP->min = min(statP->min, data[i]);
843                 statP->max = max(statP->max, data[i]);
844         }
845
846         statP->mean = sample_sum / length;
847         sample_sum = 0;
848         for (i = 0; i < length; i++) {
849                 tmp = data[i] - statP->mean;
850                 sample_sum += tmp * tmp;
851         }
852         statP->stddev = int_sqrt((long)sample_sum)/length;
853 }
854
855 /**
856  * tsl2x7x_prox_cal() - Calculates std. and sets thresholds.
857  * @indio_dev:  pointer to IIO device
858  *
859  * Calculates a standard deviation based on the samples,
860  * and sets the threshold accordingly.
861  */
862 static void tsl2x7x_prox_cal(struct iio_dev *indio_dev)
863 {
864         int prox_history[MAX_SAMPLES_CAL + 1];
865         int i;
866         struct tsl2x7x_prox_stat prox_stat_data[2];
867         struct tsl2x7x_prox_stat *calP;
868         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
869         u8 tmp_irq_settings;
870         u8 current_state = chip->tsl2x7x_chip_status;
871
872         if (chip->tsl2x7x_settings.prox_max_samples_cal > MAX_SAMPLES_CAL) {
873                 dev_err(&chip->client->dev,
874                         "%s: max prox samples cal is too big: %d\n",
875                         __func__, chip->tsl2x7x_settings.prox_max_samples_cal);
876                 chip->tsl2x7x_settings.prox_max_samples_cal = MAX_SAMPLES_CAL;
877         }
878
879         /* have to stop to change settings */
880         tsl2x7x_chip_off(indio_dev);
881
882         /* Enable proximity detection save just in case prox not wanted yet*/
883         tmp_irq_settings = chip->tsl2x7x_settings.interrupts_en;
884         chip->tsl2x7x_settings.interrupts_en |= TSL2X7X_CNTL_PROX_INT_ENBL;
885
886         /*turn on device if not already on*/
887         tsl2x7x_chip_on(indio_dev);
888
889         /*gather the samples*/
890         for (i = 0; i < chip->tsl2x7x_settings.prox_max_samples_cal; i++) {
891                 mdelay(15);
892                 tsl2x7x_get_prox(indio_dev);
893                 prox_history[i] = chip->prox_data;
894                 dev_info(&chip->client->dev, "2 i=%d prox data= %d\n",
895                         i, chip->prox_data);
896         }
897
898         tsl2x7x_chip_off(indio_dev);
899         calP = &prox_stat_data[PROX_STAT_CAL];
900         tsl2x7x_prox_calculate(prox_history,
901                 chip->tsl2x7x_settings.prox_max_samples_cal, calP);
902         chip->tsl2x7x_settings.prox_thres_high = (calP->max << 1) - calP->mean;
903
904         dev_info(&chip->client->dev, " cal min=%d mean=%d max=%d\n",
905                 calP->min, calP->mean, calP->max);
906         dev_info(&chip->client->dev,
907                 "%s proximity threshold set to %d\n",
908                 chip->client->name, chip->tsl2x7x_settings.prox_thres_high);
909
910         /* back to the way they were */
911         chip->tsl2x7x_settings.interrupts_en = tmp_irq_settings;
912         if (current_state == TSL2X7X_CHIP_WORKING)
913                 tsl2x7x_chip_on(indio_dev);
914 }
915
916 static ssize_t tsl2x7x_power_state_show(struct device *dev,
917         struct device_attribute *attr, char *buf)
918 {
919         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
920
921         return snprintf(buf, PAGE_SIZE, "%d\n", chip->tsl2x7x_chip_status);
922 }
923
924 static ssize_t tsl2x7x_power_state_store(struct device *dev,
925         struct device_attribute *attr, const char *buf, size_t len)
926 {
927         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
928         bool value;
929
930         if (strtobool(buf, &value))
931                 return -EINVAL;
932
933         if (value)
934                 tsl2x7x_chip_on(indio_dev);
935         else
936                 tsl2x7x_chip_off(indio_dev);
937
938         return len;
939 }
940
941 static ssize_t tsl2x7x_gain_available_show(struct device *dev,
942         struct device_attribute *attr, char *buf)
943 {
944         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
945
946         switch (chip->id) {
947         case tsl2571:
948         case tsl2671:
949         case tmd2671:
950         case tsl2771:
951         case tmd2771:
952                 return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128");
953         }
954
955         return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
956 }
957
958 static ssize_t tsl2x7x_prox_gain_available_show(struct device *dev,
959         struct device_attribute *attr, char *buf)
960 {
961                 return snprintf(buf, PAGE_SIZE, "%s\n", "1 2 4 8");
962 }
963
964 static ssize_t tsl2x7x_als_time_show(struct device *dev,
965         struct device_attribute *attr, char *buf)
966 {
967         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
968         int y, z;
969
970         y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
971         z = y * TSL2X7X_MIN_ITIME;
972         y /= 1000;
973         z %= 1000;
974
975         return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
976 }
977
978 static ssize_t tsl2x7x_als_time_store(struct device *dev,
979         struct device_attribute *attr, const char *buf, size_t len)
980 {
981         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
982         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
983         struct tsl2x7x_parse_result result;
984         int ret;
985
986         ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
987         if (ret)
988                 return ret;
989
990         result.fract /= 3;
991         chip->tsl2x7x_settings.als_time =
992                         (TSL2X7X_MAX_TIMER_CNT - (u8)result.fract);
993
994         dev_info(&chip->client->dev, "%s: als time = %d",
995                 __func__, chip->tsl2x7x_settings.als_time);
996
997         tsl2x7x_invoke_change(indio_dev);
998
999         return IIO_VAL_INT_PLUS_MICRO;
1000 }
1001
1002 static IIO_CONST_ATTR(in_illuminance0_integration_time_available,
1003                 ".00272 - .696");
1004
1005 static ssize_t tsl2x7x_als_cal_target_show(struct device *dev,
1006         struct device_attribute *attr, char *buf)
1007 {
1008         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
1009
1010         return snprintf(buf, PAGE_SIZE, "%d\n",
1011                         chip->tsl2x7x_settings.als_cal_target);
1012 }
1013
1014 static ssize_t tsl2x7x_als_cal_target_store(struct device *dev,
1015         struct device_attribute *attr, const char *buf, size_t len)
1016 {
1017         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1018         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1019         unsigned long value;
1020
1021         if (kstrtoul(buf, 0, &value))
1022                 return -EINVAL;
1023
1024         if (value)
1025                 chip->tsl2x7x_settings.als_cal_target = value;
1026
1027         tsl2x7x_invoke_change(indio_dev);
1028
1029         return len;
1030 }
1031
1032 /* persistence settings */
1033 static ssize_t tsl2x7x_als_persistence_show(struct device *dev,
1034         struct device_attribute *attr, char *buf)
1035 {
1036         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
1037         int y, z, filter_delay;
1038
1039         /* Determine integration time */
1040         y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
1041         z = y * TSL2X7X_MIN_ITIME;
1042         filter_delay = z * (chip->tsl2x7x_settings.persistence & 0x0F);
1043         y = (filter_delay / 1000);
1044         z = (filter_delay % 1000);
1045
1046         return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
1047 }
1048
1049 static ssize_t tsl2x7x_als_persistence_store(struct device *dev,
1050         struct device_attribute *attr, const char *buf, size_t len)
1051 {
1052         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1053         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1054         struct tsl2x7x_parse_result result;
1055         int y, z, filter_delay;
1056         int ret;
1057
1058         ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
1059         if (ret)
1060                 return ret;
1061
1062         y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
1063         z = y * TSL2X7X_MIN_ITIME;
1064
1065         filter_delay =
1066                 DIV_ROUND_UP(((result.integer * 1000) + result.fract), z);
1067
1068         chip->tsl2x7x_settings.persistence &= 0xF0;
1069         chip->tsl2x7x_settings.persistence |= (filter_delay & 0x0F);
1070
1071         dev_info(&chip->client->dev, "%s: als persistence = %d",
1072                 __func__, filter_delay);
1073
1074         tsl2x7x_invoke_change(indio_dev);
1075
1076         return IIO_VAL_INT_PLUS_MICRO;
1077 }
1078
1079 static ssize_t tsl2x7x_prox_persistence_show(struct device *dev,
1080         struct device_attribute *attr, char *buf)
1081 {
1082         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
1083         int y, z, filter_delay;
1084
1085         /* Determine integration time */
1086         y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1;
1087         z = y * TSL2X7X_MIN_ITIME;
1088         filter_delay = z * ((chip->tsl2x7x_settings.persistence & 0xF0) >> 4);
1089         y = (filter_delay / 1000);
1090         z = (filter_delay % 1000);
1091
1092         return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
1093 }
1094
1095 static ssize_t tsl2x7x_prox_persistence_store(struct device *dev,
1096         struct device_attribute *attr, const char *buf, size_t len)
1097 {
1098         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1099         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1100         struct tsl2x7x_parse_result result;
1101         int y, z, filter_delay;
1102         int ret;
1103
1104         ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
1105         if (ret)
1106                 return ret;
1107
1108         y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1;
1109         z = y * TSL2X7X_MIN_ITIME;
1110
1111         filter_delay =
1112                 DIV_ROUND_UP(((result.integer * 1000) + result.fract), z);
1113
1114         chip->tsl2x7x_settings.persistence &= 0x0F;
1115         chip->tsl2x7x_settings.persistence |= ((filter_delay << 4) & 0xF0);
1116
1117         dev_info(&chip->client->dev, "%s: prox persistence = %d",
1118                 __func__, filter_delay);
1119
1120         tsl2x7x_invoke_change(indio_dev);
1121
1122         return IIO_VAL_INT_PLUS_MICRO;
1123 }
1124
1125 static ssize_t tsl2x7x_do_calibrate(struct device *dev,
1126         struct device_attribute *attr, const char *buf, size_t len)
1127 {
1128         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1129         bool value;
1130
1131         if (strtobool(buf, &value))
1132                 return -EINVAL;
1133
1134         if (value)
1135                 tsl2x7x_als_calibrate(indio_dev);
1136
1137         tsl2x7x_invoke_change(indio_dev);
1138
1139         return len;
1140 }
1141
1142 static ssize_t tsl2x7x_luxtable_show(struct device *dev,
1143         struct device_attribute *attr, char *buf)
1144 {
1145         struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
1146         int i = 0;
1147         int offset = 0;
1148
1149         while (i < (TSL2X7X_MAX_LUX_TABLE_SIZE * 3)) {
1150                 offset += snprintf(buf + offset, PAGE_SIZE, "%d,%d,%d,",
1151                         chip->tsl2x7x_device_lux[i].ratio,
1152                         chip->tsl2x7x_device_lux[i].ch0,
1153                         chip->tsl2x7x_device_lux[i].ch1);
1154                 if (chip->tsl2x7x_device_lux[i].ratio == 0) {
1155                         /* We just printed the first "0" entry.
1156                          * Now get rid of the extra "," and break. */
1157                         offset--;
1158                         break;
1159                 }
1160                 i++;
1161         }
1162
1163         offset += snprintf(buf + offset, PAGE_SIZE, "\n");
1164         return offset;
1165 }
1166
1167 static ssize_t tsl2x7x_luxtable_store(struct device *dev,
1168         struct device_attribute *attr, const char *buf, size_t len)
1169 {
1170         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1171         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1172         int value[ARRAY_SIZE(chip->tsl2x7x_device_lux)*3 + 1];
1173         int n;
1174
1175         get_options(buf, ARRAY_SIZE(value), value);
1176
1177         /* We now have an array of ints starting at value[1], and
1178          * enumerated by value[0].
1179          * We expect each group of three ints is one table entry,
1180          * and the last table entry is all 0.
1181          */
1182         n = value[0];
1183         if ((n % 3) || n < 6 ||
1184                         n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 3)) {
1185                 dev_info(dev, "LUX TABLE INPUT ERROR 1 Value[0]=%d\n", n);
1186                 return -EINVAL;
1187         }
1188
1189         if ((value[(n - 2)] | value[(n - 1)] | value[n]) != 0) {
1190                 dev_info(dev, "LUX TABLE INPUT ERROR 2 Value[0]=%d\n", n);
1191                 return -EINVAL;
1192         }
1193
1194         if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING)
1195                 tsl2x7x_chip_off(indio_dev);
1196
1197         /* Zero out the table */
1198         memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux));
1199         memcpy(chip->tsl2x7x_device_lux, &value[1], (value[0] * 4));
1200
1201         tsl2x7x_invoke_change(indio_dev);
1202
1203         return len;
1204 }
1205
1206 static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev,
1207         struct device_attribute *attr, const char *buf, size_t len)
1208 {
1209         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1210         bool value;
1211
1212         if (strtobool(buf, &value))
1213                 return -EINVAL;
1214
1215         if (value)
1216                 tsl2x7x_prox_cal(indio_dev);
1217
1218         tsl2x7x_invoke_change(indio_dev);
1219
1220         return len;
1221 }
1222
1223 static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
1224                                          const struct iio_chan_spec *chan,
1225                                          enum iio_event_type type,
1226                                          enum iio_event_direction dir)
1227 {
1228         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1229         int ret;
1230
1231         if (chan->type == IIO_INTENSITY)
1232                 ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x10);
1233         else
1234                 ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x20);
1235
1236         return ret;
1237 }
1238
1239 static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
1240                                           const struct iio_chan_spec *chan,
1241                                           enum iio_event_type type,
1242                                           enum iio_event_direction dir,
1243                                           int val)
1244 {
1245         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1246
1247         if (chan->type == IIO_INTENSITY) {
1248                 if (val)
1249                         chip->tsl2x7x_settings.interrupts_en |= 0x10;
1250                 else
1251                         chip->tsl2x7x_settings.interrupts_en &= 0x20;
1252         } else {
1253                 if (val)
1254                         chip->tsl2x7x_settings.interrupts_en |= 0x20;
1255                 else
1256                         chip->tsl2x7x_settings.interrupts_en &= 0x10;
1257         }
1258
1259         tsl2x7x_invoke_change(indio_dev);
1260
1261         return 0;
1262 }
1263
1264 static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
1265                                 const struct iio_chan_spec *chan,
1266                                 enum iio_event_type type,
1267                                 enum iio_event_direction dir,
1268                                 enum iio_event_info info,
1269                                 int val, int val2)
1270 {
1271         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1272
1273         if (chan->type == IIO_INTENSITY) {
1274                 switch (dir) {
1275                 case IIO_EV_DIR_RISING:
1276                         chip->tsl2x7x_settings.als_thresh_high = val;
1277                         break;
1278                 case IIO_EV_DIR_FALLING:
1279                         chip->tsl2x7x_settings.als_thresh_low = val;
1280                         break;
1281                 default:
1282                         return -EINVAL;
1283                 }
1284         } else {
1285                 switch (dir) {
1286                 case IIO_EV_DIR_RISING:
1287                         chip->tsl2x7x_settings.prox_thres_high = val;
1288                         break;
1289                 case IIO_EV_DIR_FALLING:
1290                         chip->tsl2x7x_settings.prox_thres_low = val;
1291                         break;
1292                 default:
1293                         return -EINVAL;
1294                 }
1295         }
1296
1297         tsl2x7x_invoke_change(indio_dev);
1298
1299         return 0;
1300 }
1301
1302 static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
1303                                const struct iio_chan_spec *chan,
1304                                enum iio_event_type type,
1305                                enum iio_event_direction dir,
1306                                    enum iio_event_info info,
1307                                int *val, int *val2)
1308 {
1309         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1310
1311         if (chan->type == IIO_INTENSITY) {
1312                 switch (dir) {
1313                 case IIO_EV_DIR_RISING:
1314                         *val = chip->tsl2x7x_settings.als_thresh_high;
1315                         break;
1316                 case IIO_EV_DIR_FALLING:
1317                         *val = chip->tsl2x7x_settings.als_thresh_low;
1318                         break;
1319                 default:
1320                         return -EINVAL;
1321                 }
1322         } else {
1323                 switch (dir) {
1324                 case IIO_EV_DIR_RISING:
1325                         *val = chip->tsl2x7x_settings.prox_thres_high;
1326                         break;
1327                 case IIO_EV_DIR_FALLING:
1328                         *val = chip->tsl2x7x_settings.prox_thres_low;
1329                         break;
1330                 default:
1331                         return -EINVAL;
1332                 }
1333         }
1334
1335         return IIO_VAL_INT;
1336 }
1337
1338 static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
1339                             struct iio_chan_spec const *chan,
1340                             int *val,
1341                             int *val2,
1342                             long mask)
1343 {
1344         int ret = -EINVAL;
1345         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1346
1347         switch (mask) {
1348         case IIO_CHAN_INFO_PROCESSED:
1349                 switch (chan->type) {
1350                 case IIO_LIGHT:
1351                         tsl2x7x_get_lux(indio_dev);
1352                         *val = chip->als_cur_info.lux;
1353                         ret = IIO_VAL_INT;
1354                         break;
1355                 default:
1356                         return -EINVAL;
1357                 }
1358                 break;
1359         case IIO_CHAN_INFO_RAW:
1360                 switch (chan->type) {
1361                 case IIO_INTENSITY:
1362                         tsl2x7x_get_lux(indio_dev);
1363                         if (chan->channel == 0)
1364                                 *val = chip->als_cur_info.als_ch0;
1365                         else
1366                                 *val = chip->als_cur_info.als_ch1;
1367                         ret = IIO_VAL_INT;
1368                         break;
1369                 case IIO_PROXIMITY:
1370                         tsl2x7x_get_prox(indio_dev);
1371                         *val = chip->prox_data;
1372                         ret = IIO_VAL_INT;
1373                         break;
1374                 default:
1375                         return -EINVAL;
1376                 }
1377                 break;
1378         case IIO_CHAN_INFO_CALIBSCALE:
1379                 if (chan->type == IIO_LIGHT)
1380                         *val =
1381                         tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain];
1382                 else
1383                         *val =
1384                         tsl2X7X_prx_gainadj[chip->tsl2x7x_settings.prox_gain];
1385                 ret = IIO_VAL_INT;
1386                 break;
1387         case IIO_CHAN_INFO_CALIBBIAS:
1388                 *val = chip->tsl2x7x_settings.als_gain_trim;
1389                 ret = IIO_VAL_INT;
1390                 break;
1391
1392         default:
1393                 ret = -EINVAL;
1394         }
1395
1396         return ret;
1397 }
1398
1399 static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
1400                                struct iio_chan_spec const *chan,
1401                                int val,
1402                                int val2,
1403                                long mask)
1404 {
1405         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1406
1407         switch (mask) {
1408         case IIO_CHAN_INFO_CALIBSCALE:
1409                 if (chan->type == IIO_INTENSITY) {
1410                         switch (val) {
1411                         case 1:
1412                                 chip->tsl2x7x_settings.als_gain = 0;
1413                                 break;
1414                         case 8:
1415                                 chip->tsl2x7x_settings.als_gain = 1;
1416                                 break;
1417                         case 16:
1418                                 chip->tsl2x7x_settings.als_gain = 2;
1419                                 break;
1420                         case 120:
1421                                 switch (chip->id) {
1422                                 case tsl2572:
1423                                 case tsl2672:
1424                                 case tmd2672:
1425                                 case tsl2772:
1426                                 case tmd2772:
1427                                         return -EINVAL;
1428                                 }
1429                                 chip->tsl2x7x_settings.als_gain = 3;
1430                                 break;
1431                         case 128:
1432                                 switch (chip->id) {
1433                                 case tsl2571:
1434                                 case tsl2671:
1435                                 case tmd2671:
1436                                 case tsl2771:
1437                                 case tmd2771:
1438                                         return -EINVAL;
1439                                 }
1440                                 chip->tsl2x7x_settings.als_gain = 3;
1441                                 break;
1442                         default:
1443                                 return -EINVAL;
1444                         }
1445                 } else {
1446                         switch (val) {
1447                         case 1:
1448                                 chip->tsl2x7x_settings.prox_gain = 0;
1449                                 break;
1450                         case 2:
1451                                 chip->tsl2x7x_settings.prox_gain = 1;
1452                                 break;
1453                         case 4:
1454                                 chip->tsl2x7x_settings.prox_gain = 2;
1455                                 break;
1456                         case 8:
1457                                 chip->tsl2x7x_settings.prox_gain = 3;
1458                                 break;
1459                         default:
1460                                 return -EINVAL;
1461                         }
1462                 }
1463                 break;
1464         case IIO_CHAN_INFO_CALIBBIAS:
1465                 chip->tsl2x7x_settings.als_gain_trim = val;
1466                 break;
1467
1468         default:
1469                 return -EINVAL;
1470         }
1471
1472         tsl2x7x_invoke_change(indio_dev);
1473
1474         return 0;
1475 }
1476
1477 static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
1478                 tsl2x7x_power_state_show, tsl2x7x_power_state_store);
1479
1480 static DEVICE_ATTR(in_proximity0_calibscale_available, S_IRUGO,
1481                 tsl2x7x_prox_gain_available_show, NULL);
1482
1483 static DEVICE_ATTR(in_illuminance0_calibscale_available, S_IRUGO,
1484                 tsl2x7x_gain_available_show, NULL);
1485
1486 static DEVICE_ATTR(in_illuminance0_integration_time, S_IRUGO | S_IWUSR,
1487                 tsl2x7x_als_time_show, tsl2x7x_als_time_store);
1488
1489 static DEVICE_ATTR(in_illuminance0_target_input, S_IRUGO | S_IWUSR,
1490                 tsl2x7x_als_cal_target_show, tsl2x7x_als_cal_target_store);
1491
1492 static DEVICE_ATTR(in_illuminance0_calibrate, S_IWUSR, NULL,
1493                 tsl2x7x_do_calibrate);
1494
1495 static DEVICE_ATTR(in_proximity0_calibrate, S_IWUSR, NULL,
1496                 tsl2x7x_do_prox_calibrate);
1497
1498 static DEVICE_ATTR(in_illuminance0_lux_table, S_IRUGO | S_IWUSR,
1499                 tsl2x7x_luxtable_show, tsl2x7x_luxtable_store);
1500
1501 static DEVICE_ATTR(in_intensity0_thresh_period, S_IRUGO | S_IWUSR,
1502                 tsl2x7x_als_persistence_show, tsl2x7x_als_persistence_store);
1503
1504 static DEVICE_ATTR(in_proximity0_thresh_period, S_IRUGO | S_IWUSR,
1505                 tsl2x7x_prox_persistence_show, tsl2x7x_prox_persistence_store);
1506
1507 /* Use the default register values to identify the Taos device */
1508 static int tsl2x7x_device_id(unsigned char *id, int target)
1509 {
1510         switch (target) {
1511         case tsl2571:
1512         case tsl2671:
1513         case tsl2771:
1514                 return (*id & 0xf0) == TRITON_ID;
1515         case tmd2671:
1516         case tmd2771:
1517                 return (*id & 0xf0) == HALIBUT_ID;
1518         case tsl2572:
1519         case tsl2672:
1520         case tmd2672:
1521         case tsl2772:
1522         case tmd2772:
1523                 return (*id & 0xf0) == SWORDFISH_ID;
1524         }
1525
1526         return -EINVAL;
1527 }
1528
1529 static irqreturn_t tsl2x7x_event_handler(int irq, void *private)
1530 {
1531         struct iio_dev *indio_dev = private;
1532         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1533         s64 timestamp = iio_get_time_ns();
1534         int ret;
1535         u8 value;
1536
1537         value = i2c_smbus_read_byte_data(chip->client,
1538                 TSL2X7X_CMD_REG | TSL2X7X_STATUS);
1539
1540         /* What type of interrupt do we need to process */
1541         if (value & TSL2X7X_STA_PRX_INTR) {
1542                 tsl2x7x_get_prox(indio_dev); /* freshen data for ABI */
1543                 iio_push_event(indio_dev,
1544                                IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
1545                                                     0,
1546                                                     IIO_EV_TYPE_THRESH,
1547                                                     IIO_EV_DIR_EITHER),
1548                                                     timestamp);
1549         }
1550
1551         if (value & TSL2X7X_STA_ALS_INTR) {
1552                 tsl2x7x_get_lux(indio_dev); /* freshen data for ABI */
1553                 iio_push_event(indio_dev,
1554                        IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
1555                                             0,
1556                                             IIO_EV_TYPE_THRESH,
1557                                             IIO_EV_DIR_EITHER),
1558                                             timestamp);
1559         }
1560         /* Clear interrupt now that we have handled it. */
1561         ret = i2c_smbus_write_byte(chip->client,
1562                 TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN |
1563                 TSL2X7X_CMD_PROXALS_INT_CLR);
1564         if (ret < 0)
1565                 dev_err(&chip->client->dev,
1566                         "%s: Failed to clear irq from event handler. err = %d\n",
1567                         __func__, ret);
1568
1569         return IRQ_HANDLED;
1570 }
1571
1572 static struct attribute *tsl2x7x_ALS_device_attrs[] = {
1573         &dev_attr_power_state.attr,
1574         &dev_attr_in_illuminance0_calibscale_available.attr,
1575         &dev_attr_in_illuminance0_integration_time.attr,
1576         &iio_const_attr_in_illuminance0_integration_time_available\
1577         .dev_attr.attr,
1578         &dev_attr_in_illuminance0_target_input.attr,
1579         &dev_attr_in_illuminance0_calibrate.attr,
1580         &dev_attr_in_illuminance0_lux_table.attr,
1581         NULL
1582 };
1583
1584 static struct attribute *tsl2x7x_PRX_device_attrs[] = {
1585         &dev_attr_power_state.attr,
1586         &dev_attr_in_proximity0_calibrate.attr,
1587         NULL
1588 };
1589
1590 static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = {
1591         &dev_attr_power_state.attr,
1592         &dev_attr_in_illuminance0_calibscale_available.attr,
1593         &dev_attr_in_illuminance0_integration_time.attr,
1594         &iio_const_attr_in_illuminance0_integration_time_available\
1595         .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         NULL
1601 };
1602
1603 static struct attribute *tsl2x7x_PRX2_device_attrs[] = {
1604         &dev_attr_power_state.attr,
1605         &dev_attr_in_proximity0_calibrate.attr,
1606         &dev_attr_in_proximity0_calibscale_available.attr,
1607         NULL
1608 };
1609
1610 static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = {
1611         &dev_attr_power_state.attr,
1612         &dev_attr_in_illuminance0_calibscale_available.attr,
1613         &dev_attr_in_illuminance0_integration_time.attr,
1614         &iio_const_attr_in_illuminance0_integration_time_available\
1615         .dev_attr.attr,
1616         &dev_attr_in_illuminance0_target_input.attr,
1617         &dev_attr_in_illuminance0_calibrate.attr,
1618         &dev_attr_in_illuminance0_lux_table.attr,
1619         &dev_attr_in_proximity0_calibrate.attr,
1620         &dev_attr_in_proximity0_calibscale_available.attr,
1621         NULL
1622 };
1623
1624 static struct attribute *tsl2X7X_ALS_event_attrs[] = {
1625         &dev_attr_in_intensity0_thresh_period.attr,
1626         NULL,
1627 };
1628 static struct attribute *tsl2X7X_PRX_event_attrs[] = {
1629         &dev_attr_in_proximity0_thresh_period.attr,
1630         NULL,
1631 };
1632
1633 static struct attribute *tsl2X7X_ALSPRX_event_attrs[] = {
1634         &dev_attr_in_intensity0_thresh_period.attr,
1635         &dev_attr_in_proximity0_thresh_period.attr,
1636         NULL,
1637 };
1638
1639 static const struct attribute_group tsl2X7X_device_attr_group_tbl[] = {
1640         [ALS] = {
1641                 .attrs = tsl2x7x_ALS_device_attrs,
1642         },
1643         [PRX] = {
1644                 .attrs = tsl2x7x_PRX_device_attrs,
1645         },
1646         [ALSPRX] = {
1647                 .attrs = tsl2x7x_ALSPRX_device_attrs,
1648         },
1649         [PRX2] = {
1650                 .attrs = tsl2x7x_PRX2_device_attrs,
1651         },
1652         [ALSPRX2] = {
1653                 .attrs = tsl2x7x_ALSPRX2_device_attrs,
1654         },
1655 };
1656
1657 static struct attribute_group tsl2X7X_event_attr_group_tbl[] = {
1658         [ALS] = {
1659                 .attrs = tsl2X7X_ALS_event_attrs,
1660                 .name = "events",
1661         },
1662         [PRX] = {
1663                 .attrs = tsl2X7X_PRX_event_attrs,
1664                 .name = "events",
1665         },
1666         [ALSPRX] = {
1667                 .attrs = tsl2X7X_ALSPRX_event_attrs,
1668                 .name = "events",
1669         },
1670 };
1671
1672 static const struct iio_info tsl2X7X_device_info[] = {
1673         [ALS] = {
1674                 .attrs = &tsl2X7X_device_attr_group_tbl[ALS],
1675                 .event_attrs = &tsl2X7X_event_attr_group_tbl[ALS],
1676                 .driver_module = THIS_MODULE,
1677                 .read_raw = &tsl2x7x_read_raw,
1678                 .write_raw = &tsl2x7x_write_raw,
1679                 .read_event_value = &tsl2x7x_read_thresh,
1680                 .write_event_value = &tsl2x7x_write_thresh,
1681                 .read_event_config = &tsl2x7x_read_interrupt_config,
1682                 .write_event_config = &tsl2x7x_write_interrupt_config,
1683         },
1684         [PRX] = {
1685                 .attrs = &tsl2X7X_device_attr_group_tbl[PRX],
1686                 .event_attrs = &tsl2X7X_event_attr_group_tbl[PRX],
1687                 .driver_module = THIS_MODULE,
1688                 .read_raw = &tsl2x7x_read_raw,
1689                 .write_raw = &tsl2x7x_write_raw,
1690                 .read_event_value = &tsl2x7x_read_thresh,
1691                 .write_event_value = &tsl2x7x_write_thresh,
1692                 .read_event_config = &tsl2x7x_read_interrupt_config,
1693                 .write_event_config = &tsl2x7x_write_interrupt_config,
1694         },
1695         [ALSPRX] = {
1696                 .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX],
1697                 .event_attrs = &tsl2X7X_event_attr_group_tbl[ALSPRX],
1698                 .driver_module = THIS_MODULE,
1699                 .read_raw = &tsl2x7x_read_raw,
1700                 .write_raw = &tsl2x7x_write_raw,
1701                 .read_event_value = &tsl2x7x_read_thresh,
1702                 .write_event_value = &tsl2x7x_write_thresh,
1703                 .read_event_config = &tsl2x7x_read_interrupt_config,
1704                 .write_event_config = &tsl2x7x_write_interrupt_config,
1705         },
1706         [PRX2] = {
1707                 .attrs = &tsl2X7X_device_attr_group_tbl[PRX2],
1708                 .event_attrs = &tsl2X7X_event_attr_group_tbl[PRX],
1709                 .driver_module = THIS_MODULE,
1710                 .read_raw = &tsl2x7x_read_raw,
1711                 .write_raw = &tsl2x7x_write_raw,
1712                 .read_event_value = &tsl2x7x_read_thresh,
1713                 .write_event_value = &tsl2x7x_write_thresh,
1714                 .read_event_config = &tsl2x7x_read_interrupt_config,
1715                 .write_event_config = &tsl2x7x_write_interrupt_config,
1716         },
1717         [ALSPRX2] = {
1718                 .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2],
1719                 .event_attrs = &tsl2X7X_event_attr_group_tbl[ALSPRX],
1720                 .driver_module = THIS_MODULE,
1721                 .read_raw = &tsl2x7x_read_raw,
1722                 .write_raw = &tsl2x7x_write_raw,
1723                 .read_event_value = &tsl2x7x_read_thresh,
1724                 .write_event_value = &tsl2x7x_write_thresh,
1725                 .read_event_config = &tsl2x7x_read_interrupt_config,
1726                 .write_event_config = &tsl2x7x_write_interrupt_config,
1727         },
1728 };
1729
1730 static const struct iio_event_spec tsl2x7x_events[] = {
1731         {
1732                 .type = IIO_EV_TYPE_THRESH,
1733                 .dir = IIO_EV_DIR_RISING,
1734                 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
1735                         BIT(IIO_EV_INFO_ENABLE),
1736         }, {
1737                 .type = IIO_EV_TYPE_THRESH,
1738                 .dir = IIO_EV_DIR_FALLING,
1739                 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
1740                         BIT(IIO_EV_INFO_ENABLE),
1741         },
1742 };
1743
1744 static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
1745         [ALS] = {
1746                 .channel = {
1747                         {
1748                         .type = IIO_LIGHT,
1749                         .indexed = 1,
1750                         .channel = 0,
1751                         .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1752                         }, {
1753                         .type = IIO_INTENSITY,
1754                         .indexed = 1,
1755                         .channel = 0,
1756                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1757                                 BIT(IIO_CHAN_INFO_CALIBSCALE) |
1758                                 BIT(IIO_CHAN_INFO_CALIBBIAS),
1759                         .event_spec = tsl2x7x_events,
1760                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1761                         }, {
1762                         .type = IIO_INTENSITY,
1763                         .indexed = 1,
1764                         .channel = 1,
1765                         },
1766                 },
1767         .chan_table_elements = 3,
1768         .info = &tsl2X7X_device_info[ALS],
1769         },
1770         [PRX] = {
1771                 .channel = {
1772                         {
1773                         .type = IIO_PROXIMITY,
1774                         .indexed = 1,
1775                         .channel = 0,
1776                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1777                         .event_spec = tsl2x7x_events,
1778                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1779                         },
1780                 },
1781         .chan_table_elements = 1,
1782         .info = &tsl2X7X_device_info[PRX],
1783         },
1784         [ALSPRX] = {
1785                 .channel = {
1786                         {
1787                         .type = IIO_LIGHT,
1788                         .indexed = 1,
1789                         .channel = 0,
1790                         .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED)
1791                         }, {
1792                         .type = IIO_INTENSITY,
1793                         .indexed = 1,
1794                         .channel = 0,
1795                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1796                                 BIT(IIO_CHAN_INFO_CALIBSCALE) |
1797                                 BIT(IIO_CHAN_INFO_CALIBBIAS),
1798                         .event_spec = tsl2x7x_events,
1799                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1800                         }, {
1801                         .type = IIO_INTENSITY,
1802                         .indexed = 1,
1803                         .channel = 1,
1804                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1805                         }, {
1806                         .type = IIO_PROXIMITY,
1807                         .indexed = 1,
1808                         .channel = 0,
1809                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1810                         .event_spec = tsl2x7x_events,
1811                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1812                         },
1813                 },
1814         .chan_table_elements = 4,
1815         .info = &tsl2X7X_device_info[ALSPRX],
1816         },
1817         [PRX2] = {
1818                 .channel = {
1819                         {
1820                         .type = IIO_PROXIMITY,
1821                         .indexed = 1,
1822                         .channel = 0,
1823                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1824                                 BIT(IIO_CHAN_INFO_CALIBSCALE),
1825                         .event_spec = tsl2x7x_events,
1826                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1827                         },
1828                 },
1829         .chan_table_elements = 1,
1830         .info = &tsl2X7X_device_info[PRX2],
1831         },
1832         [ALSPRX2] = {
1833                 .channel = {
1834                         {
1835                         .type = IIO_LIGHT,
1836                         .indexed = 1,
1837                         .channel = 0,
1838                         .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
1839                         }, {
1840                         .type = IIO_INTENSITY,
1841                         .indexed = 1,
1842                         .channel = 0,
1843                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1844                                 BIT(IIO_CHAN_INFO_CALIBSCALE) |
1845                                 BIT(IIO_CHAN_INFO_CALIBBIAS),
1846                         .event_spec = tsl2x7x_events,
1847                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1848                         }, {
1849                         .type = IIO_INTENSITY,
1850                         .indexed = 1,
1851                         .channel = 1,
1852                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
1853                         }, {
1854                         .type = IIO_PROXIMITY,
1855                         .indexed = 1,
1856                         .channel = 0,
1857                         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
1858                                 BIT(IIO_CHAN_INFO_CALIBSCALE),
1859                         .event_spec = tsl2x7x_events,
1860                         .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
1861                         },
1862                 },
1863         .chan_table_elements = 4,
1864         .info = &tsl2X7X_device_info[ALSPRX2],
1865         },
1866 };
1867
1868 static int tsl2x7x_probe(struct i2c_client *clientp,
1869         const struct i2c_device_id *id)
1870 {
1871         int ret;
1872         unsigned char device_id;
1873         struct iio_dev *indio_dev;
1874         struct tsl2X7X_chip *chip;
1875
1876         indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
1877         if (!indio_dev)
1878                 return -ENOMEM;
1879
1880         chip = iio_priv(indio_dev);
1881         chip->client = clientp;
1882         i2c_set_clientdata(clientp, indio_dev);
1883
1884         ret = tsl2x7x_i2c_read(chip->client,
1885                 TSL2X7X_CHIPID, &device_id);
1886         if (ret < 0)
1887                 return ret;
1888
1889         if ((!tsl2x7x_device_id(&device_id, id->driver_data)) ||
1890                 (tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) {
1891                 dev_info(&chip->client->dev,
1892                                 "%s: i2c device found does not match expected id\n",
1893                                 __func__);
1894                 return -EINVAL;
1895         }
1896
1897         ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
1898         if (ret < 0) {
1899                 dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n",
1900                                 __func__, ret);
1901                 return ret;
1902         }
1903
1904         /* ALS and PROX functions can be invoked via user space poll
1905          * or H/W interrupt. If busy return last sample. */
1906         mutex_init(&chip->als_mutex);
1907         mutex_init(&chip->prox_mutex);
1908
1909         chip->tsl2x7x_chip_status = TSL2X7X_CHIP_UNKNOWN;
1910         chip->pdata = clientp->dev.platform_data;
1911         chip->id = id->driver_data;
1912         chip->chip_info =
1913                 &tsl2x7x_chip_info_tbl[device_channel_config[id->driver_data]];
1914
1915         indio_dev->info = chip->chip_info->info;
1916         indio_dev->dev.parent = &clientp->dev;
1917         indio_dev->modes = INDIO_DIRECT_MODE;
1918         indio_dev->name = chip->client->name;
1919         indio_dev->channels = chip->chip_info->channel;
1920         indio_dev->num_channels = chip->chip_info->chan_table_elements;
1921
1922         if (clientp->irq) {
1923                 ret = devm_request_threaded_irq(&clientp->dev, clientp->irq,
1924                                                 NULL,
1925                                                 &tsl2x7x_event_handler,
1926                                                 IRQF_TRIGGER_RISING |
1927                                                 IRQF_ONESHOT,
1928                                                 "TSL2X7X_event",
1929                                                 indio_dev);
1930                 if (ret) {
1931                         dev_err(&clientp->dev,
1932                                 "%s: irq request failed", __func__);
1933                         return ret;
1934                 }
1935         }
1936
1937         /* Load up the defaults */
1938         tsl2x7x_defaults(chip);
1939         /* Make sure the chip is on */
1940         tsl2x7x_chip_on(indio_dev);
1941
1942         ret = iio_device_register(indio_dev);
1943         if (ret) {
1944                 dev_err(&clientp->dev,
1945                         "%s: iio registration failed\n", __func__);
1946                 return ret;
1947         }
1948
1949         dev_info(&clientp->dev, "%s Light sensor found.\n", id->name);
1950
1951         return 0;
1952 }
1953
1954 static int tsl2x7x_suspend(struct device *dev)
1955 {
1956         struct iio_dev *indio_dev = dev_get_drvdata(dev);
1957         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1958         int ret = 0;
1959
1960         if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
1961                 ret = tsl2x7x_chip_off(indio_dev);
1962                 chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED;
1963         }
1964
1965         if (chip->pdata && chip->pdata->platform_power) {
1966                 pm_message_t pmm = {PM_EVENT_SUSPEND};
1967                 chip->pdata->platform_power(dev, pmm);
1968         }
1969
1970         return ret;
1971 }
1972
1973 static int tsl2x7x_resume(struct device *dev)
1974 {
1975         struct iio_dev *indio_dev = dev_get_drvdata(dev);
1976         struct tsl2X7X_chip *chip = iio_priv(indio_dev);
1977         int ret = 0;
1978
1979         if (chip->pdata && chip->pdata->platform_power) {
1980                 pm_message_t pmm = {PM_EVENT_RESUME};
1981                 chip->pdata->platform_power(dev, pmm);
1982         }
1983
1984         if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_SUSPENDED)
1985                 ret = tsl2x7x_chip_on(indio_dev);
1986
1987         return ret;
1988 }
1989
1990 static int tsl2x7x_remove(struct i2c_client *client)
1991 {
1992         struct iio_dev *indio_dev = i2c_get_clientdata(client);
1993
1994         tsl2x7x_chip_off(indio_dev);
1995
1996         iio_device_unregister(indio_dev);
1997
1998         return 0;
1999 }
2000
2001 static struct i2c_device_id tsl2x7x_idtable[] = {
2002         { "tsl2571", tsl2571 },
2003         { "tsl2671", tsl2671 },
2004         { "tmd2671", tmd2671 },
2005         { "tsl2771", tsl2771 },
2006         { "tmd2771", tmd2771 },
2007         { "tsl2572", tsl2572 },
2008         { "tsl2672", tsl2672 },
2009         { "tmd2672", tmd2672 },
2010         { "tsl2772", tsl2772 },
2011         { "tmd2772", tmd2772 },
2012         {}
2013 };
2014
2015 MODULE_DEVICE_TABLE(i2c, tsl2x7x_idtable);
2016
2017 static const struct dev_pm_ops tsl2x7x_pm_ops = {
2018         .suspend = tsl2x7x_suspend,
2019         .resume  = tsl2x7x_resume,
2020 };
2021
2022 /* Driver definition */
2023 static struct i2c_driver tsl2x7x_driver = {
2024         .driver = {
2025                 .name = "tsl2x7x",
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");