veml6030.c (46e28867540434f94ddb745c74466f40669bcc48) veml6030.c (22eaca4283b216f5e1f7721e4ad0ecb3d23c6774)
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * VEML6030, VMEL6035 and VEML7700 Ambient Light Sensors
4 *
5 * Copyright (c) 2019, Rishi Gupta <gupt21@gmail.com>
6 *
7 * VEML6030:
8 * Datasheet: https://www.vishay.com/docs/84366/veml6030.pdf

--- 10 unchanged lines hidden (view full) ---

19
20#include <linux/bitfield.h>
21#include <linux/module.h>
22#include <linux/i2c.h>
23#include <linux/err.h>
24#include <linux/regmap.h>
25#include <linux/interrupt.h>
26#include <linux/pm_runtime.h>
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * VEML6030, VMEL6035 and VEML7700 Ambient Light Sensors
4 *
5 * Copyright (c) 2019, Rishi Gupta <gupt21@gmail.com>
6 *
7 * VEML6030:
8 * Datasheet: https://www.vishay.com/docs/84366/veml6030.pdf

--- 10 unchanged lines hidden (view full) ---

19
20#include <linux/bitfield.h>
21#include <linux/module.h>
22#include <linux/i2c.h>
23#include <linux/err.h>
24#include <linux/regmap.h>
25#include <linux/interrupt.h>
26#include <linux/pm_runtime.h>
27#include <linux/units.h>
27#include <linux/regulator/consumer.h>
28#include <linux/iio/iio.h>
29#include <linux/iio/sysfs.h>
30#include <linux/iio/events.h>
28#include <linux/regulator/consumer.h>
29#include <linux/iio/iio.h>
30#include <linux/iio/sysfs.h>
31#include <linux/iio/events.h>
32#include <linux/iio/iio-gts-helper.h>
31#include <linux/iio/trigger_consumer.h>
32#include <linux/iio/triggered_buffer.h>
33
34/* Device registers */
35#define VEML6030_REG_ALS_CONF 0x00
36#define VEML6030_REG_ALS_WH 0x01
37#define VEML6030_REG_ALS_WL 0x02
38#define VEML6030_REG_ALS_PSM 0x03

--- 21 unchanged lines hidden (view full) ---

60#define VEML6035_CHAN_EN BIT(2)
61
62/* Regfields */
63#define VEML6030_GAIN_RF REG_FIELD(VEML6030_REG_ALS_CONF, 11, 12)
64#define VEML6030_IT_RF REG_FIELD(VEML6030_REG_ALS_CONF, 6, 9)
65
66#define VEML6035_GAIN_RF REG_FIELD(VEML6030_REG_ALS_CONF, 10, 12)
67
33#include <linux/iio/trigger_consumer.h>
34#include <linux/iio/triggered_buffer.h>
35
36/* Device registers */
37#define VEML6030_REG_ALS_CONF 0x00
38#define VEML6030_REG_ALS_WH 0x01
39#define VEML6030_REG_ALS_WL 0x02
40#define VEML6030_REG_ALS_PSM 0x03

--- 21 unchanged lines hidden (view full) ---

