1 /*
2  * Copyright (c) 2023 Andreas Kilian
3  * Copyright (c) 2024 Jeff Welder (Ellenby Technologies, Inc.)
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT vishay_veml7700
9 
10 #include <zephyr/device.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <zephyr/drivers/sensor.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/logging/log.h>
15 #include <zephyr/pm/device.h>
16 #include <zephyr/sys/byteorder.h>
17 
18 #include <zephyr/drivers/sensor/veml7700.h>
19 
20 LOG_MODULE_REGISTER(VEML7700, CONFIG_SENSOR_LOG_LEVEL);
21 
22 /*
23  * Bit mask to zero out all bits except 14 and 15.
24  * Those two are used for the high and low threshold
25  * interrupt flags in the ALS_INT register.
26  */
27 #define VEML7700_ALS_INT_MASK (~BIT_MASK(14))
28 
29 /*
30  * 16-bit command register addresses
31  */
32 #define VEML7700_CMDCODE_ALS_CONF 0x00
33 #define VEML7700_CMDCODE_ALS_WH   0x01
34 #define VEML7700_CMDCODE_ALS_WL   0x02
35 #define VEML7700_CMDCODE_PSM      0x03
36 #define VEML7700_CMDCODE_ALS      0x04
37 #define VEML7700_CMDCODE_WHITE    0x05
38 #define VEML7700_CMDCODE_ALS_INT  0x06
39 
40 /*
41  * Devicetree psm-mode property value for "PSM disabled"
42  */
43 #define VEML7700_PSM_DISABLED 0x00
44 
45 /*
46  * ALS integration time setting values.
47  *
48  * The enumerators of <tt>enum veml7700_als_it</tt> provide
49  * indices into this array to get the related value for the
50  * ALS_IT configuration bits.
51  */
52 static const uint8_t veml7700_it_values[VEML7700_ALS_IT_ELEM_COUNT] = {
53 	0x0C, /* 25  - 0b1100 */
54 	0x08, /* 50  - 0b1000 */
55 	0x00, /* 100 - 0b0000 */
56 	0x01, /* 200 - 0b0001 */
57 	0x02, /* 400 - 0b0010 */
58 	0x03, /* 800 - 0b0011 */
59 };
60 
61 /*
62  * Resolution matrix for values to convert between data provided
63  * by the sensor ("counts") and lux.
64  *
65  * These values depend on the current gain and integration time settings.
66  * The enumerators of <tt>enum veml7700_als_gain</tt> and <tt>enum veml7700_als_it</tt>
67  * are used for indices into this matrix.
68  */
69 static const float veml7700_resolution[VEML7700_ALS_GAIN_ELEM_COUNT][VEML7700_ALS_IT_ELEM_COUNT] = {
70 	/* 25ms    50ms    100ms   200ms   400ms   800ms  Integration Time */
71 	{0.2304f, 0.1152f, 0.0576f, 0.0288f, 0.0144f, 0.0072f}, /* Gain 1 */
72 	{0.1152f, 0.0576f, 0.0288f, 0.0144f, 0.0072f, 0.0036f}, /* Gain 2 */
73 	{1.8432f, 0.9216f, 0.4608f, 0.2304f, 0.1152f, 0.0576f}, /* Gain 1/8 */
74 	{0.9216f, 0.4608f, 0.2304f, 0.1152f, 0.0576f, 0.0288f}, /* Gain 1/4 */
75 };
76 
77 struct veml7700_config {
78 	struct i2c_dt_spec bus;
79 	uint8_t psm;
80 };
81 
82 struct veml7700_data {
83 	uint8_t shut_down;
84 	enum veml7700_als_gain gain;
85 	enum veml7700_als_it it;
86 	enum veml7700_int_mode int_mode;
87 	uint16_t thresh_high;
88 	uint16_t thresh_low;
89 	uint16_t als_counts;
90 	uint32_t als_lux;
91 	uint16_t white_counts;
92 	uint32_t int_flags;
93 };
94 
is_veml7700_gain_in_range(uint32_t gain_selection)95 static bool is_veml7700_gain_in_range(uint32_t gain_selection)
96 {
97 	return (gain_selection < VEML7700_ALS_GAIN_ELEM_COUNT);
98 }
99 
is_veml7700_it_in_range(uint32_t it_selection)100 static bool is_veml7700_it_in_range(uint32_t it_selection)
101 {
102 	return (it_selection < VEML7700_ALS_IT_ELEM_COUNT);
103 }
104 
105 /**
106  * @brief Waits for a specific amount of time which depends
107  * on the current integration time setting.
108  *
109  * According to datasheet for a measurement to complete one has
110  * to wait for at least the integration time. But tests showed
111  * that a much longer wait time is needed. Simply adding 50 or
112  * 100ms to the integration time is not enough so we doubled
113  * the integration time to get our wait time.
114  *
115  * This function is only called if the sensor is used in "single shot"
116  * measuring mode. In this mode the sensor measures on demand an
117  * measurements take time depending on the configures integration time.
118  * In continuous mode, activated by one of the power saving modes,
119  * you can always use the last sample value and no waiting is required.
120  *
121  * For more information see the "Designing the VEML7700 Into an Application"
122  * application notes about the power saving modes.
123  */
veml7700_sleep_by_integration_time(const struct veml7700_data * data)124 static void veml7700_sleep_by_integration_time(const struct veml7700_data *data)
125 {
126 	switch (data->it) {
127 	case VEML7700_ALS_IT_25:
128 		k_msleep(50);
129 		break;
130 	case VEML7700_ALS_IT_50:
131 		k_msleep(100);
132 		break;
133 	case VEML7700_ALS_IT_100:
134 		k_msleep(200);
135 		break;
136 	case VEML7700_ALS_IT_200:
137 		k_msleep(400);
138 		break;
139 	case VEML7700_ALS_IT_400:
140 		k_msleep(800);
141 		break;
142 	case VEML7700_ALS_IT_800:
143 		k_msleep(1600);
144 		break;
145 	}
146 }
147 
veml7700_counts_to_lux(const struct veml7700_data * data,uint16_t counts,uint32_t * lux)148 static int veml7700_counts_to_lux(const struct veml7700_data *data, uint16_t counts,
149 				  uint32_t *lux)
150 {
151 	if (!is_veml7700_gain_in_range(data->gain) || !is_veml7700_it_in_range(data->it)) {
152 		return -EINVAL;
153 	}
154 	*lux = counts * veml7700_resolution[data->gain][data->it];
155 	return 0;
156 }
157 
veml7700_lux_to_counts(const struct veml7700_data * data,uint32_t lux,uint16_t * counts)158 static int veml7700_lux_to_counts(const struct veml7700_data *data, uint32_t lux,
159 				       uint16_t *counts)
160 {
161 	if (!is_veml7700_gain_in_range(data->gain) || !is_veml7700_it_in_range(data->it)) {
162 		return -EINVAL;
163 	}
164 	*counts = lux / veml7700_resolution[data->gain][data->it];
165 	return 0;
166 }
167 
veml7700_check_gain(const struct sensor_value * val)168 static int veml7700_check_gain(const struct sensor_value *val)
169 {
170 	return val->val1 >= VEML7700_ALS_GAIN_1 && val->val1 <= VEML7700_ALS_GAIN_1_4;
171 }
172 
veml7700_check_it(const struct sensor_value * val)173 static int veml7700_check_it(const struct sensor_value *val)
174 {
175 	return val->val1 >= VEML7700_ALS_IT_25 && val->val1 <= VEML7700_ALS_IT_800;
176 }
177 
veml7700_check_int_mode(const struct sensor_value * val)178 static int veml7700_check_int_mode(const struct sensor_value *val)
179 {
180 	return (val->val1 >= VEML7700_ALS_PERS_1 && val->val1 <= VEML7700_ALS_PERS_8) ||
181 	       val->val1 == VEML7700_INT_DISABLED;
182 }
183 
veml7700_build_als_conf_param(const struct veml7700_data * data,uint16_t * return_value)184 static int veml7700_build_als_conf_param(const struct veml7700_data *data, uint16_t *return_value)
185 {
186 	if (!is_veml7700_gain_in_range(data->gain) || !is_veml7700_it_in_range(data->it)) {
187 		return -EINVAL;
188 	}
189 	uint16_t param = 0;
190 	/* Bits 15:13 -> reserved */
191 	/* Bits 12:11 -> gain selection (ALS_GAIN) */
192 	param |= data->gain << 11;
193 	/* Bit 10 -> reserved */
194 	/* Bits 9:6 -> integration time (ALS_IT) */
195 	param |= veml7700_it_values[data->it] << 6;
196 	/* Bits 5:4 -> interrupt persistent protection (ALS_PERS) */
197 	if (data->int_mode != VEML7700_INT_DISABLED) {
198 		param |= data->int_mode << 4;
199 		/* Bit 1 -> interrupt enable (ALS_INT_EN) */
200 		param |= BIT(1);
201 	}
202 	/* Bits 3:2 -> reserved */
203 	/* Bit 0 -> shut down setting (ALS_SD) */
204 	if (data->shut_down) {
205 		param |= BIT(0);
206 	}
207 	*return_value = param;
208 	return 0;
209 }
210 
veml7700_build_psm_param(const struct veml7700_config * conf)211 static uint16_t veml7700_build_psm_param(const struct veml7700_config *conf)
212 {
213 	/* We can directly use the devicetree configuration value. */
214 	return conf->psm;
215 }
216 
veml7700_write(const struct device * dev,uint8_t cmd,uint16_t data)217 static int veml7700_write(const struct device *dev, uint8_t cmd, uint16_t data)
218 {
219 	const struct veml7700_config *conf = dev->config;
220 	uint8_t send_buf[3];
221 
222 	send_buf[0] = cmd;                /* byte 0: command code */
223 	sys_put_le16(data, &send_buf[1]); /* bytes 1,2: command arguments */
224 
225 	return i2c_write_dt(&conf->bus, send_buf, ARRAY_SIZE(send_buf));
226 }
227 
veml7700_read(const struct device * dev,uint8_t cmd,uint16_t * data)228 static int veml7700_read(const struct device *dev, uint8_t cmd, uint16_t *data)
229 {
230 	const struct veml7700_config *conf = dev->config;
231 
232 	uint8_t recv_buf[2];
233 	int ret = i2c_write_read_dt(&conf->bus, &cmd, sizeof(cmd), &recv_buf, ARRAY_SIZE(recv_buf));
234 	if (ret < 0) {
235 		return ret;
236 	}
237 
238 	*data = sys_get_le16(recv_buf);
239 
240 	return 0;
241 }
242 
veml7700_write_als_conf(const struct device * dev)243 static int veml7700_write_als_conf(const struct device *dev)
244 {
245 	const struct veml7700_data *data = dev->data;
246 	uint16_t param;
247 	int ret = 0;
248 
249 	ret = veml7700_build_als_conf_param(data, &param);
250 	if (ret < 0) {
251 		return ret;
252 	}
253 	LOG_DBG("Writing ALS configuration: 0x%04x", param);
254 	return veml7700_write(dev, VEML7700_CMDCODE_ALS_CONF, param);
255 }
256 
veml7700_write_psm(const struct device * dev)257 static int veml7700_write_psm(const struct device *dev)
258 {
259 	const struct veml7700_config *conf = dev->config;
260 	uint16_t psm_param;
261 
262 	psm_param = veml7700_build_psm_param(conf);
263 	LOG_DBG("Writing PSM configuration: 0x%04x", psm_param);
264 	return veml7700_write(dev, VEML7700_CMDCODE_PSM, psm_param);
265 }
266 
veml7700_write_thresh_low(const struct device * dev)267 static int veml7700_write_thresh_low(const struct device *dev)
268 {
269 	const struct veml7700_data *data = dev->data;
270 
271 	LOG_DBG("Writing low threshold counts: %d", data->thresh_low);
272 	return veml7700_write(dev, VEML7700_CMDCODE_ALS_WL, data->thresh_low);
273 }
274 
veml7700_write_thresh_high(const struct device * dev)275 static int veml7700_write_thresh_high(const struct device *dev)
276 {
277 	const struct veml7700_data *data = dev->data;
278 
279 	LOG_DBG("Writing high threshold counts: %d", data->thresh_high);
280 	return veml7700_write(dev, VEML7700_CMDCODE_ALS_WH, data->thresh_high);
281 }
282 
veml7700_set_shutdown_flag(const struct device * dev,uint8_t new_val)283 static int veml7700_set_shutdown_flag(const struct device *dev, uint8_t new_val)
284 {
285 	struct veml7700_data *data = dev->data;
286 	uint8_t prev_sd;
287 	int ret;
288 
289 	prev_sd = data->shut_down;
290 	data->shut_down = new_val;
291 
292 	ret = veml7700_write_als_conf(dev);
293 	if (ret < 0) {
294 		data->shut_down = prev_sd;
295 	}
296 	return ret;
297 }
298 
veml7700_fetch_als(const struct device * dev)299 static int veml7700_fetch_als(const struct device *dev)
300 {
301 	struct veml7700_data *data = dev->data;
302 	uint16_t counts;
303 	int ret;
304 
305 	ret = veml7700_read(dev, VEML7700_CMDCODE_ALS, &counts);
306 	if (ret < 0) {
307 		return ret;
308 	}
309 
310 	data->als_counts = counts;
311 	ret = veml7700_counts_to_lux(data, counts, &data->als_lux);
312 	if (ret < 0) {
313 		return ret;
314 	}
315 
316 	LOG_DBG("Read ALS measurement: counts=%d, lux=%d", data->als_counts, data->als_lux);
317 
318 	return 0;
319 }
320 
veml7700_fetch_white(const struct device * dev)321 static int veml7700_fetch_white(const struct device *dev)
322 {
323 	struct veml7700_data *data = dev->data;
324 	uint16_t counts;
325 	int ret;
326 
327 	ret = veml7700_read(dev, VEML7700_CMDCODE_WHITE, &counts);
328 	if (ret < 0) {
329 		return ret;
330 	}
331 
332 	data->white_counts = counts;
333 	LOG_DBG("Read White Light measurement: counts=%d", data->white_counts);
334 
335 	return 0;
336 }
337 
veml7700_fetch_int_flags(const struct device * dev)338 static int veml7700_fetch_int_flags(const struct device *dev)
339 {
340 	struct veml7700_data *data = dev->data;
341 	uint16_t int_flags = 0;
342 	int ret;
343 
344 	ret = veml7700_read(dev, VEML7700_CMDCODE_ALS_INT, &int_flags);
345 	if (ret < 0) {
346 		return ret;
347 	}
348 
349 	data->int_flags = int_flags & VEML7700_ALS_INT_MASK;
350 	LOG_DBG("Read int state: 0x%02x", data->int_flags);
351 
352 	return 0;
353 }
354 
veml7700_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)355 static int veml7700_attr_set(const struct device *dev, enum sensor_channel chan,
356 			     enum sensor_attribute attr, const struct sensor_value *val)
357 {
358 	if (chan != SENSOR_CHAN_LIGHT) {
359 		return -ENOTSUP;
360 	}
361 
362 	struct veml7700_data *data = dev->data;
363 	int ret = 0;
364 
365 	if (attr == SENSOR_ATTR_LOWER_THRESH) {
366 		ret = veml7700_lux_to_counts(data, val->val1, &data->thresh_low);
367 		if (ret < 0) {
368 			return ret;
369 		}
370 		return veml7700_write_thresh_low(dev);
371 	} else if (attr == SENSOR_ATTR_UPPER_THRESH) {
372 		ret = veml7700_lux_to_counts(data, val->val1, &data->thresh_high);
373 		if (ret < 0) {
374 			return ret;
375 		}
376 		return veml7700_write_thresh_high(dev);
377 	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_GAIN) {
378 		if (veml7700_check_gain(val)) {
379 			data->gain = (enum veml7700_als_gain)val->val1;
380 			return veml7700_write_als_conf(dev);
381 		} else {
382 			return -EINVAL;
383 		}
384 	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_ITIME) {
385 		if (veml7700_check_it(val)) {
386 			data->it = (enum veml7700_als_it)val->val1;
387 			return veml7700_write_als_conf(dev);
388 		} else {
389 			return -EINVAL;
390 		}
391 	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_INT_MODE) {
392 		if (veml7700_check_int_mode(val)) {
393 			data->int_mode = (enum veml7700_int_mode)val->val1;
394 			return veml7700_write_als_conf(dev);
395 		} else {
396 			return -EINVAL;
397 		}
398 	} else {
399 		return -ENOTSUP;
400 	}
401 }
402 
veml7700_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)403 static int veml7700_attr_get(const struct device *dev, enum sensor_channel chan,
404 			     enum sensor_attribute attr, struct sensor_value *val)
405 {
406 	if (chan != SENSOR_CHAN_LIGHT) {
407 		return -ENOTSUP;
408 	}
409 
410 	struct veml7700_data *data = dev->data;
411 
412 	if (attr == SENSOR_ATTR_LOWER_THRESH) {
413 		val->val1 = data->thresh_low;
414 	} else if (attr == SENSOR_ATTR_UPPER_THRESH) {
415 		val->val1 = data->thresh_high;
416 	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_GAIN) {
417 		val->val1 = data->gain;
418 	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_ITIME) {
419 		val->val1 = data->it;
420 	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_INT_MODE) {
421 		val->val1 = data->int_mode;
422 	} else {
423 		return -ENOTSUP;
424 	}
425 
426 	val->val2 = 0;
427 
428 	return 0;
429 }
430 
veml7700_perform_single_measurement(const struct device * dev)431 static int veml7700_perform_single_measurement(const struct device *dev)
432 {
433 	struct veml7700_data *data = dev->data;
434 	int ret;
435 
436 	/* Start sensor */
437 	ret = veml7700_set_shutdown_flag(dev, 0);
438 	if (ret < 0) {
439 		return ret;
440 	}
441 
442 	/* Wait for sensor to finish it's startup sequence */
443 	k_msleep(5);
444 	/* Wait for measurement to complete */
445 	veml7700_sleep_by_integration_time(data);
446 
447 	/* Shut down sensor */
448 	return veml7700_set_shutdown_flag(dev, 1);
449 }
450 
veml7700_sample_fetch(const struct device * dev,enum sensor_channel chan)451 static int veml7700_sample_fetch(const struct device *dev, enum sensor_channel chan)
452 {
453 	const struct veml7700_config *conf = dev->config;
454 	struct veml7700_data *data;
455 	int ret;
456 
457 	/* Start sensor for new measurement if power saving mode is disabled */
458 	if ((chan == SENSOR_CHAN_LIGHT || chan == SENSOR_CHAN_ALL) &&
459 	    conf->psm == VEML7700_PSM_DISABLED) {
460 		ret = veml7700_perform_single_measurement(dev);
461 		if (ret < 0) {
462 			return ret;
463 		}
464 	}
465 
466 	if (chan == SENSOR_CHAN_LIGHT) {
467 		return veml7700_fetch_als(dev);
468 	} else if ((enum sensor_channel_veml7700)chan == SENSOR_CHAN_VEML7700_INTERRUPT) {
469 		data = dev->data;
470 		if (data->int_mode != VEML7700_INT_DISABLED) {
471 			return veml7700_fetch_int_flags(dev);
472 		} else {
473 			return -ENOTSUP;
474 		}
475 	} else if ((enum sensor_channel_veml7700)chan == SENSOR_CHAN_VEML7700_WHITE_RAW_COUNTS) {
476 		return veml7700_fetch_white(dev);
477 	} else if (chan == SENSOR_CHAN_ALL) {
478 		data = dev->data;
479 		if (data->int_mode != VEML7700_INT_DISABLED) {
480 			ret = veml7700_fetch_int_flags(dev);
481 			if (ret < 0) {
482 				return ret;
483 			}
484 		}
485 		ret = veml7700_fetch_white(dev);
486 		if (ret < 0) {
487 			return ret;
488 		}
489 		return veml7700_fetch_als(dev);
490 	} else {
491 		return -ENOTSUP;
492 	}
493 }
494 
veml7700_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)495 static int veml7700_channel_get(const struct device *dev, enum sensor_channel chan,
496 				struct sensor_value *val)
497 {
498 	struct veml7700_data *data = dev->data;
499 
500 	if (chan == SENSOR_CHAN_LIGHT) {
501 		val->val1 = data->als_lux;
502 	} else if ((enum sensor_channel_veml7700)chan == SENSOR_CHAN_VEML7700_RAW_COUNTS) {
503 		val->val1 = data->als_counts;
504 	} else if ((enum sensor_channel_veml7700)chan == SENSOR_CHAN_VEML7700_WHITE_RAW_COUNTS) {
505 		val->val1 = data->white_counts;
506 	} else if ((enum sensor_channel_veml7700)chan == SENSOR_CHAN_VEML7700_INTERRUPT) {
507 		val->val1 = data->int_flags;
508 	} else {
509 		return -ENOTSUP;
510 	}
511 
512 	val->val2 = 0;
513 
514 	return 0;
515 }
516 
517 #ifdef CONFIG_PM_DEVICE
518 
veml7700_pm_action(const struct device * dev,enum pm_device_action action)519 static int veml7700_pm_action(const struct device *dev, enum pm_device_action action)
520 {
521 	const struct veml7700_config *conf = dev->config;
522 
523 	if (conf->psm != VEML7700_PSM_DISABLED) {
524 		switch (action) {
525 		case PM_DEVICE_ACTION_SUSPEND:
526 			return veml7700_set_shutdown_flag(dev, 1);
527 
528 		case PM_DEVICE_ACTION_RESUME:
529 			return veml7700_set_shutdown_flag(dev, 0);
530 
531 		default:
532 			return -ENOTSUP;
533 		}
534 	}
535 
536 	return 0;
537 }
538 
539 #endif /* CONFIG_PM_DEVICE */
540 
veml7700_init(const struct device * dev)541 static int veml7700_init(const struct device *dev)
542 {
543 	const struct veml7700_config *conf = dev->config;
544 	struct veml7700_data *data = dev->data;
545 	int ret;
546 
547 	if (!i2c_is_ready_dt(&conf->bus)) {
548 		LOG_ERR("Device not ready");
549 		return -ENODEV;
550 	}
551 
552 	/* Initialize power saving mode */
553 	ret = veml7700_write_psm(dev);
554 	if (ret < 0) {
555 		return ret;
556 	}
557 
558 	/* Set initial data values */
559 	data->thresh_low = 0;
560 	data->thresh_high = 0xFFFF;
561 	data->gain = VEML7700_ALS_GAIN_1_4;
562 	data->it = VEML7700_ALS_IT_100;
563 	data->int_mode = VEML7700_INT_DISABLED;
564 	data->als_counts = 0;
565 	data->als_lux = 0;
566 	data->white_counts = 0;
567 	data->shut_down = (conf->psm != VEML7700_PSM_DISABLED) ? 0 : 1;
568 
569 	/* Initialize sensor configuration */
570 	ret = veml7700_write_thresh_low(dev);
571 	if (ret < 0) {
572 		return ret;
573 	}
574 
575 	ret = veml7700_write_thresh_high(dev);
576 	if (ret < 0) {
577 		return ret;
578 	}
579 
580 	ret = veml7700_write_als_conf(dev);
581 	if (ret < 0) {
582 		return ret;
583 	}
584 
585 	return 0;
586 }
587 
588 static const struct sensor_driver_api veml7700_api = {.sample_fetch = veml7700_sample_fetch,
589 						      .channel_get = veml7700_channel_get,
590 						      .attr_set = veml7700_attr_set,
591 						      .attr_get = veml7700_attr_get};
592 
593 #define VEML7700_INIT(n)                                                                           \
594 	static struct veml7700_data veml7700_data_##n;                                             \
595                                                                                                    \
596 	static const struct veml7700_config veml7700_config_##n = {                                \
597 		.bus = I2C_DT_SPEC_INST_GET(n), .psm = DT_INST_PROP(n, psm_mode)};                 \
598                                                                                                    \
599 	PM_DEVICE_DT_INST_DEFINE(n, veml7700_pm_action);                                           \
600                                                                                                    \
601 	SENSOR_DEVICE_DT_INST_DEFINE(n, veml7700_init, PM_DEVICE_DT_INST_GET(n),                   \
602 				     &veml7700_data_##n, &veml7700_config_##n, POST_KERNEL,        \
603 				     CONFIG_SENSOR_INIT_PRIORITY, &veml7700_api);
604 
605 DT_INST_FOREACH_STATUS_OKAY(VEML7700_INIT)
606