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