62#define VEML6035_CHAN_EN BIT(2)
63
64/* Regfields */
65#define VEML6030_GAIN_RF REG_FIELD(VEML6030_REG_ALS_CONF, 11, 12)
66#define VEML6030_IT_RF REG_FIELD(VEML6030_REG_ALS_CONF, 6, 9)
67
68#define VEML6035_GAIN_RF REG_FIELD(VEML6030_REG_ALS_CONF, 10, 12)
69
70/* Maximum scales x 10000 to work with integers */
71#define VEML6030_MAX_SCALE 21504
72#define VEML6035_MAX_SCALE 4096
73
68enum veml6030_scan {
69 VEML6030_SCAN_ALS,
70 VEML6030_SCAN_WH,
71 VEML6030_SCAN_TIMESTAMP,
72};
73
74struct veml6030_rf {
75 struct regmap_field *it;
76 struct regmap_field *gain;
77};
78
79struct veml603x_chip {
80 const char *name;
74enum veml6030_scan {
75 VEML6030_SCAN_ALS,
76 VEML6030_SCAN_WH,
77 VEML6030_SCAN_TIMESTAMP,
78};
79
80struct veml6030_rf {
81 struct regmap_field *it;
82 struct regmap_field *gain;
83};
84
85struct veml603x_chip {
86 const char *name;
81 const int(*scale_vals)[][2];
82 const int num_scale_vals;
83 const struct iio_chan_spec *channels;
84 const int num_channels;
85 const struct reg_field gain_rf;
86 const struct reg_field it_rf;
87 const struct iio_chan_spec *channels;
88 const int num_channels;
89 const struct reg_field gain_rf;
90 const struct reg_field it_rf;
91 const int max_scale;
87 int (*hw_init)(struct iio_dev *indio_dev, struct device *dev);
88 int (*set_info)(struct iio_dev *indio_dev);
92 int (*hw_init)(struct iio_dev *indio_dev, struct device *dev);
93 int (*set_info)(struct iio_dev *indio_dev);
89 int (*set_als_gain)(struct iio_dev *indio_dev, int val, int val2);
90 int (*get_als_gain)(struct iio_dev *indio_dev, int *val, int *val2);
91};
92
93/*
94 * The resolution depends on both gain and integration time. The
95 * cur_resolution stores one of the resolution mentioned in the
96 * table during startup and gets updated whenever integration time
97 * or gain is changed.
98 *
99 * Table 'resolution and maximum detection range' in the appnotes
100 * is visualized as a 2D array. The cur_gain stores index of gain
101 * in this table (0-3 for VEML6030, 0-5 for VEML6035) while the
102 * cur_integration_time holds index of integration time (0-5).
103 */
104struct veml6030_data {
105 struct i2c_client *client;
106 struct regmap *regmap;
107 struct veml6030_rf rf;
94};
95
96/*
97 * The resolution depends on both gain and integration time. The
98 * cur_resolution stores one of the resolution mentioned in the
99 * table during startup and gets updated whenever integration time
100 * or gain is changed.
101 *
102 * Table 'resolution and maximum detection range' in the appnotes
103 * is visualized as a 2D array. The cur_gain stores index of gain
104 * in this table (0-3 for VEML6030, 0-5 for VEML6035) while the
105 * cur_integration_time holds index of integration time (0-5).
106 */
107struct veml6030_data {
108 struct i2c_client *client;
109 struct regmap *regmap;
110 struct veml6030_rf rf;
108 int cur_resolution;
109 int cur_gain;
110 int cur_integration_time;
111 const struct veml603x_chip *chip;
111 const struct veml603x_chip *chip;
112 struct iio_gts gts;
113
112};
113
114};
115
114static const int veml6030_it_times[][2] = {
115 { 0, 25000 },
116 { 0, 50000 },
117 { 0, 100000 },
118 { 0, 200000 },
119 { 0, 400000 },
120 { 0, 800000 },
116#define VEML6030_SEL_IT_25MS 0x0C
117#define VEML6030_SEL_IT_50MS 0x08
118#define VEML6030_SEL_IT_100MS 0x00
119#define VEML6030_SEL_IT_200MS 0x01
120#define VEML6030_SEL_IT_400MS 0x02
121#define VEML6030_SEL_IT_800MS 0x03
122static const struct iio_itime_sel_mul veml6030_it_sel[] = {
123 GAIN_SCALE_ITIME_US(25000, VEML6030_SEL_IT_25MS, 1),
124 GAIN_SCALE_ITIME_US(50000, VEML6030_SEL_IT_50MS, 2),
125 GAIN_SCALE_ITIME_US(100000, VEML6030_SEL_IT_100MS, 4),
126 GAIN_SCALE_ITIME_US(200000, VEML6030_SEL_IT_200MS, 8),
127 GAIN_SCALE_ITIME_US(400000, VEML6030_SEL_IT_400MS, 16),
128 GAIN_SCALE_ITIME_US(800000, VEML6030_SEL_IT_800MS, 32),
121};
122
129};
130
123/*
124 * Scale is 1/gain. Value 0.125 is ALS gain x (1/8), 0.25 is
125 * ALS gain x (1/4), 0.5 is ALS gain x (1/2), 1.0 is ALS gain x 1,
126 * 2.0 is ALS gain x2, and 4.0 is ALS gain x 4.
131/* Gains are multiplied by 8 to work with integers. The values in the
132 * iio-gts tables don't need corrections because the maximum value of
133 * the scale refers to GAIN = x1, and the rest of the values are
134 * obtained from the resulting linear function.
127 */
135 */
128static const int veml6030_scale_vals[][2] = {
129 { 0, 125000 },
130 { 0, 250000 },
131 { 1, 0 },
132 { 2, 0 },
136#define VEML6030_SEL_MILLI_GAIN_X125 2
137#define VEML6030_SEL_MILLI_GAIN_X250 3
138#define VEML6030_SEL_MILLI_GAIN_X1000 0
139#define VEML6030_SEL_MILLI_GAIN_X2000 1
140static const struct iio_gain_sel_pair veml6030_gain_sel[] = {
141 GAIN_SCALE_GAIN(1, VEML6030_SEL_MILLI_GAIN_X125),
142 GAIN_SCALE_GAIN(2, VEML6030_SEL_MILLI_GAIN_X250),
143 GAIN_SCALE_GAIN(8, VEML6030_SEL_MILLI_GAIN_X1000),
144 GAIN_SCALE_GAIN(16, VEML6030_SEL_MILLI_GAIN_X2000),
133};
134
145};
146
135static const int veml6035_scale_vals[][2] = {
136 { 0, 125000 },
137 { 0, 250000 },
138 { 0, 500000 },
139 { 1, 0 },
140 { 2, 0 },
141 { 4, 0 },
147#define VEML6035_SEL_MILLI_GAIN_X125 4
148#define VEML6035_SEL_MILLI_GAIN_X250 5
149#define VEML6035_SEL_MILLI_GAIN_X500 7
150#define VEML6035_SEL_MILLI_GAIN_X1000 0
151#define VEML6035_SEL_MILLI_GAIN_X2000 1
152#define VEML6035_SEL_MILLI_GAIN_X4000 3
153static const struct iio_gain_sel_pair veml6035_gain_sel[] = {
154 GAIN_SCALE_GAIN(1, VEML6035_SEL_MILLI_GAIN_X125),
155 GAIN_SCALE_GAIN(2, VEML6035_SEL_MILLI_GAIN_X250),
156 GAIN_SCALE_GAIN(4, VEML6035_SEL_MILLI_GAIN_X500),
157 GAIN_SCALE_GAIN(8, VEML6035_SEL_MILLI_GAIN_X1000),
158 GAIN_SCALE_GAIN(16, VEML6035_SEL_MILLI_GAIN_X2000),
159 GAIN_SCALE_GAIN(32, VEML6035_SEL_MILLI_GAIN_X4000),
142};
143
144/*
145 * Persistence = 1/2/4/8 x integration time
146 * Minimum time for which light readings must stay above configured
147 * threshold to assert the interrupt.
148 */
149static const char * const period_values[] = {

--- 217 unchanged lines hidden (view full) ---

367 .max_register = VEML6030_REG_ALS_INT,
368 .val_format_endian = REGMAP_ENDIAN_LITTLE,
369 .rd_table = &veml6030_readable_table,
370 .wr_table = &veml6030_writable_table,
371 .volatile_table = &veml6030_volatile_table,
372 .cache_type = REGCACHE_RBTREE,
373};
374
160};
161
162/*
163 * Persistence = 1/2/4/8 x integration time
164 * Minimum time for which light readings must stay above configured
165 * threshold to assert the interrupt.
166 */
167static const char * const period_values[] = {

--- 217 unchanged lines hidden (view full) ---

385 .max_register = VEML6030_REG_ALS_INT,
386 .val_format_endian = REGMAP_ENDIAN_LITTLE,
387 .rd_table = &veml6030_readable_table,
388 .wr_table = &veml6030_writable_table,
389 .volatile_table = &veml6030_volatile_table,
390 .cache_type = REGCACHE_RBTREE,
391};
392
375static int veml6030_get_intgrn_tm(struct iio_dev *indio_dev,
376 int *val, int *val2)
393static int veml6030_get_it(struct veml6030_data *data, int *val, int *val2)
377{
394{
378 int it_idx, ret;
379 struct veml6030_data *data = iio_priv(indio_dev);
395 int ret, it_idx;
380
381 ret = regmap_field_read(data->rf.it, &it_idx);
396
397 ret = regmap_field_read(data->rf.it, &it_idx);
382 if (ret) {
383 dev_err(&data->client->dev,
384 "can't read als conf register %d\n", ret);
398 if (ret)
385 return ret;
399 return ret;
386 }
387
400
388 switch (it_idx) {
389 case 0:
390 *val2 = 100000;
391 break;
392 case 1:
393 *val2 = 200000;
394 break;
395 case 2:
396 *val2 = 400000;
397 break;
398 case 3:
399 *val2 = 800000;
400 break;
401 case 8:
402 *val2 = 50000;
403 break;
404 case 12:
405 *val2 = 25000;
406 break;
407 default:
408 return -EINVAL;
409 }
401 ret = iio_gts_find_int_time_by_sel(&data->gts, it_idx);
402 if (ret < 0)
403 return ret;
410
404
405 *val2 = ret;
411 *val = 0;
406 *val = 0;
407
412 return IIO_VAL_INT_PLUS_MICRO;
413}
414
408 return IIO_VAL_INT_PLUS_MICRO;
409}
410
415static int veml6030_set_intgrn_tm(struct iio_dev *indio_dev,
416 int val, int val2)
411static int veml6030_set_it(struct iio_dev *indio_dev, int val, int val2)
417{
412{
418 int ret, new_int_time, int_idx;
419 struct veml6030_data *data = iio_priv(indio_dev);
413 struct veml6030_data *data = iio_priv(indio_dev);
414 int ret, gain_idx, it_idx, new_gain, prev_gain, prev_it;
415 bool in_range;
420
416
421 if (val)
417 if (val || !iio_gts_valid_time(&data->gts, val2))
422 return -EINVAL;
423
418 return -EINVAL;
419
424 switch (val2) {
425 case 25000:
426 new_int_time = 0x300;
427 int_idx = 5;
428 break;
429 case 50000:
430 new_int_time = 0x200;
431 int_idx = 4;
432 break;
433 case 100000:
434 new_int_time = 0x00;
435 int_idx = 3;
436 break;
437 case 200000:
438 new_int_time = 0x40;
439 int_idx = 2;
440 break;
441 case 400000:
442 new_int_time = 0x80;
443 int_idx = 1;
444 break;
445 case 800000:
446 new_int_time = 0xC0;
447 int_idx = 0;
448 break;
449 default:
450 return -EINVAL;
451 }
420 ret = regmap_field_read(data->rf.it, &it_idx);
421 if (ret)
422 return ret;
452
423
453 ret = regmap_field_write(data->rf.it, new_int_time);
454 if (ret) {
455 dev_err(&data->client->dev,
456 "can't update als integration time %d\n", ret);
424 ret = regmap_field_read(data->rf.gain, &gain_idx);
425 if (ret)
457 return ret;
426 return ret;
458 }
459
427
460 /*
461 * Cache current integration time and update resolution. For every
462 * increase in integration time to next level, resolution is halved
463 * and vice-versa.
464 */
465 if (data->cur_integration_time < int_idx)
466 data->cur_resolution <<= int_idx - data->cur_integration_time;
467 else if (data->cur_integration_time > int_idx)
468 data->cur_resolution >>= data->cur_integration_time - int_idx;
428 prev_it = iio_gts_find_int_time_by_sel(&data->gts, it_idx);
429 if (prev_it < 0)
430 return prev_it;
469
431
470 data->cur_integration_time = int_idx;
432 if (prev_it == val2)
433 return 0;
471
434
472 return ret;
435 prev_gain = iio_gts_find_gain_by_sel(&data->gts, gain_idx);
436 if (prev_gain < 0)
437 return prev_gain;
438
439 ret = iio_gts_find_new_gain_by_gain_time_min(&data->gts, prev_gain, prev_it,
440 val2, &new_gain, &in_range);
441 if (ret)
442 return ret;
443
444 if (!in_range)
445 dev_dbg(&data->client->dev, "Optimal gain out of range\n");
446
447 ret = iio_gts_find_sel_by_int_time(&data->gts, val2);
448 if (ret < 0)
449 return ret;
450
451 ret = regmap_field_write(data->rf.it, ret);
452 if (ret)
453 return ret;
454
455 ret = iio_gts_find_sel_by_gain(&data->gts, new_gain);
456 if (ret < 0)
457 return ret;
458
459 return regmap_field_write(data->rf.gain, ret);
473}
474
475static int veml6030_read_persistence(struct iio_dev *indio_dev,
476 int *val, int *val2)
477{
478 int ret, reg, period, x, y;
479 struct veml6030_data *data = iio_priv(indio_dev);
480
460}
461
462static int veml6030_read_persistence(struct iio_dev *indio_dev,
463 int *val, int *val2)
464{
465 int ret, reg, period, x, y;
466 struct veml6030_data *data = iio_priv(indio_dev);
467
481 ret = veml6030_get_intgrn_tm(indio_dev, &x, &y);
468 ret = veml6030_get_it(data, &x, &y);
482 if (ret < 0)
483 return ret;
484
485 ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
486 if (ret) {
487 dev_err(&data->client->dev,
488 "can't read als conf register %d\n", ret);
489 }

--- 8 unchanged lines hidden (view full) ---

498}
499
500static int veml6030_write_persistence(struct iio_dev *indio_dev,
501 int val, int val2)
502{
503 int ret, period, x, y;
504 struct veml6030_data *data = iio_priv(indio_dev);
505
469 if (ret < 0)
470 return ret;
471
472 ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
473 if (ret) {
474 dev_err(&data->client->dev,
475 "can't read als conf register %d\n", ret);
476 }

--- 8 unchanged lines hidden (view full) ---

485}
486
487static int veml6030_write_persistence(struct iio_dev *indio_dev,
488 int val, int val2)
489{
490 int ret, period, x, y;
491 struct veml6030_data *data = iio_priv(indio_dev);
492
506 ret = veml6030_get_intgrn_tm(indio_dev, &x, &y);
493 ret = veml6030_get_it(data, &x, &y);
507 if (ret < 0)
508 return ret;
509
510 if (!val) {
511 period = val2 / y;
512 } else {
513 if ((val == 1) && (val2 == 600000))
514 period = 1600000 / y;

--- 12 unchanged lines hidden (view full) ---

527 VEML6030_ALS_PERS, (ffs(period) - 1) << 4);
528 if (ret)
529 dev_err(&data->client->dev,
530 "can't set persistence value %d\n", ret);
531
532 return ret;
533}
534
494 if (ret < 0)
495 return ret;
496
497 if (!val) {
498 period = val2 / y;
499 } else {
500 if ((val == 1) && (val2 == 600000))
501 period = 1600000 / y;

--- 12 unchanged lines hidden (view full) ---

514 VEML6030_ALS_PERS, (ffs(period) - 1) << 4);
515 if (ret)
516 dev_err(&data->client->dev,
517 "can't set persistence value %d\n", ret);
518
519 return ret;
520}
521
535/*
536 * Cache currently set gain & update resolution. For every
537 * increase in the gain to next level, resolution is halved
538 * and vice-versa.
539 */
540static void veml6030_update_gain_res(struct veml6030_data *data, int gain_idx)
522static int veml6030_set_scale(struct iio_dev *indio_dev, int val, int val2)
541{
523{
542 if (data->cur_gain < gain_idx)
543 data->cur_resolution <<= gain_idx - data->cur_gain;
544 else if (data->cur_gain > gain_idx)
545 data->cur_resolution >>= data->cur_gain - gain_idx;
546
547 data->cur_gain = gain_idx;
548}
549
550static int veml6030_set_als_gain(struct iio_dev *indio_dev,
551 int val, int val2)
552{
553 int ret, new_gain, gain_idx;
524 int ret, gain_sel, it_idx, it_sel;
554 struct veml6030_data *data = iio_priv(indio_dev);
555
525 struct veml6030_data *data = iio_priv(indio_dev);
526
556 if (val == 0 && val2 == 125000) {
557 new_gain = 0x01;
558 gain_idx = 3;
559 } else if (val == 0 && val2 == 250000) {
560 new_gain = 0x11;
561 gain_idx = 2;
562 } else if (val == 1 && val2 == 0) {
563 new_gain = 0x00;
564 gain_idx = 1;
565 } else if (val == 2 && val2 == 0) {
566 new_gain = 0x01;
567 gain_idx = 0;
568 } else {
569 return -EINVAL;
570 }
571
572 ret = regmap_field_write(data->rf.gain, new_gain);
573 if (ret) {
574 dev_err(&data->client->dev,
575 "can't set als gain %d\n", ret);
527 ret = regmap_field_read(data->rf.it, &it_idx);
528 if (ret)
576 return ret;
529 return ret;
577 }
578
530
579 veml6030_update_gain_res(data, gain_idx);
580
581 return 0;
582}
583
584static int veml6035_set_als_gain(struct iio_dev *indio_dev, int val, int val2)
585{
586 int ret, new_gain, gain_idx;
587 struct veml6030_data *data = iio_priv(indio_dev);
588
589 if (val == 0 && val2 == 125000) {
590 new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS);
591 gain_idx = 5;
592 } else if (val == 0 && val2 == 250000) {
593 new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS |
594 VEML6035_GAIN);
595 gain_idx = 4;
596 } else if (val == 0 && val2 == 500000) {
597 new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS |
598 VEML6035_GAIN | VEML6035_DG);
599 gain_idx = 3;
600 } else if (val == 1 && val2 == 0) {
601 new_gain = 0x0000;
602 gain_idx = 2;
603 } else if (val == 2 && val2 == 0) {
604 new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN);
605 gain_idx = 1;
606 } else if (val == 4 && val2 == 0) {
607 new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN |
608 VEML6035_DG);
609 gain_idx = 0;
610 } else {
611 return -EINVAL;
612 }
613
614 ret = regmap_field_write(data->rf.gain, new_gain);
615 if (ret) {
616 dev_err(&data->client->dev, "can't set als gain %d\n", ret);
531 ret = iio_gts_find_gain_time_sel_for_scale(&data->gts, val, val2,
532 &gain_sel, &it_sel);
533 if (ret)
617 return ret;
534 return ret;
618 }
619
535
620 veml6030_update_gain_res(data, gain_idx);
621
622 return 0;
623}
624
625static int veml6030_get_als_gain(struct iio_dev *indio_dev,
626 int *val, int *val2)
627{
628 int gain, ret;
629 struct veml6030_data *data = iio_priv(indio_dev);
630
631 ret = regmap_field_read(data->rf.gain, &gain);
632 if (ret) {
633 dev_err(&data->client->dev,
634 "can't read als conf register %d\n", ret);
536 ret = regmap_field_write(data->rf.it, it_sel);
537 if (ret)
635 return ret;
538 return ret;
636 }
637
539
638 switch (gain) {
639 case 0:
640 *val = 1;
641 *val2 = 0;
642 break;
643 case 1:
644 *val = 2;
645 *val2 = 0;
646 break;
647 case 2:
648 *val = 0;
649 *val2 = 125000;
650 break;
651 case 3:
652 *val = 0;
653 *val2 = 250000;
654 break;
655 default:
656 return -EINVAL;
657 }
658
659 return IIO_VAL_INT_PLUS_MICRO;
660}
661
662static int veml6035_get_als_gain(struct iio_dev *indio_dev, int *val, int *val2)
663{
664 int gain, ret;
665 struct veml6030_data *data = iio_priv(indio_dev);
666
667 ret = regmap_field_read(data->rf.gain, &gain);
668 if (ret) {
669 dev_err(&data->client->dev,
670 "can't read als conf register %d\n", ret);
540 ret = regmap_field_write(data->rf.gain, gain_sel);
541 if (ret)
671 return ret;
542 return ret;
672 }
673
543
674 switch (gain) {
675 case 0:
676 *val = 1;
677 *val2 = 0;
678 break;
679 case 1:
680 case 2:
681 *val = 2;
682 *val2 = 0;
683 break;
684 case 3:
685 *val = 4;
686 *val2 = 0;
687 break;
688 case 4:
689 *val = 0;
690 *val2 = 125000;
691 break;
692 case 5:
693 case 6:
694 *val = 0;
695 *val2 = 250000;
696 break;
697 case 7:
698 *val = 0;
699 *val2 = 500000;
700 break;
701 default:
702 return -EINVAL;
703 }
704
705 return IIO_VAL_INT_PLUS_MICRO;
544 return 0;
706}
707
708static int veml6030_read_thresh(struct iio_dev *indio_dev,
709 int *val, int *val2, int dir)
710{
711 int ret, reg;
712 struct veml6030_data *data = iio_priv(indio_dev);
713

--- 30 unchanged lines hidden (view full) ---

744 if (ret)
745 dev_err(&data->client->dev,
746 "can't set low threshold %d\n", ret);
747 }
748
749 return ret;
750}
751
545}
546
547static int veml6030_read_thresh(struct iio_dev *indio_dev,
548 int *val, int *val2, int dir)
549{
550 int ret, reg;
551 struct veml6030_data *data = iio_priv(indio_dev);
552

--- 30 unchanged lines hidden (view full) ---

583 if (ret)
584 dev_err(&data->client->dev,
585 "can't set low threshold %d\n", ret);
586 }
587
588 return ret;
589}
590
591static int veml6030_get_total_gain(struct veml6030_data *data)
592{
593 int gain, it, reg, ret;
594
595 ret = regmap_field_read(data->rf.gain, &reg);
596 if (ret)
597 return ret;
598
599 gain = iio_gts_find_gain_by_sel(&data->gts, reg);
600 if (gain < 0)
601 return gain;
602
603 ret = regmap_field_read(data->rf.it, &reg);
604 if (ret)
605 return ret;
606
607 it = iio_gts_find_int_time_by_sel(&data->gts, reg);
608 if (it < 0)
609 return it;
610
611 return iio_gts_get_total_gain(&data->gts, gain, it);
612}
613
614static int veml6030_get_scale(struct veml6030_data *data, int *val, int *val2)
615{
616 int gain, it, reg, ret;
617
618 ret = regmap_field_read(data->rf.gain, &reg);
619 if (ret)
620 return ret;
621
622 gain = iio_gts_find_gain_by_sel(&data->gts, reg);
623 if (gain < 0)
624 return gain;
625
626 ret = regmap_field_read(data->rf.it, &reg);
627 if (ret)
628 return ret;
629
630 it = iio_gts_find_int_time_by_sel(&data->gts, reg);
631 if (it < 0)
632 return it;
633
634 ret = iio_gts_get_scale(&data->gts, gain, it, val, val2);
635 if (ret)
636 return ret;
637
638 return IIO_VAL_INT_PLUS_NANO;
639}
640
641static int veml6030_process_als(struct veml6030_data *data, int raw,
642 int *val, int *val2)
643{
644 int total_gain;
645
646 total_gain = veml6030_get_total_gain(data);
647 if (total_gain < 0)
648 return total_gain;
649
650 *val = raw * data->chip->max_scale / total_gain / 10000;
651 *val2 = raw * data->chip->max_scale / total_gain % 10000 * 100;
652
653 return IIO_VAL_INT_PLUS_MICRO;
654}
655
752/*
753 * Provide both raw as well as light reading in lux.
754 * light (in lux) = resolution * raw reading
755 */
756static int veml6030_read_raw(struct iio_dev *indio_dev,
757 struct iio_chan_spec const *chan, int *val,
758 int *val2, long mask)
759{

--- 7 unchanged lines hidden (view full) ---

767 case IIO_CHAN_INFO_PROCESSED:
768 switch (chan->type) {
769 case IIO_LIGHT:
770 ret = regmap_read(regmap, VEML6030_REG_ALS_DATA, &reg);
771 if (ret < 0) {
772 dev_err(dev, "can't read als data %d\n", ret);
773 return ret;
774 }
656/*
657 * Provide both raw as well as light reading in lux.
658 * light (in lux) = resolution * raw reading
659 */
660static int veml6030_read_raw(struct iio_dev *indio_dev,
661 struct iio_chan_spec const *chan, int *val,
662 int *val2, long mask)
663{

--- 7 unchanged lines hidden (view full) ---

671 case IIO_CHAN_INFO_PROCESSED:
672 switch (chan->type) {
673 case IIO_LIGHT:
674 ret = regmap_read(regmap, VEML6030_REG_ALS_DATA, &reg);
675 if (ret < 0) {
676 dev_err(dev, "can't read als data %d\n", ret);
677 return ret;
678 }
775 if (mask == IIO_CHAN_INFO_PROCESSED) {
776 *val = (reg * data->cur_resolution) / 10000;
777 *val2 = (reg * data->cur_resolution) % 10000 * 100;
778 return IIO_VAL_INT_PLUS_MICRO;
779 }
679 if (mask == IIO_CHAN_INFO_PROCESSED)
680 return veml6030_process_als(data, reg, val, val2);
681
780 *val = reg;
781 return IIO_VAL_INT;
782 case IIO_INTENSITY:
783 ret = regmap_read(regmap, VEML6030_REG_WH_DATA, &reg);
784 if (ret < 0) {
785 dev_err(dev, "can't read white data %d\n", ret);
786 return ret;
787 }
788 *val = reg;
789 return IIO_VAL_INT;
790 default:
791 return -EINVAL;
792 }
793 case IIO_CHAN_INFO_INT_TIME:
682 *val = reg;
683 return IIO_VAL_INT;
684 case IIO_INTENSITY:
685 ret = regmap_read(regmap, VEML6030_REG_WH_DATA, &reg);
686 if (ret < 0) {
687 dev_err(dev, "can't read white data %d\n", ret);
688 return ret;
689 }
690 *val = reg;
691 return IIO_VAL_INT;
692 default:
693 return -EINVAL;
694 }
695 case IIO_CHAN_INFO_INT_TIME:
794 return veml6030_get_intgrn_tm(indio_dev, val, val2);
696 return veml6030_get_it(data, val, val2);
795 case IIO_CHAN_INFO_SCALE:
697 case IIO_CHAN_INFO_SCALE:
796 return data->chip->get_als_gain(indio_dev, val, val2);
698 return veml6030_get_scale(data, val, val2);
797 default:
798 return -EINVAL;
799 }
800}
801
802static int veml6030_read_avail(struct iio_dev *indio_dev,
803 struct iio_chan_spec const *chan,
804 const int **vals, int *type, int *length,
805 long mask)
806{
807 struct veml6030_data *data = iio_priv(indio_dev);
808
809 switch (mask) {
810 case IIO_CHAN_INFO_INT_TIME:
699 default:
700 return -EINVAL;
701 }
702}
703
704static int veml6030_read_avail(struct iio_dev *indio_dev,
705 struct iio_chan_spec const *chan,
706 const int **vals, int *type, int *length,
707 long mask)
708{
709 struct veml6030_data *data = iio_priv(indio_dev);
710
711 switch (mask) {
712 case IIO_CHAN_INFO_INT_TIME:
811 *vals = (int *)&veml6030_it_times;
812 *length = 2 * ARRAY_SIZE(veml6030_it_times);
813 *type = IIO_VAL_INT_PLUS_MICRO;
814 return IIO_AVAIL_LIST;
713 return iio_gts_avail_times(&data->gts, vals, type, length);
815 case IIO_CHAN_INFO_SCALE:
714 case IIO_CHAN_INFO_SCALE:
816 *vals = (int *)*data->chip->scale_vals;
817 *length = 2 * data->chip->num_scale_vals;
818 *type = IIO_VAL_INT_PLUS_MICRO;
819 return IIO_AVAIL_LIST;
715 return iio_gts_all_avail_scales(&data->gts, vals, type, length);
820 }
821
822 return -EINVAL;
823}
824
825static int veml6030_write_raw(struct iio_dev *indio_dev,
826 struct iio_chan_spec const *chan,
827 int val, int val2, long mask)
828{
716 }
717
718 return -EINVAL;
719}
720
721static int veml6030_write_raw(struct iio_dev *indio_dev,
722 struct iio_chan_spec const *chan,
723 int val, int val2, long mask)
724{
829 struct veml6030_data *data = iio_priv(indio_dev);
830
831 switch (mask) {
832 case IIO_CHAN_INFO_INT_TIME:
725 switch (mask) {
726 case IIO_CHAN_INFO_INT_TIME:
833 return veml6030_set_intgrn_tm(indio_dev, val, val2);
727 return veml6030_set_it(indio_dev, val, val2);
834 case IIO_CHAN_INFO_SCALE:
728 case IIO_CHAN_INFO_SCALE:
835 return data->chip->set_als_gain(indio_dev, val, val2);
729 return veml6030_set_scale(indio_dev, val, val2);
836 default:
837 return -EINVAL;
838 }
839}
840
730 default:
731 return -EINVAL;
732 }
733}
734
735static int veml6030_write_raw_get_fmt(struct iio_dev *indio_dev,
736 struct iio_chan_spec const *chan,
737 long mask)
738{
739 switch (mask) {
740 case IIO_CHAN_INFO_SCALE:
741 return IIO_VAL_INT_PLUS_NANO;
742 case IIO_CHAN_INFO_INT_TIME:
743 return IIO_VAL_INT_PLUS_MICRO;
744 default:
745 return -EINVAL;
746 }
747}
748
841static int veml6030_read_event_val(struct iio_dev *indio_dev,
842 const struct iio_chan_spec *chan, enum iio_event_type type,
843 enum iio_event_direction dir, enum iio_event_info info,
844 int *val, int *val2)
845{
846 switch (info) {
847 case IIO_EV_INFO_VALUE:
848 switch (dir) {

--- 76 unchanged lines hidden (view full) ---

925
926 return ret;
927}
928
929static const struct iio_info veml6030_info = {
930 .read_raw = veml6030_read_raw,
931 .read_avail = veml6030_read_avail,
932 .write_raw = veml6030_write_raw,
749static int veml6030_read_event_val(struct iio_dev *indio_dev,
750 const struct iio_chan_spec *chan, enum iio_event_type type,
751 enum iio_event_direction dir, enum iio_event_info info,
752 int *val, int *val2)
753{
754 switch (info) {
755 case IIO_EV_INFO_VALUE:
756 switch (dir) {

--- 76 unchanged lines hidden (view full) ---

833
834 return ret;
835}
836
837static const struct iio_info veml6030_info = {
838 .read_raw = veml6030_read_raw,
839 .read_avail = veml6030_read_avail,
840 .write_raw = veml6030_write_raw,
841 .write_raw_get_fmt = veml6030_write_raw_get_fmt,
933 .read_event_value = veml6030_read_event_val,
934 .write_event_value = veml6030_write_event_val,
935 .read_event_config = veml6030_read_interrupt_config,
936 .write_event_config = veml6030_write_interrupt_config,
937 .event_attrs = &veml6030_event_attr_group,
938};
939
940static const struct iio_info veml6030_info_no_irq = {
941 .read_raw = veml6030_read_raw,
942 .read_avail = veml6030_read_avail,
943 .write_raw = veml6030_write_raw,
842 .read_event_value = veml6030_read_event_val,
843 .write_event_value = veml6030_write_event_val,
844 .read_event_config = veml6030_read_interrupt_config,
845 .write_event_config = veml6030_write_interrupt_config,
846 .event_attrs = &veml6030_event_attr_group,
847};
848
849static const struct iio_info veml6030_info_no_irq = {
850 .read_raw = veml6030_read_raw,
851 .read_avail = veml6030_read_avail,
852 .write_raw = veml6030_write_raw,
853 .write_raw_get_fmt = veml6030_write_raw_get_fmt,
944};
945
946static irqreturn_t veml6030_event_handler(int irq, void *private)
947{
948 int ret, reg, evtdir;
949 struct iio_dev *indio_dev = private;
950 struct veml6030_data *data = iio_priv(indio_dev);
951

--- 109 unchanged lines hidden (view full) ---

1061 * interrupt disabled by default. First shutdown the sensor,
1062 * update registers and then power on the sensor.
1063 */
1064static int veml6030_hw_init(struct iio_dev *indio_dev, struct device *dev)
1065{
1066 int ret, val;
1067 struct veml6030_data *data = iio_priv(indio_dev);
1068
854};
855
856static irqreturn_t veml6030_event_handler(int irq, void *private)
857{
858 int ret, reg, evtdir;
859 struct iio_dev *indio_dev = private;
860 struct veml6030_data *data = iio_priv(indio_dev);
861

--- 109 unchanged lines hidden (view full) ---

971 * interrupt disabled by default. First shutdown the sensor,
972 * update registers and then power on the sensor.
973 */
974static int veml6030_hw_init(struct iio_dev *indio_dev, struct device *dev)
975{
976 int ret, val;
977 struct veml6030_data *data = iio_priv(indio_dev);
978
979 ret = devm_iio_init_iio_gts(dev, 2, 150400000,
980 veml6030_gain_sel, ARRAY_SIZE(veml6030_gain_sel),
981 veml6030_it_sel, ARRAY_SIZE(veml6030_it_sel),
982 &data->gts);
983 if (ret)
984 return dev_err_probe(dev, ret, "failed to init iio gts\n");
985
1069 ret = veml6030_als_shut_down(data);
1070 if (ret)
1071 return dev_err_probe(dev, ret, "can't shutdown als\n");
1072
1073 ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, 0x1001);
1074 if (ret)
1075 return dev_err_probe(dev, ret, "can't setup als configs\n");
1076

--- 19 unchanged lines hidden (view full) ---

1096 return ret;
1097
1098 /* Clear stale interrupt status bits if any during start */
1099 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val);
1100 if (ret < 0)
1101 return dev_err_probe(dev, ret,
1102 "can't clear als interrupt status\n");
1103
986 ret = veml6030_als_shut_down(data);
987 if (ret)
988 return dev_err_probe(dev, ret, "can't shutdown als\n");
989
990 ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, 0x1001);
991 if (ret)
992 return dev_err_probe(dev, ret, "can't setup als configs\n");
993

--- 19 unchanged lines hidden (view full) ---

1013 return ret;
1014
1015 /* Clear stale interrupt status bits if any during start */
1016 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val);
1017 if (ret < 0)
1018 return dev_err_probe(dev, ret,
1019 "can't clear als interrupt status\n");
1020
1104 /* Cache currently active measurement parameters */
1105 data->cur_gain = 3;
1106 data->cur_resolution = 5376;
1107 data->cur_integration_time = 3;
1108
1109 return ret;
1110}
1111
1112/*
1113 * Set ALS gain to 1/8, integration time to 100 ms, ALS and WHITE
1114 * channel enabled, ALS channel interrupt, PSM enabled,
1115 * PSM_WAIT = 0.8 s, persistence to 1 x integration time and the
1116 * threshold interrupt disabled by default. First shutdown the sensor,
1117 * update registers and then power on the sensor.
1118 */
1119static int veml6035_hw_init(struct iio_dev *indio_dev, struct device *dev)
1120{
1121 int ret, val;
1122 struct veml6030_data *data = iio_priv(indio_dev);
1123
1021 return ret;
1022}
1023
1024/*
1025 * Set ALS gain to 1/8, integration time to 100 ms, ALS and WHITE
1026 * channel enabled, ALS channel interrupt, PSM enabled,
1027 * PSM_WAIT = 0.8 s, persistence to 1 x integration time and the
1028 * threshold interrupt disabled by default. First shutdown the sensor,
1029 * update registers and then power on the sensor.
1030 */
1031static int veml6035_hw_init(struct iio_dev *indio_dev, struct device *dev)
1032{
1033 int ret, val;
1034 struct veml6030_data *data = iio_priv(indio_dev);
1035
1036 ret = devm_iio_init_iio_gts(dev, 0, 409600000,
1037 veml6035_gain_sel, ARRAY_SIZE(veml6035_gain_sel),
1038 veml6030_it_sel, ARRAY_SIZE(veml6030_it_sel),
1039 &data->gts);
1040 if (ret)
1041 return dev_err_probe(dev, ret, "failed to init iio gts\n");
1042
1124 ret = veml6030_als_shut_down(data);
1125 if (ret)
1126 return dev_err_probe(dev, ret, "can't shutdown als\n");
1127
1128 ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF,
1129 VEML6035_SENS | VEML6035_CHAN_EN | VEML6030_ALS_SD);
1130 if (ret)
1131 return dev_err_probe(dev, ret, "can't setup als configs\n");

--- 20 unchanged lines hidden (view full) ---

1152 return ret;
1153
1154 /* Clear stale interrupt status bits if any during start */
1155 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val);
1156 if (ret < 0)
1157 return dev_err_probe(dev, ret,
1158 "can't clear als interrupt status\n");
1159
1043 ret = veml6030_als_shut_down(data);
1044 if (ret)
1045 return dev_err_probe(dev, ret, "can't shutdown als\n");
1046
1047 ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF,
1048 VEML6035_SENS | VEML6035_CHAN_EN | VEML6030_ALS_SD);
1049 if (ret)
1050 return dev_err_probe(dev, ret, "can't setup als configs\n");

--- 20 unchanged lines hidden (view full) ---

1071 return ret;
1072
1073 /* Clear stale interrupt status bits if any during start */
1074 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val);
1075 if (ret < 0)
1076 return dev_err_probe(dev, ret,
1077 "can't clear als interrupt status\n");
1078
1160 /* Cache currently active measurement parameters */
1161 data->cur_gain = 5;
1162 data->cur_resolution = 1024;
1163 data->cur_integration_time = 3;
1164
1165 return 0;
1166}
1167
1168static int veml6030_probe(struct i2c_client *client)
1169{
1170 int ret;
1171 struct veml6030_data *data;
1172 struct iio_dev *indio_dev;

--- 79 unchanged lines hidden (view full) ---

1252 return ret;
1253}
1254
1255static DEFINE_RUNTIME_DEV_PM_OPS(veml6030_pm_ops, veml6030_runtime_suspend,
1256 veml6030_runtime_resume, NULL);
1257
1258static const struct veml603x_chip veml6030_chip = {
1259 .name = "veml6030",
1079 return 0;
1080}
1081
1082static int veml6030_probe(struct i2c_client *client)
1083{
1084 int ret;
1085 struct veml6030_data *data;
1086 struct iio_dev *indio_dev;

--- 79 unchanged lines hidden (view full) ---

1166 return ret;
1167}
1168
1169static DEFINE_RUNTIME_DEV_PM_OPS(veml6030_pm_ops, veml6030_runtime_suspend,
1170 veml6030_runtime_resume, NULL);
1171
1172static const struct veml603x_chip veml6030_chip = {
1173 .name = "veml6030",
1260 .scale_vals = &veml6030_scale_vals,
1261 .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
1262 .channels = veml6030_channels,
1263 .num_channels = ARRAY_SIZE(veml6030_channels),
1264 .gain_rf = VEML6030_GAIN_RF,
1265 .it_rf = VEML6030_IT_RF,
1174 .channels = veml6030_channels,
1175 .num_channels = ARRAY_SIZE(veml6030_channels),
1176 .gain_rf = VEML6030_GAIN_RF,
1177 .it_rf = VEML6030_IT_RF,
1178 .max_scale = VEML6030_MAX_SCALE,
1266 .hw_init = veml6030_hw_init,
1267 .set_info = veml6030_set_info,
1179 .hw_init = veml6030_hw_init,
1180 .set_info = veml6030_set_info,
1268 .set_als_gain = veml6030_set_als_gain,
1269 .get_als_gain = veml6030_get_als_gain,
1270};
1271
1272static const struct veml603x_chip veml6035_chip = {
1273 .name = "veml6035",
1181};
1182
1183static const struct veml603x_chip veml6035_chip = {
1184 .name = "veml6035",
1274 .scale_vals = &veml6035_scale_vals,
1275 .num_scale_vals = ARRAY_SIZE(veml6035_scale_vals),
1276 .channels = veml6030_channels,
1277 .num_channels = ARRAY_SIZE(veml6030_channels),
1278 .gain_rf = VEML6035_GAIN_RF,
1279 .it_rf = VEML6030_IT_RF,
1185 .channels = veml6030_channels,
1186 .num_channels = ARRAY_SIZE(veml6030_channels),
1187 .gain_rf = VEML6035_GAIN_RF,
1188 .it_rf = VEML6030_IT_RF,
1189 .max_scale = VEML6035_MAX_SCALE,
1280 .hw_init = veml6035_hw_init,
1281 .set_info = veml6030_set_info,
1190 .hw_init = veml6035_hw_init,
1191 .set_info = veml6030_set_info,
1282 .set_als_gain = veml6035_set_als_gain,
1283 .get_als_gain = veml6035_get_als_gain,
1284};
1285
1286static const struct veml603x_chip veml7700_chip = {
1287 .name = "veml7700",
1192};
1193
1194static const struct veml603x_chip veml7700_chip = {
1195 .name = "veml7700",
1288 .scale_vals = &veml6030_scale_vals,
1289 .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
1290 .channels = veml7700_channels,
1291 .num_channels = ARRAY_SIZE(veml7700_channels),
1292 .gain_rf = VEML6030_GAIN_RF,
1293 .it_rf = VEML6030_IT_RF,
1196 .channels = veml7700_channels,
1197 .num_channels = ARRAY_SIZE(veml7700_channels),
1198 .gain_rf = VEML6030_GAIN_RF,
1199 .it_rf = VEML6030_IT_RF,
1200 .max_scale = VEML6030_MAX_SCALE,
1294 .hw_init = veml6030_hw_init,
1295 .set_info = veml7700_set_info,
1201 .hw_init = veml6030_hw_init,
1202 .set_info = veml7700_set_info,
1296 .set_als_gain = veml6030_set_als_gain,
1297 .get_als_gain = veml6030_get_als_gain,
1298};
1299
1300static const struct of_device_id veml6030_of_match[] = {
1301 {
1302 .compatible = "vishay,veml6030",
1303 .data = &veml6030_chip,
1304 },
1305 {

--- 25 unchanged lines hidden (view full) ---

1331 .probe = veml6030_probe,
1332 .id_table = veml6030_id,
1333};
1334module_i2c_driver(veml6030_driver);
1335
1336MODULE_AUTHOR("Rishi Gupta <gupt21@gmail.com>");
1337MODULE_DESCRIPTION("VEML6030 Ambient Light Sensor");
1338MODULE_LICENSE("GPL v2");
1203};
1204
1205static const struct of_device_id veml6030_of_match[] = {
1206 {
1207 .compatible = "vishay,veml6030",
1208 .data = &veml6030_chip,
1209 },
1210 {

--- 25 unchanged lines hidden (view full) ---

1236 .probe = veml6030_probe,
1237 .id_table = veml6030_id,
1238};
1239module_i2c_driver(veml6030_driver);
1240
1241MODULE_AUTHOR("Rishi Gupta <gupt21@gmail.com>");
1242MODULE_DESCRIPTION("VEML6030 Ambient Light Sensor");
1243MODULE_LICENSE("GPL v2");
1244MODULE_IMPORT_NS("IIO_GTS_HELPER");