xref: /openbmc/linux/drivers/iio/light/veml6030.c (revision bef7a78d)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * VEML6030 Ambient Light Sensor
4  *
5  * Copyright (c) 2019, Rishi Gupta <gupt21@gmail.com>
6  *
7  * Datasheet: https://www.vishay.com/docs/84366/veml6030.pdf
8  * Appnote-84367: https://www.vishay.com/docs/84367/designingveml6030.pdf
9  */
10 
11 #include <linux/module.h>
12 #include <linux/i2c.h>
13 #include <linux/err.h>
14 #include <linux/regmap.h>
15 #include <linux/interrupt.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/iio/iio.h>
18 #include <linux/iio/sysfs.h>
19 #include <linux/iio/events.h>
20 
21 /* Device registers */
22 #define VEML6030_REG_ALS_CONF   0x00
23 #define VEML6030_REG_ALS_WH     0x01
24 #define VEML6030_REG_ALS_WL     0x02
25 #define VEML6030_REG_ALS_PSM    0x03
26 #define VEML6030_REG_ALS_DATA   0x04
27 #define VEML6030_REG_WH_DATA    0x05
28 #define VEML6030_REG_ALS_INT    0x06
29 
30 /* Bit masks for specific functionality */
31 #define VEML6030_ALS_IT       GENMASK(9, 6)
32 #define VEML6030_PSM          GENMASK(2, 1)
33 #define VEML6030_ALS_PERS     GENMASK(5, 4)
34 #define VEML6030_ALS_GAIN     GENMASK(12, 11)
35 #define VEML6030_PSM_EN       BIT(0)
36 #define VEML6030_INT_TH_LOW   BIT(15)
37 #define VEML6030_INT_TH_HIGH  BIT(14)
38 #define VEML6030_ALS_INT_EN   BIT(1)
39 #define VEML6030_ALS_SD       BIT(0)
40 
41 /*
42  * The resolution depends on both gain and integration time. The
43  * cur_resolution stores one of the resolution mentioned in the
44  * table during startup and gets updated whenever integration time
45  * or gain is changed.
46  *
47  * Table 'resolution and maximum detection range' in appnote 84367
48  * is visualized as a 2D array. The cur_gain stores index of gain
49  * in this table (0-3) while the cur_integration_time holds index
50  * of integration time (0-5).
51  */
52 struct veml6030_data {
53 	struct i2c_client *client;
54 	struct regmap *regmap;
55 	int cur_resolution;
56 	int cur_gain;
57 	int cur_integration_time;
58 };
59 
60 /* Integration time available in seconds */
61 static IIO_CONST_ATTR(in_illuminance_integration_time_available,
62 				"0.025 0.05 0.1 0.2 0.4 0.8");
63 
64 /*
65  * Scale is 1/gain. Value 0.125 is ALS gain x (1/8), 0.25 is
66  * ALS gain x (1/4), 1.0 = ALS gain x 1 and 2.0 is ALS gain x 2.
67  */
68 static IIO_CONST_ATTR(in_illuminance_scale_available,
69 				"0.125 0.25 1.0 2.0");
70 
71 static struct attribute *veml6030_attributes[] = {
72 	&iio_const_attr_in_illuminance_integration_time_available.dev_attr.attr,
73 	&iio_const_attr_in_illuminance_scale_available.dev_attr.attr,
74 	NULL
75 };
76 
77 static const struct attribute_group veml6030_attr_group = {
78 	.attrs = veml6030_attributes,
79 };
80 
81 /*
82  * Persistence = 1/2/4/8 x integration time
83  * Minimum time for which light readings must stay above configured
84  * threshold to assert the interrupt.
85  */
86 static const char * const period_values[] = {
87 		"0.1 0.2 0.4 0.8",
88 		"0.2 0.4 0.8 1.6",
89 		"0.4 0.8 1.6 3.2",
90 		"0.8 1.6 3.2 6.4",
91 		"0.05 0.1 0.2 0.4",
92 		"0.025 0.050 0.1 0.2"
93 };
94 
95 /*
96  * Return list of valid period values in seconds corresponding to
97  * the currently active integration time.
98  */
99 static ssize_t in_illuminance_period_available_show(struct device *dev,
100 				struct device_attribute *attr, char *buf)
101 {
102 	int ret, reg, x;
103 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
104 	struct veml6030_data *data = iio_priv(indio_dev);
105 
106 	ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
107 	if (ret) {
108 		dev_err(&data->client->dev,
109 				"can't read als conf register %d\n", ret);
110 		return ret;
111 	}
112 
113 	ret = ((reg >> 6) & 0xF);
114 	switch (ret) {
115 	case 0:
116 	case 1:
117 	case 2:
118 	case 3:
119 		x = ret;
120 		break;
121 	case 8:
122 		x = 4;
123 		break;
124 	case 12:
125 		x = 5;
126 		break;
127 	default:
128 		return -EINVAL;
129 	}
130 
131 	return snprintf(buf, PAGE_SIZE, "%s\n", period_values[x]);
132 }
133 
134 static IIO_DEVICE_ATTR_RO(in_illuminance_period_available, 0);
135 
136 static struct attribute *veml6030_event_attributes[] = {
137 	&iio_dev_attr_in_illuminance_period_available.dev_attr.attr,
138 	NULL
139 };
140 
141 static const struct attribute_group veml6030_event_attr_group = {
142 	.attrs = veml6030_event_attributes,
143 };
144 
145 static int veml6030_als_pwr_on(struct veml6030_data *data)
146 {
147 	return regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
148 				 VEML6030_ALS_SD, 0);
149 }
150 
151 static int veml6030_als_shut_down(struct veml6030_data *data)
152 {
153 	return regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
154 				 VEML6030_ALS_SD, 1);
155 }
156 
157 static void veml6030_als_shut_down_action(void *data)
158 {
159 	veml6030_als_shut_down(data);
160 }
161 
162 static const struct iio_event_spec veml6030_event_spec[] = {
163 	{
164 		.type = IIO_EV_TYPE_THRESH,
165 		.dir = IIO_EV_DIR_RISING,
166 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
167 	}, {
168 		.type = IIO_EV_TYPE_THRESH,
169 		.dir = IIO_EV_DIR_FALLING,
170 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
171 	}, {
172 		.type = IIO_EV_TYPE_THRESH,
173 		.dir = IIO_EV_DIR_EITHER,
174 		.mask_separate = BIT(IIO_EV_INFO_PERIOD) |
175 		BIT(IIO_EV_INFO_ENABLE),
176 	},
177 };
178 
179 /* Channel number */
180 enum veml6030_chan {
181 	CH_ALS,
182 	CH_WHITE,
183 };
184 
185 static const struct iio_chan_spec veml6030_channels[] = {
186 	{
187 		.type = IIO_LIGHT,
188 		.channel = CH_ALS,
189 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
190 				BIT(IIO_CHAN_INFO_PROCESSED) |
191 				BIT(IIO_CHAN_INFO_INT_TIME) |
192 				BIT(IIO_CHAN_INFO_SCALE),
193 		.event_spec = veml6030_event_spec,
194 		.num_event_specs = ARRAY_SIZE(veml6030_event_spec),
195 	},
196 	{
197 		.type = IIO_INTENSITY,
198 		.channel = CH_WHITE,
199 		.modified = 1,
200 		.channel2 = IIO_MOD_LIGHT_BOTH,
201 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
202 				BIT(IIO_CHAN_INFO_PROCESSED),
203 	},
204 };
205 
206 static const struct regmap_config veml6030_regmap_config = {
207 	.name = "veml6030_regmap",
208 	.reg_bits = 8,
209 	.val_bits = 16,
210 	.max_register = VEML6030_REG_ALS_INT,
211 	.val_format_endian = REGMAP_ENDIAN_LITTLE,
212 };
213 
214 static int veml6030_get_intgrn_tm(struct iio_dev *indio_dev,
215 						int *val, int *val2)
216 {
217 	int ret, reg;
218 	struct veml6030_data *data = iio_priv(indio_dev);
219 
220 	ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
221 	if (ret) {
222 		dev_err(&data->client->dev,
223 				"can't read als conf register %d\n", ret);
224 		return ret;
225 	}
226 
227 	switch ((reg >> 6) & 0xF) {
228 	case 0:
229 		*val2 = 100000;
230 		break;
231 	case 1:
232 		*val2 = 200000;
233 		break;
234 	case 2:
235 		*val2 = 400000;
236 		break;
237 	case 3:
238 		*val2 = 800000;
239 		break;
240 	case 8:
241 		*val2 = 50000;
242 		break;
243 	case 12:
244 		*val2 = 25000;
245 		break;
246 	default:
247 		return -EINVAL;
248 	}
249 
250 	*val = 0;
251 	return IIO_VAL_INT_PLUS_MICRO;
252 }
253 
254 static int veml6030_set_intgrn_tm(struct iio_dev *indio_dev,
255 						int val, int val2)
256 {
257 	int ret, new_int_time, int_idx;
258 	struct veml6030_data *data = iio_priv(indio_dev);
259 
260 	if (val)
261 		return -EINVAL;
262 
263 	switch (val2) {
264 	case 25000:
265 		new_int_time = 0x300;
266 		int_idx = 5;
267 		break;
268 	case 50000:
269 		new_int_time = 0x200;
270 		int_idx = 4;
271 		break;
272 	case 100000:
273 		new_int_time = 0x00;
274 		int_idx = 3;
275 		break;
276 	case 200000:
277 		new_int_time = 0x40;
278 		int_idx = 2;
279 		break;
280 	case 400000:
281 		new_int_time = 0x80;
282 		int_idx = 1;
283 		break;
284 	case 800000:
285 		new_int_time = 0xC0;
286 		int_idx = 0;
287 		break;
288 	default:
289 		return -EINVAL;
290 	}
291 
292 	ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
293 					VEML6030_ALS_IT, new_int_time);
294 	if (ret) {
295 		dev_err(&data->client->dev,
296 				"can't update als integration time %d\n", ret);
297 		return ret;
298 	}
299 
300 	/*
301 	 * Cache current integration time and update resolution. For every
302 	 * increase in integration time to next level, resolution is halved
303 	 * and vice-versa.
304 	 */
305 	if (data->cur_integration_time < int_idx)
306 		data->cur_resolution <<= int_idx - data->cur_integration_time;
307 	else if (data->cur_integration_time > int_idx)
308 		data->cur_resolution >>= data->cur_integration_time - int_idx;
309 
310 	data->cur_integration_time = int_idx;
311 
312 	return ret;
313 }
314 
315 static int veml6030_read_persistence(struct iio_dev *indio_dev,
316 						int *val, int *val2)
317 {
318 	int ret, reg, period, x, y;
319 	struct veml6030_data *data = iio_priv(indio_dev);
320 
321 	ret = veml6030_get_intgrn_tm(indio_dev, &x, &y);
322 	if (ret < 0)
323 		return ret;
324 
325 	ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
326 	if (ret) {
327 		dev_err(&data->client->dev,
328 				"can't read als conf register %d\n", ret);
329 	}
330 
331 	/* integration time multiplied by 1/2/4/8 */
332 	period = y * (1 << ((reg >> 4) & 0x03));
333 
334 	*val = period / 1000000;
335 	*val2 = period % 1000000;
336 
337 	return IIO_VAL_INT_PLUS_MICRO;
338 }
339 
340 static int veml6030_write_persistence(struct iio_dev *indio_dev,
341 						int val, int val2)
342 {
343 	int ret, period, x, y;
344 	struct veml6030_data *data = iio_priv(indio_dev);
345 
346 	ret = veml6030_get_intgrn_tm(indio_dev, &x, &y);
347 	if (ret < 0)
348 		return ret;
349 
350 	if (!val) {
351 		period = val2 / y;
352 	} else {
353 		if ((val == 1) && (val2 == 600000))
354 			period = 1600000 / y;
355 		else if ((val == 3) && (val2 == 200000))
356 			period = 3200000 / y;
357 		else if ((val == 6) && (val2 == 400000))
358 			period = 6400000 / y;
359 		else
360 			period = -1;
361 	}
362 
363 	if (period <= 0 || period > 8 || hweight8(period) != 1)
364 		return -EINVAL;
365 
366 	ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
367 				VEML6030_ALS_PERS, (ffs(period) - 1) << 4);
368 	if (ret)
369 		dev_err(&data->client->dev,
370 				"can't set persistence value %d\n", ret);
371 
372 	return ret;
373 }
374 
375 static int veml6030_set_als_gain(struct iio_dev *indio_dev,
376 						int val, int val2)
377 {
378 	int ret, new_gain, gain_idx;
379 	struct veml6030_data *data = iio_priv(indio_dev);
380 
381 	if (val == 0 && val2 == 125000) {
382 		new_gain = 0x1000; /* 0x02 << 11 */
383 		gain_idx = 3;
384 	} else if (val == 0 && val2 == 250000) {
385 		new_gain = 0x1800;
386 		gain_idx = 2;
387 	} else if (val == 1 && val2 == 0) {
388 		new_gain = 0x00;
389 		gain_idx = 1;
390 	} else if (val == 2 && val2 == 0) {
391 		new_gain = 0x800;
392 		gain_idx = 0;
393 	} else {
394 		return -EINVAL;
395 	}
396 
397 	ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
398 					VEML6030_ALS_GAIN, new_gain);
399 	if (ret) {
400 		dev_err(&data->client->dev,
401 				"can't set als gain %d\n", ret);
402 		return ret;
403 	}
404 
405 	/*
406 	 * Cache currently set gain & update resolution. For every
407 	 * increase in the gain to next level, resolution is halved
408 	 * and vice-versa.
409 	 */
410 	if (data->cur_gain < gain_idx)
411 		data->cur_resolution <<= gain_idx - data->cur_gain;
412 	else if (data->cur_gain > gain_idx)
413 		data->cur_resolution >>= data->cur_gain - gain_idx;
414 
415 	data->cur_gain = gain_idx;
416 
417 	return ret;
418 }
419 
420 static int veml6030_get_als_gain(struct iio_dev *indio_dev,
421 						int *val, int *val2)
422 {
423 	int ret, reg;
424 	struct veml6030_data *data = iio_priv(indio_dev);
425 
426 	ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
427 	if (ret) {
428 		dev_err(&data->client->dev,
429 				"can't read als conf register %d\n", ret);
430 		return ret;
431 	}
432 
433 	switch ((reg >> 11) & 0x03) {
434 	case 0:
435 		*val = 1;
436 		*val2 = 0;
437 		break;
438 	case 1:
439 		*val = 2;
440 		*val2 = 0;
441 		break;
442 	case 2:
443 		*val = 0;
444 		*val2 = 125000;
445 		break;
446 	case 3:
447 		*val = 0;
448 		*val2 = 250000;
449 		break;
450 	default:
451 		return -EINVAL;
452 	}
453 
454 	return IIO_VAL_INT_PLUS_MICRO;
455 }
456 
457 static int veml6030_read_thresh(struct iio_dev *indio_dev,
458 						int *val, int *val2, int dir)
459 {
460 	int ret, reg;
461 	struct veml6030_data *data = iio_priv(indio_dev);
462 
463 	if (dir == IIO_EV_DIR_RISING)
464 		ret = regmap_read(data->regmap, VEML6030_REG_ALS_WH, &reg);
465 	else
466 		ret = regmap_read(data->regmap, VEML6030_REG_ALS_WL, &reg);
467 	if (ret) {
468 		dev_err(&data->client->dev,
469 				"can't read als threshold value %d\n", ret);
470 		return ret;
471 	}
472 
473 	*val = reg & 0xffff;
474 	return IIO_VAL_INT;
475 }
476 
477 static int veml6030_write_thresh(struct iio_dev *indio_dev,
478 						int val, int val2, int dir)
479 {
480 	int ret;
481 	struct veml6030_data *data = iio_priv(indio_dev);
482 
483 	if (val > 0xFFFF || val < 0 || val2)
484 		return -EINVAL;
485 
486 	if (dir == IIO_EV_DIR_RISING) {
487 		ret = regmap_write(data->regmap, VEML6030_REG_ALS_WH, val);
488 		if (ret)
489 			dev_err(&data->client->dev,
490 					"can't set high threshold %d\n", ret);
491 	} else {
492 		ret = regmap_write(data->regmap, VEML6030_REG_ALS_WL, val);
493 		if (ret)
494 			dev_err(&data->client->dev,
495 					"can't set low threshold %d\n", ret);
496 	}
497 
498 	return ret;
499 }
500 
501 /*
502  * Provide both raw as well as light reading in lux.
503  * light (in lux) = resolution * raw reading
504  */
505 static int veml6030_read_raw(struct iio_dev *indio_dev,
506 			    struct iio_chan_spec const *chan, int *val,
507 			    int *val2, long mask)
508 {
509 	int ret, reg;
510 	struct veml6030_data *data = iio_priv(indio_dev);
511 	struct regmap *regmap = data->regmap;
512 	struct device *dev = &data->client->dev;
513 
514 	switch (mask) {
515 	case IIO_CHAN_INFO_RAW:
516 	case IIO_CHAN_INFO_PROCESSED:
517 		switch (chan->type) {
518 		case IIO_LIGHT:
519 			ret = regmap_read(regmap, VEML6030_REG_ALS_DATA, &reg);
520 			if (ret < 0) {
521 				dev_err(dev, "can't read als data %d\n", ret);
522 				return ret;
523 			}
524 			if (mask == IIO_CHAN_INFO_PROCESSED) {
525 				*val = (reg * data->cur_resolution) / 10000;
526 				*val2 = (reg * data->cur_resolution) % 10000;
527 				return IIO_VAL_INT_PLUS_MICRO;
528 			}
529 			*val = reg;
530 			return IIO_VAL_INT;
531 		case IIO_INTENSITY:
532 			ret = regmap_read(regmap, VEML6030_REG_WH_DATA, &reg);
533 			if (ret < 0) {
534 				dev_err(dev, "can't read white data %d\n", ret);
535 				return ret;
536 			}
537 			if (mask == IIO_CHAN_INFO_PROCESSED) {
538 				*val = (reg * data->cur_resolution) / 10000;
539 				*val2 = (reg * data->cur_resolution) % 10000;
540 				return IIO_VAL_INT_PLUS_MICRO;
541 			}
542 			*val = reg;
543 			return IIO_VAL_INT;
544 		default:
545 			return -EINVAL;
546 		}
547 	case IIO_CHAN_INFO_INT_TIME:
548 		if (chan->type == IIO_LIGHT)
549 			return veml6030_get_intgrn_tm(indio_dev, val, val2);
550 		return -EINVAL;
551 	case IIO_CHAN_INFO_SCALE:
552 		if (chan->type == IIO_LIGHT)
553 			return veml6030_get_als_gain(indio_dev, val, val2);
554 		return -EINVAL;
555 	default:
556 		return -EINVAL;
557 	}
558 }
559 
560 static int veml6030_write_raw(struct iio_dev *indio_dev,
561 				struct iio_chan_spec const *chan,
562 				int val, int val2, long mask)
563 {
564 	switch (mask) {
565 	case IIO_CHAN_INFO_INT_TIME:
566 		switch (chan->type) {
567 		case IIO_LIGHT:
568 			return veml6030_set_intgrn_tm(indio_dev, val, val2);
569 		default:
570 			return -EINVAL;
571 		}
572 	case IIO_CHAN_INFO_SCALE:
573 		switch (chan->type) {
574 		case IIO_LIGHT:
575 			return veml6030_set_als_gain(indio_dev, val, val2);
576 		default:
577 			return -EINVAL;
578 		}
579 	default:
580 		return -EINVAL;
581 	}
582 }
583 
584 static int veml6030_read_event_val(struct iio_dev *indio_dev,
585 		const struct iio_chan_spec *chan, enum iio_event_type type,
586 		enum iio_event_direction dir, enum iio_event_info info,
587 		int *val, int *val2)
588 {
589 	switch (info) {
590 	case IIO_EV_INFO_VALUE:
591 		switch (dir) {
592 		case IIO_EV_DIR_RISING:
593 		case IIO_EV_DIR_FALLING:
594 			return veml6030_read_thresh(indio_dev, val, val2, dir);
595 		default:
596 			return -EINVAL;
597 		}
598 		break;
599 	case IIO_EV_INFO_PERIOD:
600 		return veml6030_read_persistence(indio_dev, val, val2);
601 	default:
602 		return -EINVAL;
603 	}
604 }
605 
606 static int veml6030_write_event_val(struct iio_dev *indio_dev,
607 		const struct iio_chan_spec *chan, enum iio_event_type type,
608 		enum iio_event_direction dir, enum iio_event_info info,
609 		int val, int val2)
610 {
611 	switch (info) {
612 	case IIO_EV_INFO_VALUE:
613 		return veml6030_write_thresh(indio_dev, val, val2, dir);
614 	case IIO_EV_INFO_PERIOD:
615 		return veml6030_write_persistence(indio_dev, val, val2);
616 	default:
617 		return -EINVAL;
618 	}
619 }
620 
621 static int veml6030_read_interrupt_config(struct iio_dev *indio_dev,
622 		const struct iio_chan_spec *chan, enum iio_event_type type,
623 		enum iio_event_direction dir)
624 {
625 	int ret, reg;
626 	struct veml6030_data *data = iio_priv(indio_dev);
627 
628 	ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
629 	if (ret) {
630 		dev_err(&data->client->dev,
631 				"can't read als conf register %d\n", ret);
632 		return ret;
633 	}
634 
635 	if (reg & VEML6030_ALS_INT_EN)
636 		return 1;
637 	else
638 		return 0;
639 }
640 
641 /*
642  * Sensor should not be measuring light when interrupt is configured.
643  * Therefore correct sequence to configure interrupt functionality is:
644  * shut down -> enable/disable interrupt -> power on
645  *
646  * state = 1 enables interrupt, state = 0 disables interrupt
647  */
648 static int veml6030_write_interrupt_config(struct iio_dev *indio_dev,
649 		const struct iio_chan_spec *chan, enum iio_event_type type,
650 		enum iio_event_direction dir, int state)
651 {
652 	int ret;
653 	struct veml6030_data *data = iio_priv(indio_dev);
654 
655 	if (state < 0 || state > 1)
656 		return -EINVAL;
657 
658 	ret = veml6030_als_shut_down(data);
659 	if (ret < 0) {
660 		dev_err(&data->client->dev,
661 			"can't disable als to configure interrupt %d\n", ret);
662 		return ret;
663 	}
664 
665 	/* enable interrupt + power on */
666 	ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
667 			VEML6030_ALS_INT_EN | VEML6030_ALS_SD, state << 1);
668 	if (ret)
669 		dev_err(&data->client->dev,
670 			"can't enable interrupt & poweron als %d\n", ret);
671 
672 	return ret;
673 }
674 
675 static const struct iio_info veml6030_info = {
676 	.read_raw  = veml6030_read_raw,
677 	.write_raw = veml6030_write_raw,
678 	.read_event_value = veml6030_read_event_val,
679 	.write_event_value	= veml6030_write_event_val,
680 	.read_event_config = veml6030_read_interrupt_config,
681 	.write_event_config	= veml6030_write_interrupt_config,
682 	.attrs = &veml6030_attr_group,
683 	.event_attrs = &veml6030_event_attr_group,
684 };
685 
686 static const struct iio_info veml6030_info_no_irq = {
687 	.read_raw  = veml6030_read_raw,
688 	.write_raw = veml6030_write_raw,
689 	.attrs = &veml6030_attr_group,
690 };
691 
692 static irqreturn_t veml6030_event_handler(int irq, void *private)
693 {
694 	int ret, reg, evtdir;
695 	struct iio_dev *indio_dev = private;
696 	struct veml6030_data *data = iio_priv(indio_dev);
697 
698 	ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &reg);
699 	if (ret) {
700 		dev_err(&data->client->dev,
701 				"can't read als interrupt register %d\n", ret);
702 		return IRQ_HANDLED;
703 	}
704 
705 	/* Spurious interrupt handling */
706 	if (!(reg & (VEML6030_INT_TH_HIGH | VEML6030_INT_TH_LOW)))
707 		return IRQ_NONE;
708 
709 	if (reg & VEML6030_INT_TH_HIGH)
710 		evtdir = IIO_EV_DIR_RISING;
711 	else
712 		evtdir = IIO_EV_DIR_FALLING;
713 
714 	iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
715 					0, IIO_EV_TYPE_THRESH, evtdir),
716 					iio_get_time_ns(indio_dev));
717 
718 	return IRQ_HANDLED;
719 }
720 
721 /*
722  * Set ALS gain to 1/8, integration time to 100 ms, PSM to mode 2,
723  * persistence to 1 x integration time and the threshold
724  * interrupt disabled by default. First shutdown the sensor,
725  * update registers and then power on the sensor.
726  */
727 static int veml6030_hw_init(struct iio_dev *indio_dev)
728 {
729 	int ret, val;
730 	struct veml6030_data *data = iio_priv(indio_dev);
731 	struct i2c_client *client = data->client;
732 
733 	ret = veml6030_als_shut_down(data);
734 	if (ret) {
735 		dev_err(&client->dev, "can't shutdown als %d\n", ret);
736 		return ret;
737 	}
738 
739 	ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, 0x1001);
740 	if (ret) {
741 		dev_err(&client->dev, "can't setup als configs %d\n", ret);
742 		return ret;
743 	}
744 
745 	ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_PSM,
746 				 VEML6030_PSM | VEML6030_PSM_EN, 0x03);
747 	if (ret) {
748 		dev_err(&client->dev, "can't setup default PSM %d\n", ret);
749 		return ret;
750 	}
751 
752 	ret = regmap_write(data->regmap, VEML6030_REG_ALS_WH, 0xFFFF);
753 	if (ret) {
754 		dev_err(&client->dev, "can't setup high threshold %d\n", ret);
755 		return ret;
756 	}
757 
758 	ret = regmap_write(data->regmap, VEML6030_REG_ALS_WL, 0x0000);
759 	if (ret) {
760 		dev_err(&client->dev, "can't setup low threshold %d\n", ret);
761 		return ret;
762 	}
763 
764 	ret = veml6030_als_pwr_on(data);
765 	if (ret) {
766 		dev_err(&client->dev, "can't poweron als %d\n", ret);
767 		return ret;
768 	}
769 
770 	/* Wait 4 ms to let processor & oscillator start correctly */
771 	usleep_range(4000, 4002);
772 
773 	/* Clear stale interrupt status bits if any during start */
774 	ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val);
775 	if (ret < 0) {
776 		dev_err(&client->dev,
777 			"can't clear als interrupt status %d\n", ret);
778 		return ret;
779 	}
780 
781 	/* Cache currently active measurement parameters */
782 	data->cur_gain = 3;
783 	data->cur_resolution = 4608;
784 	data->cur_integration_time = 3;
785 
786 	return ret;
787 }
788 
789 static int veml6030_probe(struct i2c_client *client,
790 			  const struct i2c_device_id *id)
791 {
792 	int ret;
793 	struct veml6030_data *data;
794 	struct iio_dev *indio_dev;
795 	struct regmap *regmap;
796 
797 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
798 		dev_err(&client->dev, "i2c adapter doesn't support plain i2c\n");
799 		return -EOPNOTSUPP;
800 	}
801 
802 	regmap = devm_regmap_init_i2c(client, &veml6030_regmap_config);
803 	if (IS_ERR(regmap)) {
804 		dev_err(&client->dev, "can't setup regmap\n");
805 		return PTR_ERR(regmap);
806 	}
807 
808 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
809 	if (!indio_dev)
810 		return -ENOMEM;
811 
812 	data = iio_priv(indio_dev);
813 	i2c_set_clientdata(client, indio_dev);
814 	data->client = client;
815 	data->regmap = regmap;
816 
817 	indio_dev->name = "veml6030";
818 	indio_dev->channels = veml6030_channels;
819 	indio_dev->num_channels = ARRAY_SIZE(veml6030_channels);
820 	indio_dev->modes = INDIO_DIRECT_MODE;
821 
822 	if (client->irq) {
823 		ret = devm_request_threaded_irq(&client->dev, client->irq,
824 						NULL, veml6030_event_handler,
825 						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
826 						"veml6030", indio_dev);
827 		if (ret < 0) {
828 			dev_err(&client->dev,
829 					"irq %d request failed\n", client->irq);
830 			return ret;
831 		}
832 		indio_dev->info = &veml6030_info;
833 	} else {
834 		indio_dev->info = &veml6030_info_no_irq;
835 	}
836 
837 	ret = veml6030_hw_init(indio_dev);
838 	if (ret < 0)
839 		return ret;
840 
841 	ret = devm_add_action_or_reset(&client->dev,
842 					veml6030_als_shut_down_action, data);
843 	if (ret < 0)
844 		return ret;
845 
846 	return devm_iio_device_register(&client->dev, indio_dev);
847 }
848 
849 static int __maybe_unused veml6030_runtime_suspend(struct device *dev)
850 {
851 	int ret;
852 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
853 	struct veml6030_data *data = iio_priv(indio_dev);
854 
855 	ret = veml6030_als_shut_down(data);
856 	if (ret < 0)
857 		dev_err(&data->client->dev, "can't suspend als %d\n", ret);
858 
859 	return ret;
860 }
861 
862 static int __maybe_unused veml6030_runtime_resume(struct device *dev)
863 {
864 	int ret;
865 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
866 	struct veml6030_data *data = iio_priv(indio_dev);
867 
868 	ret = veml6030_als_pwr_on(data);
869 	if (ret < 0)
870 		dev_err(&data->client->dev, "can't resume als %d\n", ret);
871 
872 	return ret;
873 }
874 
875 static const struct dev_pm_ops veml6030_pm_ops = {
876 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
877 				pm_runtime_force_resume)
878 	SET_RUNTIME_PM_OPS(veml6030_runtime_suspend,
879 				veml6030_runtime_resume, NULL)
880 };
881 
882 static const struct of_device_id veml6030_of_match[] = {
883 	{ .compatible = "vishay,veml6030" },
884 	{ }
885 };
886 MODULE_DEVICE_TABLE(of, veml6030_of_match);
887 
888 static const struct i2c_device_id veml6030_id[] = {
889 	{ "veml6030", 0 },
890 	{ }
891 };
892 MODULE_DEVICE_TABLE(i2c, veml6030_id);
893 
894 static struct i2c_driver veml6030_driver = {
895 	.driver = {
896 		.name = "veml6030",
897 		.of_match_table = veml6030_of_match,
898 		.pm = &veml6030_pm_ops,
899 	},
900 	.probe = veml6030_probe,
901 	.id_table = veml6030_id,
902 };
903 module_i2c_driver(veml6030_driver);
904 
905 MODULE_AUTHOR("Rishi Gupta <gupt21@gmail.com>");
906 MODULE_DESCRIPTION("VEML6030 Ambient Light Sensor");
907 MODULE_LICENSE("GPL v2");
908