1 /*
2  * Copyright (c) 2024 Juliane Schulze, deveritec GmbH
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT vishay_vcnl36825t
8 
9 #include "vcnl36825t.h"
10 
11 #include <stdlib.h>
12 
13 #include <zephyr/drivers/i2c.h>
14 #include <zephyr/drivers/sensor.h>
15 #include <zephyr/logging/log.h>
16 #include <zephyr/pm/device.h>
17 #include <zephyr/sys/byteorder.h>
18 #include <zephyr/sys/check.h>
19 #include <zephyr/sys/util.h>
20 
21 LOG_MODULE_REGISTER(VCNL36825T, CONFIG_SENSOR_LOG_LEVEL);
22 
vcnl36825t_read(const struct i2c_dt_spec * spec,uint8_t reg_addr,uint16_t * value)23 int vcnl36825t_read(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint16_t *value)
24 {
25 	uint8_t rx_buf[2];
26 	int rc;
27 
28 	rc = i2c_write_read_dt(spec, &reg_addr, sizeof(reg_addr), rx_buf, sizeof(rx_buf));
29 	if (rc < 0) {
30 		return rc;
31 	}
32 
33 	*value = sys_get_le16(rx_buf);
34 
35 	return 0;
36 }
37 
vcnl36825t_write(const struct i2c_dt_spec * spec,uint8_t reg_addr,uint16_t value)38 int vcnl36825t_write(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint16_t value)
39 {
40 	uint8_t tx_buf[3] = {reg_addr};
41 
42 	sys_put_le16(value, &tx_buf[1]);
43 	return i2c_write_dt(spec, tx_buf, sizeof(tx_buf));
44 }
45 
vcnl36825t_update(const struct i2c_dt_spec * spec,uint8_t reg_addr,uint16_t mask,uint16_t value)46 int vcnl36825t_update(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint16_t mask,
47 		      uint16_t value)
48 {
49 	int rc;
50 	uint16_t old_value, new_value;
51 
52 	rc = vcnl36825t_read(spec, reg_addr, &old_value);
53 	if (rc < 0) {
54 		return rc;
55 	}
56 
57 	new_value = (old_value & ~mask) | (value & mask);
58 
59 	if (new_value == old_value) {
60 		return 0;
61 	}
62 
63 	return vcnl36825t_write(spec, reg_addr, new_value);
64 }
65 
66 #if CONFIG_PM_DEVICE
vcnl36825t_pm_action(const struct device * dev,enum pm_device_action action)67 static int vcnl36825t_pm_action(const struct device *dev, enum pm_device_action action)
68 {
69 	const struct vcnl36825t_config *config = dev->config;
70 	struct vcnl36825t_data *data = dev->data;
71 
72 	int rc;
73 
74 	switch (action) {
75 	case PM_DEVICE_ACTION_RESUME:
76 		rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF1, VCNL36825T_PS_ON_MSK,
77 				       VCNL36825T_PS_ON);
78 		if (rc < 0) {
79 			return rc;
80 		}
81 
82 		if (config->low_power) {
83 			rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF4,
84 					       VCNL36825T_PS_LPEN_MSK, VCNL36825T_PS_LPEN_ENABLED);
85 			if (rc < 0) {
86 				return rc;
87 			}
88 		}
89 
90 		if (config->operation_mode == VCNL36825T_OPERATION_MODE_AUTO) {
91 			rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF3,
92 					       VCNL36825T_PS_AF_MSK, VCNL36825T_PS_AF_AUTO);
93 			if (rc < 0) {
94 				return rc;
95 			}
96 		}
97 
98 		k_usleep(VCNL36825T_POWER_UP_US);
99 
100 		rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF2, VCNL36825T_PS_ST_MSK,
101 				       VCNL36825T_PS_ST_START);
102 		if (rc < 0) {
103 			return rc;
104 		}
105 
106 		data->meas_timeout_us = data->meas_timeout_wakeup_us;
107 
108 		break;
109 	case PM_DEVICE_ACTION_SUSPEND:
110 		rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF2, VCNL36825T_PS_ST_MSK,
111 				       VCNL36825T_PS_ST_STOP);
112 		if (rc < 0) {
113 			return rc;
114 		}
115 
116 		if (config->operation_mode == VCNL36825T_OPERATION_MODE_AUTO) {
117 			rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF3,
118 					       VCNL36825T_PS_AF_MSK, VCNL36825T_PS_AF_FORCE);
119 			if (rc < 0) {
120 				return rc;
121 			}
122 		}
123 
124 		/* unset LPEN-bit if active, otherwise high current draw can be observed */
125 		if (config->low_power) {
126 			rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF4,
127 					       VCNL36825T_PS_LPEN_MSK, VCNL36825T_PS_LPEN_DISABLED);
128 			if (rc < 0) {
129 				return rc;
130 			}
131 		}
132 
133 		rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF1, VCNL36825T_PS_ON_MSK,
134 				       VCNL36825T_PS_OFF);
135 		if (rc < 0) {
136 			return rc;
137 		}
138 		break;
139 	default:
140 		LOG_ERR("action %d not supported", (int)action);
141 		return -ENOTSUP;
142 	}
143 
144 	return 0;
145 }
146 
147 #endif
148 
vcnl36825t_sample_fetch(const struct device * dev,enum sensor_channel chan)149 static int vcnl36825t_sample_fetch(const struct device *dev, enum sensor_channel chan)
150 {
151 	const struct vcnl36825t_config *config = dev->config;
152 	struct vcnl36825t_data *data = dev->data;
153 	int rc;
154 
155 #if CONFIG_PM_DEVICE
156 	enum pm_device_state state;
157 
158 	(void)pm_device_state_get(dev, &state);
159 	if (state != PM_DEVICE_STATE_ACTIVE) {
160 		return -EBUSY;
161 	}
162 #endif
163 
164 	switch (chan) {
165 	case SENSOR_CHAN_ALL:
166 	case SENSOR_CHAN_PROX:
167 		if (config->operation_mode == VCNL36825T_OPERATION_MODE_FORCE) {
168 			rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF3,
169 					       VCNL36825T_PS_TRIG_MSK, VCNL36825T_PS_TRIG_ONCE);
170 			if (rc < 0) {
171 				LOG_ERR("could not trigger proximity measurement %d", rc);
172 				return rc;
173 			}
174 
175 			k_usleep(data->meas_timeout_us);
176 
177 #ifdef CONFIG_PM_DEVICE
178 			data->meas_timeout_us = data->meas_timeout_running_us;
179 #endif
180 		}
181 
182 		rc = vcnl36825t_read(&config->i2c, VCNL36825T_REG_PS_DATA, &data->proximity);
183 		if (rc < 0) {
184 			LOG_ERR("could not fetch proximity measurement %d", rc);
185 			return rc;
186 		}
187 
188 		break;
189 	default:
190 		LOG_ERR("invalid sensor channel");
191 		return -EINVAL;
192 	}
193 
194 	return 0;
195 }
196 
vcnl36825t_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)197 static int vcnl36825t_channel_get(const struct device *dev, enum sensor_channel chan,
198 				  struct sensor_value *val)
199 {
200 	struct vcnl36825t_data *data = dev->data;
201 
202 	switch (chan) {
203 	case SENSOR_CHAN_ALL:
204 	case SENSOR_CHAN_PROX:
205 		val->val1 = data->proximity & VCNL36825T_OS_DATA_MSK;
206 		val->val2 = 0;
207 		break;
208 	default:
209 		return -ENOTSUP;
210 	}
211 
212 	return 0;
213 }
214 
vcnl36825t_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)215 static int vcnl36825t_attr_set(const struct device *dev, enum sensor_channel chan,
216 			       enum sensor_attribute attr, const struct sensor_value *val)
217 {
218 	CHECKIF(dev == NULL) {
219 		LOG_ERR("dev: NULL");
220 		return -EINVAL;
221 	}
222 
223 	CHECKIF(val == NULL) {
224 		LOG_ERR("val: NULL");
225 		return -EINVAL;
226 	}
227 
228 	int __maybe_unused rc;
229 
230 	switch (attr) {
231 	default:
232 #if CONFIG_VCNL36825T_TRIGGER
233 		rc = vcnl36825t_trigger_attr_set(dev, chan, attr, val);
234 		if (rc < 0) {
235 			return rc;
236 		}
237 #else
238 		return -ENOTSUP;
239 #endif
240 	}
241 
242 	return 0;
243 }
244 
245 /**
246  * @brief calculate measurement timeout in us
247  *
248  * @param meas_duration base duration of a measurement in us*VCNL36825T_FORCED_FACTOR_SCALE
249  * @param meas_factor factor which needs to be multiplied to cope with additional delays (multiplied
250  *                    by VCNL36825T_FORCED_FACTOR_SCALE)
251  *
252  * @note
253  *  Always add 1 to prevent corner case losses due to precision.
254  */
vcn36825t_measurement_timeout_us(unsigned int meas_duration,unsigned int forced_factor)255 static inline unsigned int vcn36825t_measurement_timeout_us(unsigned int meas_duration,
256 							    unsigned int forced_factor)
257 {
258 	return ((meas_duration * forced_factor) / VCNL36825T_FORCED_FACTOR_SCALE) + 1;
259 }
260 
261 /**
262  * @brief helper function to configure the registers
263  *
264  * @param dev pointer to the VCNL36825T instance
265  */
vcnl36825t_init_registers(const struct device * dev)266 static int vcnl36825t_init_registers(const struct device *dev)
267 {
268 	const struct vcnl36825t_config *config = dev->config;
269 	struct vcnl36825t_data *data = dev->data;
270 
271 	int rc;
272 	uint16_t reg_value;
273 
274 	unsigned int meas_duration = 1;
275 
276 	/* reset registers as defined by the datasheet */
277 	const uint16_t resetValues[][2] = {
278 		{VCNL36825T_REG_PS_CONF1, VCNL36825T_CONF1_DEFAULT},
279 		{VCNL36825T_REG_PS_CONF2, VCNL36825T_CONF2_DEFAULT},
280 		{VCNL36825T_REG_PS_CONF3, VCNL36825T_CONF3_DEFAULT},
281 		{VCNL36825T_REG_PS_THDL, VCNL36825T_THDL_DEFAULT},
282 		{VCNL36825T_REG_PS_THDH, VCNL36825T_THDH_DEFAULT},
283 		{VCNL36825T_REG_PS_CANC, VCNL36825T_CANC_DEFAULT},
284 		{VCNL36825T_REG_PS_CONF4, VCNL36825T_CONF4_DEFAULT},
285 	};
286 
287 	for (size_t i = 0; i < ARRAY_SIZE(resetValues); ++i) {
288 		vcnl36825t_write(&config->i2c, resetValues[i][0], resetValues[i][1]);
289 	}
290 
291 	/* PS_CONF1 */
292 	reg_value = 0x01; /* must be set according to datasheet */
293 	reg_value |= VCNL36825T_PS_ON;
294 
295 	rc = vcnl36825t_write(&config->i2c, VCNL36825T_REG_PS_CONF1, reg_value);
296 	if (rc < 0) {
297 		LOG_ERR("I2C for PS_ON returned %d", rc);
298 		return -EIO;
299 	}
300 
301 	reg_value |= VCNL36825T_PS_CAL;
302 	reg_value |= 1 << 9; /* reserved, must be set by datasheet */
303 
304 	rc = vcnl36825t_write(&config->i2c, VCNL36825T_REG_PS_CONF1, reg_value);
305 	if (rc < 0) {
306 		LOG_ERR("I2C for PS_CAL returned %d", rc);
307 	}
308 
309 	k_usleep(VCNL36825T_POWER_UP_US);
310 
311 	/* PS_CONF2 */
312 	reg_value = 0;
313 
314 	switch (config->period) {
315 	case VCNL36825T_MEAS_PERIOD_10MS:
316 		reg_value |= VCNL36825T_PS_PERIOD_10MS;
317 		break;
318 	case VCNL36825T_MEAS_PERIOD_20MS:
319 		reg_value |= VCNL36825T_PS_PERIOD_20MS;
320 		break;
321 	case VCNL36825T_MEAS_PERIOD_40MS:
322 		reg_value |= VCNL36825T_PS_PERIOD_40MS;
323 		break;
324 	case VCNL36825T_MEAS_PERIOD_80MS:
325 		__fallthrough;
326 	default:
327 		reg_value |= VCNL36825T_PS_PERIOD_80MS;
328 		break;
329 	}
330 
331 	reg_value |= VCNL36825T_PS_PERS_1;
332 	reg_value |= VCNL36825T_PS_ST_STOP;
333 
334 	switch (config->proximity_it) {
335 	case VCNL36825T_PROXIMITY_INTEGRATION_1T:
336 		reg_value |= VCNL36825T_PS_IT_1T;
337 		meas_duration *= 1;
338 		break;
339 	case VCNL36825T_PROXIMITY_INTEGRATION_2T:
340 		reg_value |= VCNL36825T_PS_IT_2T;
341 		meas_duration *= 2;
342 		break;
343 	case VCNL36825T_PROXIMITY_INTEGRATION_4T:
344 		reg_value |= VCNL36825T_PS_IT_4T;
345 		meas_duration *= 4;
346 		break;
347 	case VCNL36825T_PROXIMITY_INTEGRATION_8T:
348 		__fallthrough;
349 	default:
350 		reg_value |= VCNL36825T_PS_IT_8T;
351 		meas_duration *= 8;
352 		break;
353 	}
354 
355 	switch (config->multi_pulse) {
356 	case VCNL38652T_MULTI_PULSE_1:
357 		reg_value |= VCNL36825T_MPS_PULSES_1;
358 		break;
359 	case VCNL38652T_MULTI_PULSE_2:
360 		reg_value |= VCNL36825T_MPS_PULSES_2;
361 		break;
362 	case VCNL38652T_MULTI_PULSE_4:
363 		reg_value |= VCNL36825T_MPS_PULSES_4;
364 		break;
365 	case VCNL38652T_MULTI_PULSE_8:
366 		__fallthrough;
367 	default:
368 		reg_value |= VCNL36825T_MPS_PULSES_8;
369 		break;
370 	}
371 
372 	switch (config->proximity_itb) {
373 	case VCNL36825T_PROXIMITY_INTEGRATION_DURATION_25us:
374 		reg_value |= VCNL36825T_PS_ITB_25us;
375 		meas_duration *= 25;
376 		break;
377 	case VCNL36825T_PROXIMITY_INTEGRATION_DURATION_50us:
378 		__fallthrough;
379 	default:
380 		reg_value |= VCNL36825T_PS_ITB_50us;
381 		meas_duration *= 50;
382 		break;
383 	}
384 
385 	if (config->high_gain) {
386 		reg_value |= VCNL36825T_PS_HG_HIGH;
387 	}
388 
389 	rc = vcnl36825t_write(&config->i2c, VCNL36825T_REG_PS_CONF2, reg_value);
390 	if (rc < 0) {
391 		LOG_ERR("I2C for setting PS_CONF2 returned %d", rc);
392 		return -EIO;
393 	}
394 
395 	/* PS_CONF3 */
396 	reg_value = 0;
397 
398 	if (config->operation_mode == VCNL36825T_OPERATION_MODE_FORCE) {
399 		reg_value |= VCNL36825T_PS_AF_FORCE;
400 	}
401 
402 	switch (config->laser_current) {
403 	case VCNL36825T_LASER_CURRENT_10MS:
404 		reg_value |= VCNL36825T_PS_I_VCSEL_10MA;
405 		break;
406 	case VCNL36825T_LASER_CURRENT_12MS:
407 		reg_value |= VCNL36825T_PS_I_VCSEL_12MA;
408 		break;
409 	case VCNL36825T_LASER_CURRENT_14MS:
410 		reg_value |= VCNL36825T_PS_I_VCSEL_14MA;
411 		break;
412 	case VCNL36825T_LASER_CURRENT_16MS:
413 		reg_value |= VCNL36825T_PS_I_VCSEL_16MA;
414 		break;
415 	case VCNL36825T_LASER_CURRENT_18MS:
416 		reg_value |= VCNL36825T_PS_I_VCSEL_18MA;
417 		break;
418 	case VCNL36825T_LASER_CURRENT_20MS:
419 		__fallthrough;
420 	default:
421 		reg_value |= VCNL36825T_PS_I_VCSEL_20MA;
422 		break;
423 	}
424 
425 	if (config->high_dynamic_output) {
426 		reg_value |= VCNL36825T_PS_HD_16BIT;
427 	}
428 
429 	if (config->sunlight_cancellation) {
430 		reg_value |= VCNL36825T_PS_SC_ENABLED;
431 	}
432 
433 	rc = vcnl36825t_write(&config->i2c, VCNL36825T_REG_PS_CONF3, reg_value);
434 	if (rc < 0) {
435 		LOG_ERR("I2C for setting PS_CONF3 returned %d", rc);
436 		return -EIO;
437 	}
438 
439 	/* PS_CONF4 */
440 	reg_value = 0;
441 
442 	if (config->low_power) {
443 		reg_value |= VCNL36825T_PS_LPEN_ENABLED;
444 	}
445 
446 	switch (config->period) {
447 	case VCNL36825T_MEAS_PERIOD_40MS:
448 		reg_value |= VCNL36825T_PS_LPPER_40MS;
449 		break;
450 	case VCNL36825T_MEAS_PERIOD_80MS:
451 		reg_value |= VCNL36825T_PS_LPPER_80MS;
452 		break;
453 	case VCNL36825T_MEAS_PERIOD_160MS:
454 		reg_value |= VCNL36825T_PS_LPPER_160MS;
455 		break;
456 	case VCNL36825T_MEAS_PERIOD_320MS:
457 		__fallthrough;
458 	default:
459 		reg_value |= VCNL36825T_PS_LPPER_320MS;
460 		break;
461 	}
462 
463 	rc = vcnl36825t_write(&config->i2c, VCNL36825T_REG_PS_CONF4, reg_value);
464 	if (rc < 0) {
465 		LOG_ERR("I2C for setting PS_CONF4 returned %d", rc);
466 		return -EIO;
467 	}
468 
469 	data->meas_timeout_us =
470 		vcn36825t_measurement_timeout_us(meas_duration, VCNL36825T_FORCED_FACTOR_SUM);
471 
472 #ifdef CONFIG_PM_DEVICE
473 	data->meas_timeout_running_us = data->meas_timeout_us;
474 	data->meas_timeout_wakeup_us = vcn36825t_measurement_timeout_us(
475 		meas_duration, VCNL36825T_FORCED_FACTOR_WAKEUP_SUM);
476 
477 	/* ensure that the time is roughly around VCNL36825T_FORCED_WAKEUP_DELAY_MAX_US if the
478 	 * wakeup time is bigger but "normal" measurement time is less
479 	 */
480 	if (data->meas_timeout_wakeup_us > VCNL36825T_FORCED_WAKEUP_DELAY_MAX_US) {
481 		data->meas_timeout_wakeup_us =
482 			MAX(data->meas_timeout_running_us, VCNL36825T_FORCED_WAKEUP_DELAY_MAX_US);
483 	}
484 #endif
485 
486 	return 0;
487 }
488 
vcnl36825t_init(const struct device * dev)489 static int vcnl36825t_init(const struct device *dev)
490 {
491 	const struct vcnl36825t_config *config = dev->config;
492 	int rc;
493 
494 	uint16_t reg_value;
495 
496 	if (!i2c_is_ready_dt(&config->i2c)) {
497 		LOG_ERR("device is not ready");
498 		return -ENODEV;
499 	}
500 
501 	rc = vcnl36825t_read(&config->i2c, VCNL36825T_REG_DEV_ID, &reg_value);
502 	if (rc < 0) {
503 		LOG_ERR("could not read device id");
504 		return rc;
505 	}
506 
507 	if ((reg_value & VCNL36825T_ID_MSK) != VCNL36825T_DEVICE_ID) {
508 		LOG_ERR("incorrect device id (%d)", reg_value);
509 		return -EIO;
510 	}
511 
512 	LOG_INF("version code: 0x%X",
513 		(unsigned int)FIELD_GET(VCNL36825T_VERSION_CODE_MSK, reg_value));
514 
515 	rc = vcnl36825t_init_registers(dev);
516 	if (rc < 0) {
517 		return rc;
518 	}
519 
520 #if CONFIG_VCNL36825T_TRIGGER
521 	rc = vcnl36825t_trigger_init(dev);
522 	if (rc < 0) {
523 		return rc;
524 	}
525 #endif
526 	rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF2, VCNL36825T_PS_ST_MSK,
527 			       VCNL36825T_PS_ST_START);
528 	if (rc < 0) {
529 		LOG_ERR("error starting measurement");
530 		return -EIO;
531 	}
532 
533 	return 0;
534 }
535 
536 static DEVICE_API(sensor, vcnl36825t_driver_api) = {
537 	.sample_fetch = vcnl36825t_sample_fetch,
538 	.channel_get = vcnl36825t_channel_get,
539 	.attr_set = vcnl36825t_attr_set,
540 #if CONFIG_VCNL36825T_TRIGGER
541 	.trigger_set = vcnl36825t_trigger_set,
542 #endif
543 };
544 
545 #define VCNL36825T_DEFINE(inst)                                                                    \
546 	BUILD_ASSERT(!DT_INST_PROP(inst, low_power) || (DT_INST_PROP(inst, measurement_period) >=  \
547 							VCNL36825T_PS_LPPER_VALUE_MIN_MS),         \
548 		     "measurement-period must be greater/equal 40 ms in low-power mode");          \
549 	BUILD_ASSERT(                                                                              \
550 		DT_INST_PROP(inst, low_power) || (DT_INST_PROP(inst, measurement_period) <=        \
551 						  VCNL36825T_PS_PERIOD_VALUE_MAX_MS),              \
552 		"measurement-period must be less/equal 80 ms with deactivated low-power mode");    \
553 	BUILD_ASSERT(!DT_INST_PROP(inst, low_power) || (DT_INST_ENUM_IDX(inst, operation_mode) ==  \
554 							VCNL36825T_OPERATION_MODE_AUTO),           \
555 		     "operation-mode \"force\" only available if low-power mode deactivated");     \
556 	static struct vcnl36825t_data vcnl36825t_data_##inst;                                      \
557 	static const struct vcnl36825t_config vcnl36825t_config_##inst = {                         \
558 		.i2c = I2C_DT_SPEC_INST_GET(inst),                                                 \
559 		.operation_mode = DT_INST_ENUM_IDX(inst, operation_mode),                          \
560 		.period = DT_INST_ENUM_IDX(inst, measurement_period),                              \
561 		.proximity_it = DT_INST_ENUM_IDX(inst, proximity_it),                              \
562 		.proximity_itb = DT_INST_ENUM_IDX(inst, proximity_itb),                            \
563 		.multi_pulse = DT_INST_ENUM_IDX(inst, multi_pulse),                                \
564 		.low_power = DT_INST_PROP(inst, low_power),                                        \
565 		.high_gain = DT_INST_PROP(inst, high_gain),                                        \
566 		.laser_current = DT_INST_ENUM_IDX(inst, laser_current),                            \
567 		.high_dynamic_output = DT_INST_PROP(inst, high_dynamic_output),                    \
568 		.sunlight_cancellation = DT_INST_PROP(inst, sunlight_cancellation),                \
569 		IF_ENABLED(CONFIG_VCNL36825T_TRIGGER,                                              \
570 			   (.int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),                    \
571 			    .int_mode = DT_INST_ENUM_IDX(inst, int_mode),                          \
572 			    .int_proximity_count = DT_INST_PROP(inst, int_proximity_count),        \
573 			    .int_smart_persistence = DT_INST_PROP(inst, int_smart_persistence)))}; \
574 	IF_ENABLED(CONFIG_PM_DEVICE, (PM_DEVICE_DT_INST_DEFINE(inst, vcnl36825t_pm_action)));      \
575 	SENSOR_DEVICE_DT_INST_DEFINE(                                                              \
576 		inst, vcnl36825t_init,                                                             \
577 		COND_CODE_1(CONFIG_PM_DEVICE, (PM_DEVICE_DT_INST_GET(inst)), (NULL)),              \
578 		&vcnl36825t_data_##inst, &vcnl36825t_config_##inst, POST_KERNEL,                   \
579 		CONFIG_SENSOR_INIT_PRIORITY, &vcnl36825t_driver_api);
580 
581 DT_INST_FOREACH_STATUS_OKAY(VCNL36825T_DEFINE)
582