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