accel/ivpu: Move recovery work to system_unbound_wq
[drm/drm-misc.git] / drivers / iio / light / veml6030.c
blobccb43dfd5cf782fe9cd99f022732a65741a034e2
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * VEML6030, VMEL6035 and VEML7700 Ambient Light Sensors
5 * Copyright (c) 2019, Rishi Gupta <gupt21@gmail.com>
7 * VEML6030:
8 * Datasheet: https://www.vishay.com/docs/84366/veml6030.pdf
9 * Appnote-84367: https://www.vishay.com/docs/84367/designingveml6030.pdf
11 * VEML6035:
12 * Datasheet: https://www.vishay.com/docs/84889/veml6035.pdf
13 * Appnote-84944: https://www.vishay.com/docs/84944/designingveml6035.pdf
15 * VEML7700:
16 * Datasheet: https://www.vishay.com/docs/84286/veml7700.pdf
17 * Appnote-84323: https://www.vishay.com/docs/84323/designingveml7700.pdf
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/regulator/consumer.h>
28 #include <linux/iio/iio.h>
29 #include <linux/iio/sysfs.h>
30 #include <linux/iio/events.h>
32 /* Device registers */
33 #define VEML6030_REG_ALS_CONF 0x00
34 #define VEML6030_REG_ALS_WH 0x01
35 #define VEML6030_REG_ALS_WL 0x02
36 #define VEML6030_REG_ALS_PSM 0x03
37 #define VEML6030_REG_ALS_DATA 0x04
38 #define VEML6030_REG_WH_DATA 0x05
39 #define VEML6030_REG_ALS_INT 0x06
41 /* Bit masks for specific functionality */
42 #define VEML6030_ALS_IT GENMASK(9, 6)
43 #define VEML6030_PSM GENMASK(2, 1)
44 #define VEML6030_ALS_PERS GENMASK(5, 4)
45 #define VEML6030_ALS_GAIN GENMASK(12, 11)
46 #define VEML6030_PSM_EN BIT(0)
47 #define VEML6030_INT_TH_LOW BIT(15)
48 #define VEML6030_INT_TH_HIGH BIT(14)
49 #define VEML6030_ALS_INT_EN BIT(1)
50 #define VEML6030_ALS_SD BIT(0)
52 #define VEML6035_GAIN_M GENMASK(12, 10)
53 #define VEML6035_GAIN BIT(10)
54 #define VEML6035_DG BIT(11)
55 #define VEML6035_SENS BIT(12)
56 #define VEML6035_INT_CHAN BIT(3)
57 #define VEML6035_CHAN_EN BIT(2)
59 struct veml603x_chip {
60 const char *name;
61 const int(*scale_vals)[][2];
62 const int num_scale_vals;
63 const struct iio_chan_spec *channels;
64 const int num_channels;
65 int (*hw_init)(struct iio_dev *indio_dev, struct device *dev);
66 int (*set_info)(struct iio_dev *indio_dev);
67 int (*set_als_gain)(struct iio_dev *indio_dev, int val, int val2);
68 int (*get_als_gain)(struct iio_dev *indio_dev, int *val, int *val2);
72 * The resolution depends on both gain and integration time. The
73 * cur_resolution stores one of the resolution mentioned in the
74 * table during startup and gets updated whenever integration time
75 * or gain is changed.
77 * Table 'resolution and maximum detection range' in the appnotes
78 * is visualized as a 2D array. The cur_gain stores index of gain
79 * in this table (0-3 for VEML6030, 0-5 for VEML6035) while the
80 * cur_integration_time holds index of integration time (0-5).
82 struct veml6030_data {
83 struct i2c_client *client;
84 struct regmap *regmap;
85 int cur_resolution;
86 int cur_gain;
87 int cur_integration_time;
88 const struct veml603x_chip *chip;
91 static const int veml6030_it_times[][2] = {
92 { 0, 25000 },
93 { 0, 50000 },
94 { 0, 100000 },
95 { 0, 200000 },
96 { 0, 400000 },
97 { 0, 800000 },
101 * Scale is 1/gain. Value 0.125 is ALS gain x (1/8), 0.25 is
102 * ALS gain x (1/4), 0.5 is ALS gain x (1/2), 1.0 is ALS gain x 1,
103 * 2.0 is ALS gain x2, and 4.0 is ALS gain x 4.
105 static const int veml6030_scale_vals[][2] = {
106 { 0, 125000 },
107 { 0, 250000 },
108 { 1, 0 },
109 { 2, 0 },
112 static const int veml6035_scale_vals[][2] = {
113 { 0, 125000 },
114 { 0, 250000 },
115 { 0, 500000 },
116 { 1, 0 },
117 { 2, 0 },
118 { 4, 0 },
122 * Persistence = 1/2/4/8 x integration time
123 * Minimum time for which light readings must stay above configured
124 * threshold to assert the interrupt.
126 static const char * const period_values[] = {
127 "0.1 0.2 0.4 0.8",
128 "0.2 0.4 0.8 1.6",
129 "0.4 0.8 1.6 3.2",
130 "0.8 1.6 3.2 6.4",
131 "0.05 0.1 0.2 0.4",
132 "0.025 0.050 0.1 0.2"
136 * Return list of valid period values in seconds corresponding to
137 * the currently active integration time.
139 static ssize_t in_illuminance_period_available_show(struct device *dev,
140 struct device_attribute *attr, char *buf)
142 struct veml6030_data *data = iio_priv(dev_to_iio_dev(dev));
143 int ret, reg, x;
145 ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
146 if (ret) {
147 dev_err(&data->client->dev,
148 "can't read als conf register %d\n", ret);
149 return ret;
152 ret = ((reg >> 6) & 0xF);
153 switch (ret) {
154 case 0:
155 case 1:
156 case 2:
157 case 3:
158 x = ret;
159 break;
160 case 8:
161 x = 4;
162 break;
163 case 12:
164 x = 5;
165 break;
166 default:
167 return -EINVAL;
170 return sysfs_emit(buf, "%s\n", period_values[x]);
173 static IIO_DEVICE_ATTR_RO(in_illuminance_period_available, 0);
175 static struct attribute *veml6030_event_attributes[] = {
176 &iio_dev_attr_in_illuminance_period_available.dev_attr.attr,
177 NULL
180 static const struct attribute_group veml6030_event_attr_group = {
181 .attrs = veml6030_event_attributes,
184 static int veml6030_als_pwr_on(struct veml6030_data *data)
186 int ret;
188 ret = regmap_clear_bits(data->regmap, VEML6030_REG_ALS_CONF,
189 VEML6030_ALS_SD);
190 if (ret)
191 return ret;
193 /* Wait 4 ms to let processor & oscillator start correctly */
194 fsleep(4000);
196 return 0;
199 static int veml6030_als_shut_down(struct veml6030_data *data)
201 return regmap_set_bits(data->regmap, VEML6030_REG_ALS_CONF,
202 VEML6030_ALS_SD);
205 static void veml6030_als_shut_down_action(void *data)
207 veml6030_als_shut_down(data);
210 static const struct iio_event_spec veml6030_event_spec[] = {
212 .type = IIO_EV_TYPE_THRESH,
213 .dir = IIO_EV_DIR_RISING,
214 .mask_separate = BIT(IIO_EV_INFO_VALUE),
215 }, {
216 .type = IIO_EV_TYPE_THRESH,
217 .dir = IIO_EV_DIR_FALLING,
218 .mask_separate = BIT(IIO_EV_INFO_VALUE),
219 }, {
220 .type = IIO_EV_TYPE_THRESH,
221 .dir = IIO_EV_DIR_EITHER,
222 .mask_separate = BIT(IIO_EV_INFO_PERIOD) |
223 BIT(IIO_EV_INFO_ENABLE),
227 /* Channel number */
228 enum veml6030_chan {
229 CH_ALS,
230 CH_WHITE,
233 static const struct iio_chan_spec veml6030_channels[] = {
235 .type = IIO_LIGHT,
236 .channel = CH_ALS,
237 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
238 BIT(IIO_CHAN_INFO_PROCESSED) |
239 BIT(IIO_CHAN_INFO_INT_TIME) |
240 BIT(IIO_CHAN_INFO_SCALE),
241 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
242 BIT(IIO_CHAN_INFO_SCALE),
243 .event_spec = veml6030_event_spec,
244 .num_event_specs = ARRAY_SIZE(veml6030_event_spec),
247 .type = IIO_INTENSITY,
248 .channel = CH_WHITE,
249 .modified = 1,
250 .channel2 = IIO_MOD_LIGHT_BOTH,
251 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
252 BIT(IIO_CHAN_INFO_INT_TIME) |
253 BIT(IIO_CHAN_INFO_SCALE),
254 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
255 BIT(IIO_CHAN_INFO_SCALE),
259 static const struct iio_chan_spec veml7700_channels[] = {
261 .type = IIO_LIGHT,
262 .channel = CH_ALS,
263 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
264 BIT(IIO_CHAN_INFO_PROCESSED) |
265 BIT(IIO_CHAN_INFO_INT_TIME) |
266 BIT(IIO_CHAN_INFO_SCALE),
267 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
268 BIT(IIO_CHAN_INFO_SCALE),
271 .type = IIO_INTENSITY,
272 .channel = CH_WHITE,
273 .modified = 1,
274 .channel2 = IIO_MOD_LIGHT_BOTH,
275 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
276 BIT(IIO_CHAN_INFO_INT_TIME) |
277 BIT(IIO_CHAN_INFO_SCALE),
278 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
279 BIT(IIO_CHAN_INFO_SCALE),
283 static const struct regmap_config veml6030_regmap_config = {
284 .name = "veml6030_regmap",
285 .reg_bits = 8,
286 .val_bits = 16,
287 .max_register = VEML6030_REG_ALS_INT,
288 .val_format_endian = REGMAP_ENDIAN_LITTLE,
291 static int veml6030_get_intgrn_tm(struct iio_dev *indio_dev,
292 int *val, int *val2)
294 int ret, reg;
295 struct veml6030_data *data = iio_priv(indio_dev);
297 ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
298 if (ret) {
299 dev_err(&data->client->dev,
300 "can't read als conf register %d\n", ret);
301 return ret;
304 switch ((reg >> 6) & 0xF) {
305 case 0:
306 *val2 = 100000;
307 break;
308 case 1:
309 *val2 = 200000;
310 break;
311 case 2:
312 *val2 = 400000;
313 break;
314 case 3:
315 *val2 = 800000;
316 break;
317 case 8:
318 *val2 = 50000;
319 break;
320 case 12:
321 *val2 = 25000;
322 break;
323 default:
324 return -EINVAL;
327 *val = 0;
328 return IIO_VAL_INT_PLUS_MICRO;
331 static int veml6030_set_intgrn_tm(struct iio_dev *indio_dev,
332 int val, int val2)
334 int ret, new_int_time, int_idx;
335 struct veml6030_data *data = iio_priv(indio_dev);
337 if (val)
338 return -EINVAL;
340 switch (val2) {
341 case 25000:
342 new_int_time = 0x300;
343 int_idx = 5;
344 break;
345 case 50000:
346 new_int_time = 0x200;
347 int_idx = 4;
348 break;
349 case 100000:
350 new_int_time = 0x00;
351 int_idx = 3;
352 break;
353 case 200000:
354 new_int_time = 0x40;
355 int_idx = 2;
356 break;
357 case 400000:
358 new_int_time = 0x80;
359 int_idx = 1;
360 break;
361 case 800000:
362 new_int_time = 0xC0;
363 int_idx = 0;
364 break;
365 default:
366 return -EINVAL;
369 ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
370 VEML6030_ALS_IT, new_int_time);
371 if (ret) {
372 dev_err(&data->client->dev,
373 "can't update als integration time %d\n", ret);
374 return ret;
378 * Cache current integration time and update resolution. For every
379 * increase in integration time to next level, resolution is halved
380 * and vice-versa.
382 if (data->cur_integration_time < int_idx)
383 data->cur_resolution <<= int_idx - data->cur_integration_time;
384 else if (data->cur_integration_time > int_idx)
385 data->cur_resolution >>= data->cur_integration_time - int_idx;
387 data->cur_integration_time = int_idx;
389 return ret;
392 static int veml6030_read_persistence(struct iio_dev *indio_dev,
393 int *val, int *val2)
395 int ret, reg, period, x, y;
396 struct veml6030_data *data = iio_priv(indio_dev);
398 ret = veml6030_get_intgrn_tm(indio_dev, &x, &y);
399 if (ret < 0)
400 return ret;
402 ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
403 if (ret) {
404 dev_err(&data->client->dev,
405 "can't read als conf register %d\n", ret);
408 /* integration time multiplied by 1/2/4/8 */
409 period = y * (1 << ((reg >> 4) & 0x03));
411 *val = period / 1000000;
412 *val2 = period % 1000000;
414 return IIO_VAL_INT_PLUS_MICRO;
417 static int veml6030_write_persistence(struct iio_dev *indio_dev,
418 int val, int val2)
420 int ret, period, x, y;
421 struct veml6030_data *data = iio_priv(indio_dev);
423 ret = veml6030_get_intgrn_tm(indio_dev, &x, &y);
424 if (ret < 0)
425 return ret;
427 if (!val) {
428 period = val2 / y;
429 } else {
430 if ((val == 1) && (val2 == 600000))
431 period = 1600000 / y;
432 else if ((val == 3) && (val2 == 200000))
433 period = 3200000 / y;
434 else if ((val == 6) && (val2 == 400000))
435 period = 6400000 / y;
436 else
437 period = -1;
440 if (period <= 0 || period > 8 || hweight8(period) != 1)
441 return -EINVAL;
443 ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
444 VEML6030_ALS_PERS, (ffs(period) - 1) << 4);
445 if (ret)
446 dev_err(&data->client->dev,
447 "can't set persistence value %d\n", ret);
449 return ret;
453 * Cache currently set gain & update resolution. For every
454 * increase in the gain to next level, resolution is halved
455 * and vice-versa.
457 static void veml6030_update_gain_res(struct veml6030_data *data, int gain_idx)
459 if (data->cur_gain < gain_idx)
460 data->cur_resolution <<= gain_idx - data->cur_gain;
461 else if (data->cur_gain > gain_idx)
462 data->cur_resolution >>= data->cur_gain - gain_idx;
464 data->cur_gain = gain_idx;
467 static int veml6030_set_als_gain(struct iio_dev *indio_dev,
468 int val, int val2)
470 int ret, new_gain, gain_idx;
471 struct veml6030_data *data = iio_priv(indio_dev);
473 if (val == 0 && val2 == 125000) {
474 new_gain = 0x1000; /* 0x02 << 11 */
475 gain_idx = 3;
476 } else if (val == 0 && val2 == 250000) {
477 new_gain = 0x1800;
478 gain_idx = 2;
479 } else if (val == 1 && val2 == 0) {
480 new_gain = 0x00;
481 gain_idx = 1;
482 } else if (val == 2 && val2 == 0) {
483 new_gain = 0x800;
484 gain_idx = 0;
485 } else {
486 return -EINVAL;
489 ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
490 VEML6030_ALS_GAIN, new_gain);
491 if (ret) {
492 dev_err(&data->client->dev,
493 "can't set als gain %d\n", ret);
494 return ret;
497 veml6030_update_gain_res(data, gain_idx);
499 return 0;
502 static int veml6035_set_als_gain(struct iio_dev *indio_dev, int val, int val2)
504 int ret, new_gain, gain_idx;
505 struct veml6030_data *data = iio_priv(indio_dev);
507 if (val == 0 && val2 == 125000) {
508 new_gain = VEML6035_SENS;
509 gain_idx = 5;
510 } else if (val == 0 && val2 == 250000) {
511 new_gain = VEML6035_SENS | VEML6035_GAIN;
512 gain_idx = 4;
513 } else if (val == 0 && val2 == 500000) {
514 new_gain = VEML6035_SENS | VEML6035_GAIN |
515 VEML6035_DG;
516 gain_idx = 3;
517 } else if (val == 1 && val2 == 0) {
518 new_gain = 0x0000;
519 gain_idx = 2;
520 } else if (val == 2 && val2 == 0) {
521 new_gain = VEML6035_GAIN;
522 gain_idx = 1;
523 } else if (val == 4 && val2 == 0) {
524 new_gain = VEML6035_GAIN | VEML6035_DG;
525 gain_idx = 0;
526 } else {
527 return -EINVAL;
530 ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
531 VEML6035_GAIN_M, new_gain);
532 if (ret) {
533 dev_err(&data->client->dev, "can't set als gain %d\n", ret);
534 return ret;
537 veml6030_update_gain_res(data, gain_idx);
539 return 0;
542 static int veml6030_get_als_gain(struct iio_dev *indio_dev,
543 int *val, int *val2)
545 int ret, reg;
546 struct veml6030_data *data = iio_priv(indio_dev);
548 ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
549 if (ret) {
550 dev_err(&data->client->dev,
551 "can't read als conf register %d\n", ret);
552 return ret;
555 switch ((reg >> 11) & 0x03) {
556 case 0:
557 *val = 1;
558 *val2 = 0;
559 break;
560 case 1:
561 *val = 2;
562 *val2 = 0;
563 break;
564 case 2:
565 *val = 0;
566 *val2 = 125000;
567 break;
568 case 3:
569 *val = 0;
570 *val2 = 250000;
571 break;
572 default:
573 return -EINVAL;
576 return IIO_VAL_INT_PLUS_MICRO;
579 static int veml6035_get_als_gain(struct iio_dev *indio_dev, int *val, int *val2)
581 int ret, reg;
582 struct veml6030_data *data = iio_priv(indio_dev);
584 ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
585 if (ret) {
586 dev_err(&data->client->dev,
587 "can't read als conf register %d\n", ret);
588 return ret;
591 switch (FIELD_GET(VEML6035_GAIN_M, reg)) {
592 case 0:
593 *val = 1;
594 *val2 = 0;
595 break;
596 case 1:
597 case 2:
598 *val = 2;
599 *val2 = 0;
600 break;
601 case 3:
602 *val = 4;
603 *val2 = 0;
604 break;
605 case 4:
606 *val = 0;
607 *val2 = 125000;
608 break;
609 case 5:
610 case 6:
611 *val = 0;
612 *val2 = 250000;
613 break;
614 case 7:
615 *val = 0;
616 *val2 = 500000;
617 break;
618 default:
619 return -EINVAL;
622 return IIO_VAL_INT_PLUS_MICRO;
625 static int veml6030_read_thresh(struct iio_dev *indio_dev,
626 int *val, int *val2, int dir)
628 int ret, reg;
629 struct veml6030_data *data = iio_priv(indio_dev);
631 if (dir == IIO_EV_DIR_RISING)
632 ret = regmap_read(data->regmap, VEML6030_REG_ALS_WH, &reg);
633 else
634 ret = regmap_read(data->regmap, VEML6030_REG_ALS_WL, &reg);
635 if (ret) {
636 dev_err(&data->client->dev,
637 "can't read als threshold value %d\n", ret);
638 return ret;
641 *val = reg & 0xffff;
642 return IIO_VAL_INT;
645 static int veml6030_write_thresh(struct iio_dev *indio_dev,
646 int val, int val2, int dir)
648 int ret;
649 struct veml6030_data *data = iio_priv(indio_dev);
651 if (val > 0xFFFF || val < 0 || val2)
652 return -EINVAL;
654 if (dir == IIO_EV_DIR_RISING) {
655 ret = regmap_write(data->regmap, VEML6030_REG_ALS_WH, val);
656 if (ret)
657 dev_err(&data->client->dev,
658 "can't set high threshold %d\n", ret);
659 } else {
660 ret = regmap_write(data->regmap, VEML6030_REG_ALS_WL, val);
661 if (ret)
662 dev_err(&data->client->dev,
663 "can't set low threshold %d\n", ret);
666 return ret;
670 * Provide both raw as well as light reading in lux.
671 * light (in lux) = resolution * raw reading
673 static int veml6030_read_raw(struct iio_dev *indio_dev,
674 struct iio_chan_spec const *chan, int *val,
675 int *val2, long mask)
677 int ret, reg;
678 struct veml6030_data *data = iio_priv(indio_dev);
679 struct regmap *regmap = data->regmap;
680 struct device *dev = &data->client->dev;
682 switch (mask) {
683 case IIO_CHAN_INFO_RAW:
684 case IIO_CHAN_INFO_PROCESSED:
685 switch (chan->type) {
686 case IIO_LIGHT:
687 ret = regmap_read(regmap, VEML6030_REG_ALS_DATA, &reg);
688 if (ret < 0) {
689 dev_err(dev, "can't read als data %d\n", ret);
690 return ret;
692 if (mask == IIO_CHAN_INFO_PROCESSED) {
693 *val = (reg * data->cur_resolution) / 10000;
694 *val2 = (reg * data->cur_resolution) % 10000 * 100;
695 return IIO_VAL_INT_PLUS_MICRO;
697 *val = reg;
698 return IIO_VAL_INT;
699 case IIO_INTENSITY:
700 ret = regmap_read(regmap, VEML6030_REG_WH_DATA, &reg);
701 if (ret < 0) {
702 dev_err(dev, "can't read white data %d\n", ret);
703 return ret;
705 *val = reg;
706 return IIO_VAL_INT;
707 default:
708 return -EINVAL;
710 case IIO_CHAN_INFO_INT_TIME:
711 return veml6030_get_intgrn_tm(indio_dev, val, val2);
712 case IIO_CHAN_INFO_SCALE:
713 return data->chip->get_als_gain(indio_dev, val, val2);
714 default:
715 return -EINVAL;
719 static int veml6030_read_avail(struct iio_dev *indio_dev,
720 struct iio_chan_spec const *chan,
721 const int **vals, int *type, int *length,
722 long mask)
724 struct veml6030_data *data = iio_priv(indio_dev);
726 switch (mask) {
727 case IIO_CHAN_INFO_INT_TIME:
728 *vals = (int *)&veml6030_it_times;
729 *length = 2 * ARRAY_SIZE(veml6030_it_times);
730 *type = IIO_VAL_INT_PLUS_MICRO;
731 return IIO_AVAIL_LIST;
732 case IIO_CHAN_INFO_SCALE:
733 *vals = (int *)*data->chip->scale_vals;
734 *length = 2 * data->chip->num_scale_vals;
735 *type = IIO_VAL_INT_PLUS_MICRO;
736 return IIO_AVAIL_LIST;
739 return -EINVAL;
742 static int veml6030_write_raw(struct iio_dev *indio_dev,
743 struct iio_chan_spec const *chan,
744 int val, int val2, long mask)
746 struct veml6030_data *data = iio_priv(indio_dev);
748 switch (mask) {
749 case IIO_CHAN_INFO_INT_TIME:
750 return veml6030_set_intgrn_tm(indio_dev, val, val2);
751 case IIO_CHAN_INFO_SCALE:
752 return data->chip->set_als_gain(indio_dev, val, val2);
753 default:
754 return -EINVAL;
758 static int veml6030_read_event_val(struct iio_dev *indio_dev,
759 const struct iio_chan_spec *chan, enum iio_event_type type,
760 enum iio_event_direction dir, enum iio_event_info info,
761 int *val, int *val2)
763 switch (info) {
764 case IIO_EV_INFO_VALUE:
765 switch (dir) {
766 case IIO_EV_DIR_RISING:
767 case IIO_EV_DIR_FALLING:
768 return veml6030_read_thresh(indio_dev, val, val2, dir);
769 default:
770 return -EINVAL;
772 break;
773 case IIO_EV_INFO_PERIOD:
774 return veml6030_read_persistence(indio_dev, val, val2);
775 default:
776 return -EINVAL;
780 static int veml6030_write_event_val(struct iio_dev *indio_dev,
781 const struct iio_chan_spec *chan, enum iio_event_type type,
782 enum iio_event_direction dir, enum iio_event_info info,
783 int val, int val2)
785 switch (info) {
786 case IIO_EV_INFO_VALUE:
787 return veml6030_write_thresh(indio_dev, val, val2, dir);
788 case IIO_EV_INFO_PERIOD:
789 return veml6030_write_persistence(indio_dev, val, val2);
790 default:
791 return -EINVAL;
795 static int veml6030_read_interrupt_config(struct iio_dev *indio_dev,
796 const struct iio_chan_spec *chan, enum iio_event_type type,
797 enum iio_event_direction dir)
799 int ret, reg;
800 struct veml6030_data *data = iio_priv(indio_dev);
802 ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
803 if (ret) {
804 dev_err(&data->client->dev,
805 "can't read als conf register %d\n", ret);
806 return ret;
809 if (reg & VEML6030_ALS_INT_EN)
810 return 1;
811 else
812 return 0;
816 * Sensor should not be measuring light when interrupt is configured.
817 * Therefore correct sequence to configure interrupt functionality is:
818 * shut down -> enable/disable interrupt -> power on
820 * state = 1 enables interrupt, state = 0 disables interrupt
822 static int veml6030_write_interrupt_config(struct iio_dev *indio_dev,
823 const struct iio_chan_spec *chan, enum iio_event_type type,
824 enum iio_event_direction dir, bool state)
826 int ret;
827 struct veml6030_data *data = iio_priv(indio_dev);
829 ret = veml6030_als_shut_down(data);
830 if (ret < 0) {
831 dev_err(&data->client->dev,
832 "can't disable als to configure interrupt %d\n", ret);
833 return ret;
836 /* enable interrupt + power on */
837 ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
838 VEML6030_ALS_INT_EN | VEML6030_ALS_SD, state << 1);
839 if (ret)
840 dev_err(&data->client->dev,
841 "can't enable interrupt & poweron als %d\n", ret);
843 return ret;
846 static const struct iio_info veml6030_info = {
847 .read_raw = veml6030_read_raw,
848 .read_avail = veml6030_read_avail,
849 .write_raw = veml6030_write_raw,
850 .read_event_value = veml6030_read_event_val,
851 .write_event_value = veml6030_write_event_val,
852 .read_event_config = veml6030_read_interrupt_config,
853 .write_event_config = veml6030_write_interrupt_config,
854 .event_attrs = &veml6030_event_attr_group,
857 static const struct iio_info veml6030_info_no_irq = {
858 .read_raw = veml6030_read_raw,
859 .read_avail = veml6030_read_avail,
860 .write_raw = veml6030_write_raw,
863 static irqreturn_t veml6030_event_handler(int irq, void *private)
865 int ret, reg, evtdir;
866 struct iio_dev *indio_dev = private;
867 struct veml6030_data *data = iio_priv(indio_dev);
869 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &reg);
870 if (ret) {
871 dev_err(&data->client->dev,
872 "can't read als interrupt register %d\n", ret);
873 return IRQ_HANDLED;
876 /* Spurious interrupt handling */
877 if (!(reg & (VEML6030_INT_TH_HIGH | VEML6030_INT_TH_LOW)))
878 return IRQ_NONE;
880 if (reg & VEML6030_INT_TH_HIGH)
881 evtdir = IIO_EV_DIR_RISING;
882 else
883 evtdir = IIO_EV_DIR_FALLING;
885 iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
886 0, IIO_EV_TYPE_THRESH, evtdir),
887 iio_get_time_ns(indio_dev));
889 return IRQ_HANDLED;
892 static int veml6030_set_info(struct iio_dev *indio_dev)
894 struct veml6030_data *data = iio_priv(indio_dev);
895 struct i2c_client *client = data->client;
896 int ret;
898 if (client->irq) {
899 ret = devm_request_threaded_irq(&client->dev, client->irq,
900 NULL, veml6030_event_handler,
901 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
902 indio_dev->name, indio_dev);
903 if (ret < 0)
904 return dev_err_probe(&client->dev, ret,
905 "irq %d request failed\n",
906 client->irq);
908 indio_dev->info = &veml6030_info;
909 } else {
910 indio_dev->info = &veml6030_info_no_irq;
913 return 0;
916 static int veml7700_set_info(struct iio_dev *indio_dev)
918 indio_dev->info = &veml6030_info_no_irq;
920 return 0;
924 * Set ALS gain to 1/8, integration time to 100 ms, PSM to mode 2,
925 * persistence to 1 x integration time and the threshold
926 * interrupt disabled by default. First shutdown the sensor,
927 * update registers and then power on the sensor.
929 static int veml6030_hw_init(struct iio_dev *indio_dev, struct device *dev)
931 int ret, val;
932 struct veml6030_data *data = iio_priv(indio_dev);
934 ret = veml6030_als_shut_down(data);
935 if (ret)
936 return dev_err_probe(dev, ret, "can't shutdown als\n");
938 ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, 0x1001);
939 if (ret)
940 return dev_err_probe(dev, ret, "can't setup als configs\n");
942 ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_PSM,
943 VEML6030_PSM | VEML6030_PSM_EN, 0x03);
944 if (ret)
945 return dev_err_probe(dev, ret, "can't setup default PSM\n");
947 ret = regmap_write(data->regmap, VEML6030_REG_ALS_WH, 0xFFFF);
948 if (ret)
949 return dev_err_probe(dev, ret, "can't setup high threshold\n");
951 ret = regmap_write(data->regmap, VEML6030_REG_ALS_WL, 0x0000);
952 if (ret)
953 return dev_err_probe(dev, ret, "can't setup low threshold\n");
955 ret = veml6030_als_pwr_on(data);
956 if (ret)
957 return dev_err_probe(dev, ret, "can't poweron als\n");
959 ret = devm_add_action_or_reset(dev, veml6030_als_shut_down_action, data);
960 if (ret < 0)
961 return ret;
963 /* Clear stale interrupt status bits if any during start */
964 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val);
965 if (ret < 0)
966 return dev_err_probe(dev, ret,
967 "can't clear als interrupt status\n");
969 /* Cache currently active measurement parameters */
970 data->cur_gain = 3;
971 data->cur_resolution = 5376;
972 data->cur_integration_time = 3;
974 return ret;
978 * Set ALS gain to 1/8, integration time to 100 ms, ALS and WHITE
979 * channel enabled, ALS channel interrupt, PSM enabled,
980 * PSM_WAIT = 0.8 s, persistence to 1 x integration time and the
981 * threshold interrupt disabled by default. First shutdown the sensor,
982 * update registers and then power on the sensor.
984 static int veml6035_hw_init(struct iio_dev *indio_dev, struct device *dev)
986 int ret, val;
987 struct veml6030_data *data = iio_priv(indio_dev);
989 ret = veml6030_als_shut_down(data);
990 if (ret)
991 return dev_err_probe(dev, ret, "can't shutdown als\n");
993 ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF,
994 VEML6035_SENS | VEML6035_CHAN_EN | VEML6030_ALS_SD);
995 if (ret)
996 return dev_err_probe(dev, ret, "can't setup als configs\n");
998 ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_PSM,
999 VEML6030_PSM | VEML6030_PSM_EN, 0x03);
1000 if (ret)
1001 return dev_err_probe(dev, ret, "can't setup default PSM\n");
1003 ret = regmap_write(data->regmap, VEML6030_REG_ALS_WH, 0xFFFF);
1004 if (ret)
1005 return dev_err_probe(dev, ret, "can't setup high threshold\n");
1007 ret = regmap_write(data->regmap, VEML6030_REG_ALS_WL, 0x0000);
1008 if (ret)
1009 return dev_err_probe(dev, ret, "can't setup low threshold\n");
1011 ret = veml6030_als_pwr_on(data);
1012 if (ret)
1013 return dev_err_probe(dev, ret, "can't poweron als\n");
1015 ret = devm_add_action_or_reset(dev, veml6030_als_shut_down_action, data);
1016 if (ret < 0)
1017 return ret;
1019 /* Clear stale interrupt status bits if any during start */
1020 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val);
1021 if (ret < 0)
1022 return dev_err_probe(dev, ret,
1023 "can't clear als interrupt status\n");
1025 /* Cache currently active measurement parameters */
1026 data->cur_gain = 5;
1027 data->cur_resolution = 1024;
1028 data->cur_integration_time = 3;
1030 return 0;
1033 static int veml6030_probe(struct i2c_client *client)
1035 int ret;
1036 struct veml6030_data *data;
1037 struct iio_dev *indio_dev;
1038 struct regmap *regmap;
1040 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
1041 return dev_err_probe(&client->dev, -EOPNOTSUPP,
1042 "i2c adapter doesn't support plain i2c\n");
1044 regmap = devm_regmap_init_i2c(client, &veml6030_regmap_config);
1045 if (IS_ERR(regmap))
1046 return dev_err_probe(&client->dev, PTR_ERR(regmap),
1047 "can't setup regmap\n");
1049 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
1050 if (!indio_dev)
1051 return -ENOMEM;
1053 data = iio_priv(indio_dev);
1054 i2c_set_clientdata(client, indio_dev);
1055 data->client = client;
1056 data->regmap = regmap;
1058 ret = devm_regulator_get_enable(&client->dev, "vdd");
1059 if (ret)
1060 return dev_err_probe(&client->dev, ret,
1061 "failed to enable regulator\n");
1063 data->chip = i2c_get_match_data(client);
1064 if (!data->chip)
1065 return -EINVAL;
1067 indio_dev->name = data->chip->name;
1068 indio_dev->channels = data->chip->channels;
1069 indio_dev->num_channels = data->chip->num_channels;
1070 indio_dev->modes = INDIO_DIRECT_MODE;
1072 ret = data->chip->set_info(indio_dev);
1073 if (ret < 0)
1074 return ret;
1076 ret = data->chip->hw_init(indio_dev, &client->dev);
1077 if (ret < 0)
1078 return ret;
1080 return devm_iio_device_register(&client->dev, indio_dev);
1083 static int veml6030_runtime_suspend(struct device *dev)
1085 int ret;
1086 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1087 struct veml6030_data *data = iio_priv(indio_dev);
1089 ret = veml6030_als_shut_down(data);
1090 if (ret < 0)
1091 dev_err(&data->client->dev, "can't suspend als %d\n", ret);
1093 return ret;
1096 static int veml6030_runtime_resume(struct device *dev)
1098 int ret;
1099 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1100 struct veml6030_data *data = iio_priv(indio_dev);
1102 ret = veml6030_als_pwr_on(data);
1103 if (ret < 0)
1104 dev_err(&data->client->dev, "can't resume als %d\n", ret);
1106 return ret;
1109 static DEFINE_RUNTIME_DEV_PM_OPS(veml6030_pm_ops, veml6030_runtime_suspend,
1110 veml6030_runtime_resume, NULL);
1112 static const struct veml603x_chip veml6030_chip = {
1113 .name = "veml6030",
1114 .scale_vals = &veml6030_scale_vals,
1115 .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
1116 .channels = veml6030_channels,
1117 .num_channels = ARRAY_SIZE(veml6030_channels),
1118 .hw_init = veml6030_hw_init,
1119 .set_info = veml6030_set_info,
1120 .set_als_gain = veml6030_set_als_gain,
1121 .get_als_gain = veml6030_get_als_gain,
1124 static const struct veml603x_chip veml6035_chip = {
1125 .name = "veml6035",
1126 .scale_vals = &veml6035_scale_vals,
1127 .num_scale_vals = ARRAY_SIZE(veml6035_scale_vals),
1128 .channels = veml6030_channels,
1129 .num_channels = ARRAY_SIZE(veml6030_channels),
1130 .hw_init = veml6035_hw_init,
1131 .set_info = veml6030_set_info,
1132 .set_als_gain = veml6035_set_als_gain,
1133 .get_als_gain = veml6035_get_als_gain,
1136 static const struct veml603x_chip veml7700_chip = {
1137 .name = "veml7700",
1138 .scale_vals = &veml6030_scale_vals,
1139 .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
1140 .channels = veml7700_channels,
1141 .num_channels = ARRAY_SIZE(veml7700_channels),
1142 .hw_init = veml6030_hw_init,
1143 .set_info = veml7700_set_info,
1144 .set_als_gain = veml6030_set_als_gain,
1145 .get_als_gain = veml6030_get_als_gain,
1148 static const struct of_device_id veml6030_of_match[] = {
1150 .compatible = "vishay,veml6030",
1151 .data = &veml6030_chip,
1154 .compatible = "vishay,veml6035",
1155 .data = &veml6035_chip,
1158 .compatible = "vishay,veml7700",
1159 .data = &veml7700_chip,
1163 MODULE_DEVICE_TABLE(of, veml6030_of_match);
1165 static const struct i2c_device_id veml6030_id[] = {
1166 { "veml6030", (kernel_ulong_t)&veml6030_chip},
1167 { "veml6035", (kernel_ulong_t)&veml6035_chip},
1168 { "veml7700", (kernel_ulong_t)&veml7700_chip},
1171 MODULE_DEVICE_TABLE(i2c, veml6030_id);
1173 static struct i2c_driver veml6030_driver = {
1174 .driver = {
1175 .name = "veml6030",
1176 .of_match_table = veml6030_of_match,
1177 .pm = pm_ptr(&veml6030_pm_ops),
1179 .probe = veml6030_probe,
1180 .id_table = veml6030_id,
1182 module_i2c_driver(veml6030_driver);
1184 MODULE_AUTHOR("Rishi Gupta <gupt21@gmail.com>");
1185 MODULE_DESCRIPTION("VEML6030 Ambient Light Sensor");
1186 MODULE_LICENSE("GPL v2");