1 /*
2  * Copyright (c) 2024 Juliane Schulze, deveritec GmbH
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_DRIVERS_SENSOR_VCNL36825T_VCNL36825T_H_
8 #define ZEPHYR_DRIVERS_SENSOR_VCNL36825T_VCNL36825T_H_
9 
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <zephyr/drivers/sensor.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/sys/util.h>
15 
16 #define VCNL36825T_REG_PS_CONF1		0x00
17 #define VCNL36825T_REG_PS_CONF2		0x03
18 #define VCNL36825T_REG_PS_CONF3		0x04
19 #define VCNL36825T_REG_PS_THDL		0x05
20 #define VCNL36825T_REG_PS_THDH		0x06
21 #define VCNL36825T_REG_PS_CANC		0x07
22 #define VCNL36825T_REG_PS_CONF4		0x08
23 #define VCNL36825T_REG_PS_DATA		0xF8
24 #define VCNL36825T_REG_INT_FLAG		0xF9
25 #define VCNL36825T_REG_DEV_ID		0xFA
26 #define VCNL36825T_REG_PS_AC_DATA	0xFB
27 
28 /* default values */
29 #define VCNL36825T_CONF1_DEFAULT	0x0001
30 #define VCNL36825T_CONF2_DEFAULT	0x0000
31 #define VCNL36825T_CONF3_DEFAULT	0x0000
32 #define VCNL36825T_THDL_DEFAULT		0x0000
33 #define VCNL36825T_THDH_DEFAULT		0x0000
34 #define VCNL36825T_CANC_DEFAULT		0x0000
35 #define VCNL36825T_CONF4_DEFAULT	0x0000
36 
37 /* PS_CONF1 */
38 #define VCNL36825T_PS_ON_POS	1
39 #define VCNL36825T_PS_CAL_POS	7
40 
41 #define VCNL36825T_PS_ON_MSK	GENMASK(1, 1)
42 
43 #define VCNL36825T_PS_ON	(1 << VCNL36825T_PS_ON_POS)
44 #define VCNL36825T_PS_OFF	(0 << VCNL36825T_PS_ON_POS)
45 
46 #define VCNL36825T_PS_CAL	(1 << VCNL36825T_PS_CAL_POS)
47 
48 /* PS_CONF2 */
49 #define VCNL36825T_PS_ST_POS		0
50 #define VCNL36825T_PS_PS_SMART_PERS_POS	1
51 #define VCNL36825T_PS_INT_POS		2
52 #define VCNL36825T_PS_PERS_POS		4
53 #define VCNL36825T_PS_PERIOD_POS	6
54 #define VCNL36825T_PS_HG_POS		10
55 #define VCNL36825T_PS_ITB_POS		11
56 #define VCNL36825T_PS_MPS_POS		12
57 #define VCNL36825T_PS_IT_POS		14
58 
59 #define VCNL36825T_PS_ST_MSK		GENMASK(0, 0)
60 #define VCNL36825T_PS_SMART_PERS_MSK	GENMASK(1, 1)
61 #define VCNL36825T_PS_INT_MSK		GENMASK(3, 2)
62 #define VCNL36825T_PS_PERS_MSK		GENMASK(5, 4)
63 
64 #define VCNL36825T_PS_ST_START	(0 << VCNL36825T_PS_ST_POS)
65 #define VCNL36825T_PS_ST_STOP	(1 << VCNL36825T_PS_ST_POS)
66 
67 #define VCNL36825T_PS_SMART_PERS_DISABLED	(0 << VCNL36825T_PS_PS_SMART_PERS_POS)
68 #define VCNL36825T_PS_SMART_PERS_ENABLED	(1 << VCNL36825T_PS_PS_SMART_PERS_POS)
69 
70 #define VCNL36825T_PS_INT_DISABLE		(0 << VCNL36825T_PS_INT_POS)
71 #define VCNL36825T_PS_INT_MODE_LOGIC_HIGH_LOW	(1 << VCNL36825T_PS_INT_POS)
72 #define VCNL36825T_PS_INT_MODE_FIRST_HIGH	(2 << VCNL36825T_PS_INT_POS)
73 #define VCNL36825T_PS_INT_MODE_NORMAL		(3 << VCNL36825T_PS_INT_POS)
74 
75 #define VCNL36825T_PS_PERS_1	(0 << VCNL36825T_PS_PERS_POS)
76 #define VCNL36825T_PS_PERS_2	(1 << VCNL36825T_PS_PERS_POS)
77 #define VCNL36825T_PS_PERS_3	(2 << VCNL36825T_PS_PERS_POS)
78 #define VCNL36825T_PS_PERS_4	(3 << VCNL36825T_PS_PERS_POS)
79 
80 #define VCNL36825T_PS_PERIOD_10MS	(0 << VCNL36825T_PS_PERIOD_POS)
81 #define VCNL36825T_PS_PERIOD_20MS	(1 << VCNL36825T_PS_PERIOD_POS)
82 #define VCNL36825T_PS_PERIOD_40MS	(2 << VCNL36825T_PS_PERIOD_POS)
83 #define VCNL36825T_PS_PERIOD_80MS	(3 << VCNL36825T_PS_PERIOD_POS)
84 
85 #define VCNL36825T_PS_HG_LOW	(0 << VCNL36825T_PS_HG_POS)
86 #define VCNL36825T_PS_HG_HIGH	(1 << VCNL36825T_PS_HG_POS)
87 
88 #define VCNL36825T_PS_ITB_25us	(0 << VCNL36825T_PS_ITB_POS)
89 #define VCNL36825T_PS_ITB_50us	(1 << VCNL36825T_PS_ITB_POS)
90 
91 #define VCNL36825T_MPS_PULSES_1	(0 << VCNL36825T_PS_MPS_POS)
92 #define VCNL36825T_MPS_PULSES_2	(1 << VCNL36825T_PS_MPS_POS)
93 #define VCNL36825T_MPS_PULSES_4	(2 << VCNL36825T_PS_MPS_POS)
94 #define VCNL36825T_MPS_PULSES_8	(4 << VCNL36825T_PS_MPS_POS)
95 
96 #define VCNL36825T_PS_IT_1T	(0 << VCNL36825T_PS_IT_POS)
97 #define VCNL36825T_PS_IT_2T	(1 << VCNL36825T_PS_IT_POS)
98 #define VCNL36825T_PS_IT_4T	(2 << VCNL36825T_PS_IT_POS)
99 #define VCNL36825T_PS_IT_8T	(3 << VCNL36825T_PS_IT_POS)
100 
101 /* PS_CONF3 */
102 #define VCNL36825T_PS_SP_INT_POS	2
103 #define VCNL36825T_PS_FORCENUM_POS	4
104 #define VCNL36825T_PS_TRIG_POS		5
105 #define VCNL36825T_PS_AF_POS		6
106 #define VCNL36825T_PS_I_VCSEL_POS	8
107 #define VCNL36825T_PS_HD_POS		12
108 #define VCNL36825T_PS_SC_POS		13
109 
110 #define VCNL36825T_PS_TRIG_MSK	GENMASK(5, 5)
111 #define VCNL36825T_PS_AF_MSK	GENMASK(6, 6)
112 
113 #define VCNL36825T_PS_SP_INT_DISABLED	(0 << VCNL36825T_PS_SP_INT_POS)
114 #define VCNL36825T_PS_SP_INT_ENABLED	(1 << VCNL36825T_PS_SP_INT_POS)
115 
116 #define VCNL36825T_PS_FORCENUM_ONE_CYCLE	(0 << VCNL36825T_PS_FORCENUM_POS)
117 #define VCNL36825T_PS_FORCENUM_TWO_CYCLES	(1 << VCNL36825T_PS_FORCENUM_POS)
118 
119 #define VCNL36825T_PS_TRIG_NONE	(0 << VCNL36825T_PS_TRIG_POS)
120 #define VCNL36825T_PS_TRIG_ONCE	(1 << VCNL36825T_PS_TRIG_POS)
121 
122 #define VCNL36825T_PS_AF_AUTO	(0 << VCNL36825T_PS_AF_POS)
123 #define VCNL36825T_PS_AF_FORCE	(1 << VCNL36825T_PS_AF_POS)
124 
125 #define VCNL36825T_PS_I_VCSEL_10MA	(2 << VCNL36825T_PS_I_VCSEL_POS)
126 #define VCNL36825T_PS_I_VCSEL_12MA	(3 << VCNL36825T_PS_I_VCSEL_POS)
127 #define VCNL36825T_PS_I_VCSEL_14MA	(4 << VCNL36825T_PS_I_VCSEL_POS)
128 #define VCNL36825T_PS_I_VCSEL_16MA	(5 << VCNL36825T_PS_I_VCSEL_POS)
129 #define VCNL36825T_PS_I_VCSEL_18MA	(6 << VCNL36825T_PS_I_VCSEL_POS)
130 #define VCNL36825T_PS_I_VCSEL_20MA	(7 << VCNL36825T_PS_I_VCSEL_POS)
131 
132 #define VCNL36825T_PS_HD_12BIT	(0 << VCNL36825T_PS_HD_POS)
133 #define VCNL36825T_PS_HD_16BIT	(1 << VCNL36825T_PS_HD_POS)
134 
135 #define VCNL36825T_PS_SC_DISABLED	(0 << VCNL36825T_PS_SC_POS)
136 #define VCNL36825T_PS_SC_ENABLED	(7 << VCNL36825T_PS_SC_POS)
137 
138 /* PS CONF4 */
139 #define VCNL36825T_PS_AC_INT_POS	0
140 #define VCNL36825T_PS_AC_TRIG_POS	2
141 #define VCNL36825T_PS_AC_POS		3
142 #define VCNL36825T_PS_AC_NUM_POS	4
143 #define VCNL36825T_PS_AC_PERIOD_POS	6
144 #define VCNL36825T_PS_LPEN_POS		8
145 #define VCNL36825T_PS_LPPER_POS		9
146 
147 #define VCNL36825T_PS_LPEN_MSK	GENMASK(8, 8)
148 
149 #define VCNL36825T_PS_AC_INT_DISABLED	(0 << VCNL36825T_PS_AC_INT_POS)
150 #define VCNL36825T_PS_AC_INT_ENABLED	(1 << VCNL36825T_PS_AC_INT_POS)
151 
152 #define VCNL36825T_PS_AC_TRIG_DISABLED	(0 << VCNL36825T_PS_AC_TRIG_POS)
153 #define VCNL36825T_PS_AC_TRIG_ONCE	(1 << VCNL36825T_PS_AC_TRIG_POS)
154 
155 #define VCNL36825T_PS_AC_DISABLED	(0 << VCNL36825T_PS_AC_POS)
156 #define VCNL36825T_PS_AC_ENABLED	(1 << VCNL36825T_PS_AC_POS)
157 
158 #define VCNL36825T_PS_AC_NUM_1	(0 << VCNL36825T_PS_AC_NUM_POS)
159 #define VCNL36825T_PS_AC_NUM_2	(1 << VCNL36825T_PS_AC_NUM_POS)
160 #define VCNL36825T_PS_AC_NUM_4	(2 << VCNL36825T_PS_AC_NUM_POS)
161 #define VCNL36825T_PS_AC_NUM_8	(3 << VCNL36825T_PS_AC_NUM_POS)
162 
163 #define VCNL36825T_PS_AC_PERIOD_3MS	(0 << VCNL36825T_PS_AC_PERIOD_POS)
164 #define VCNL36825T_PS_AC_PERIOD_6MS	(1 << VCNL36825T_PS_AC_PERIOD_POS)
165 #define VCNL36825T_PS_AC_PERIOD_12MS	(2 << VCNL36825T_PS_AC_PERIOD_POS)
166 #define VCNL36825T_PS_AC_PERIOD_24MS	(3 << VCNL36825T_PS_AC_PERIOD_POS)
167 
168 #define VCNL36825T_PS_LPEN_DISABLED	(0 << VCNL36825T_PS_LPEN_POS)
169 #define VCNL36825T_PS_LPEN_ENABLED	(1 << VCNL36825T_PS_LPEN_POS)
170 
171 #define VCNL36825T_PS_LPPER_40MS	(0 << VCNL36825T_PS_LPPER_POS)
172 #define VCNL36825T_PS_LPPER_80MS	(1 << VCNL36825T_PS_LPPER_POS)
173 #define VCNL36825T_PS_LPPER_160MS	(2 << VCNL36825T_PS_LPPER_POS)
174 #define VCNL36825T_PS_LPPER_320MS	(3 << VCNL36825T_PS_LPPER_POS)
175 
176 /* PS_DATA */
177 #define VCNL36825T_PS_DATA_L_POS	0
178 #define VCNL36825T_PS_DATA_H_POS	8
179 
180 #define VCNL36825T_PS_DATA_L_MSK	GENMASK(7, 0)
181 #define VCNL36825T_PS_DATA_H_MSK	GENMASK(11, 8)
182 #define VCNL36825T_OS_DATA_MSK		(VCNL36825T_PS_DATA_L_MSK | VCNL36825T_PS_DATA_H_MSK)
183 
184 /* INT_FLAG */
185 #define VCNL36825T_PS_IF_AWAY_POS	8
186 #define VCNL36825T_PS_IF_CLOSE_POS	9
187 #define VCNL36825T_PS_SPFLAG_POS	12
188 #define VCNL36825T_PS_ACFLAG_POS	13
189 
190 #define VCNL36825T_PS_IF_AWAY_MSK	GENMASK(8, 8)
191 #define VCNL36825T_PS_IF_CLOSE_MSK	GENMASK(9, 9)
192 #define VCNL36825T_PS_SPFLAG_MSK	GENMASK(12, 12)
193 #define VCNL36825T_PS_ACFLAG_MSK	GENMASK(13, 13)
194 
195 /* ID */
196 #define VCNL36825T_ID_POS		0
197 #define VCNL36825T_VERSION_CODE_POS	8
198 
199 #define VCNL36825T_ID_MSK		GENMASK(7, 0)
200 #define VCNL36825T_VERSION_CODE_MSK	GENMASK(11, 8)
201 
202 #define VCNL36825T_DEVICE_ID	0b00100110
203 
204 /* PS_AC_DATA */
205 #define VCNL36825T_AC_DATA_L_POS	0
206 #define VCNL36825T_AC_DATA_H_POS	8
207 #define VCNL36825T_AC_SUN_POS		14
208 #define VCNL36825T_AC_BUSY_POS		15
209 
210 #define VCNL36825T_AC_DATA_L_MSK	GENMASK(7, 0)
211 #define VCNL36825T_AC_DATA_H_MSK	GENMASK(11, 8)
212 #define VCNL36825T_AC_SUN_MSK		GENMASK(14, 14)
213 #define VCNL36825T_AC_BUSY_MSK		GENMASK(15, 15)
214 
215 #define VCNL36825T_PS_PERIOD_VALUE_MAX_MS	80
216 #define VCNL36825T_PS_LPPER_VALUE_MIN_MS	40
217 
218 /* see application note "Designing the VCNL36825T Into an Application": power up takes 2500 us */
219 #define VCNL36825T_POWER_UP_US	2500
220 
221 #define VCNL36825T_FORCED_FACTOR_TIME_TO_TRIGGER	0.5
222 #define VCNL36825T_FORCED_FACTOR_DC_KILL_AMBIENT	3
223 #define VCNL36825T_FORCED_FACTOR_MEASUREMENT		1
224 #define VCNL36825T_FORCED_FACTOR_SHUTDOWN		1
225 #define VCNL36825T_FORCED_FACTOR_SCALE			10
226 
227 /* necessary time to wait before data of a "forced" measurement is available */
228 #define VCNL36825T_FORCED_FACTOR_SUM                                                               \
229 	((VCNL36825T_FORCED_FACTOR_TIME_TO_TRIGGER + VCNL36825T_FORCED_FACTOR_DC_KILL_AMBIENT +    \
230 	  VCNL36825T_FORCED_FACTOR_MEASUREMENT + VCNL36825T_FORCED_FACTOR_SHUTDOWN) *              \
231 	 VCNL36825T_FORCED_FACTOR_SCALE)
232 
233 #ifdef CONFIG_PM_DEVICE
234 
235 #define VCNL36825T_FORCED_WAKEUP_DELAY_MAX_US 1000
236 #define VCNL36825T_FORCED_FACTOR_WAKEUP_DELAY 10
237 
238 /* necessary wait time before data for a "forced" measurement is available AFTER the device slept */
239 #define VCNL36825T_FORCED_FACTOR_WAKEUP_SUM                                                        \
240 	(VCNL36825T_FORCED_FACTOR_SUM +                                                            \
241 	 (VCNL36825T_FORCED_FACTOR_WAKEUP_DELAY * VCNL36825T_FORCED_FACTOR_SCALE))
242 
243 #endif
244 
245 enum vcnl36825t_operation_mode {
246 	VCNL36825T_OPERATION_MODE_AUTO,
247 	VCNL36825T_OPERATION_MODE_FORCE,
248 };
249 
250 enum vcnl36825t_measurement_period {
251 	VCNL36825T_MEAS_PERIOD_10MS,
252 	VCNL36825T_MEAS_PERIOD_20MS,
253 	VCNL36825T_MEAS_PERIOD_40MS,
254 	VCNL36825T_MEAS_PERIOD_80MS,
255 	VCNL36825T_MEAS_PERIOD_160MS,
256 	VCNL36825T_MEAS_PERIOD_320MS,
257 };
258 
259 enum vcnl36825t_proximity_integration_time {
260 	VCNL36825T_PROXIMITY_INTEGRATION_1T,
261 	VCNL36825T_PROXIMITY_INTEGRATION_2T,
262 	VCNL36825T_PROXIMITY_INTEGRATION_4T,
263 	VCNL36825T_PROXIMITY_INTEGRATION_8T,
264 };
265 
266 enum vcnl36825t_proximity_integration_duration {
267 	VCNL36825T_PROXIMITY_INTEGRATION_DURATION_25us,
268 	VCNL36825T_PROXIMITY_INTEGRATION_DURATION_50us,
269 };
270 
271 enum vcnl36825t_multi_pulse {
272 	VCNL38652T_MULTI_PULSE_1,
273 	VCNL38652T_MULTI_PULSE_2,
274 	VCNL38652T_MULTI_PULSE_4,
275 	VCNL38652T_MULTI_PULSE_8,
276 };
277 
278 enum vcnl38625t_laser_current {
279 	VCNL36825T_LASER_CURRENT_10MS,
280 	VCNL36825T_LASER_CURRENT_12MS,
281 	VCNL36825T_LASER_CURRENT_14MS,
282 	VCNL36825T_LASER_CURRENT_16MS,
283 	VCNL36825T_LASER_CURRENT_18MS,
284 	VCNL36825T_LASER_CURRENT_20MS,
285 };
286 
287 enum vcnl36825t_int_mode {
288 	VCNL36825T_INT_MODE_NORMAL,
289 	VCNL36825T_INT_MODE_FIRST_HIGH,
290 	VCNL36825T_INT_MODE_LOGIC_HIGH_LOW,
291 };
292 
293 struct vcnl36825t_config {
294 	struct i2c_dt_spec i2c;
295 
296 	enum vcnl36825t_operation_mode operation_mode;
297 
298 	enum vcnl36825t_measurement_period period;
299 	enum vcnl36825t_proximity_integration_time proximity_it;
300 	enum vcnl36825t_proximity_integration_duration proximity_itb;
301 	enum vcnl36825t_multi_pulse multi_pulse;
302 
303 	bool low_power;
304 	bool high_gain;
305 
306 	enum vcnl38625t_laser_current laser_current;
307 	bool high_dynamic_output;
308 	bool sunlight_cancellation;
309 
310 #if CONFIG_VCNL36825T_TRIGGER
311 	struct gpio_dt_spec int_gpio;
312 	enum vcnl36825t_int_mode int_mode;
313 	uint8_t int_proximity_count;
314 	bool int_smart_persistence;
315 #endif
316 };
317 
318 struct vcnl36825t_data {
319 	uint16_t proximity;
320 
321 	unsigned int meas_timeout_us; /** wait time for finished measurement in "forced"-mode  */
322 
323 #ifdef CONFIG_PM_DEVICE
324 	unsigned int meas_timeout_running_us;
325 	unsigned int meas_timeout_wakeup_us;
326 #endif
327 
328 #if CONFIG_VCNL36825T_TRIGGER
329 	const struct device *dev;
330 	const struct gpio_dt_spec *int_gpio;
331 
332 	const struct sensor_trigger *int_trigger;
333 	sensor_trigger_handler_t int_handler;
334 
335 	struct gpio_callback int_gpio_handler;
336 
337 #if CONFIG_VCNL36825T_TRIGGER_OWN_THREAD
338 	K_KERNEL_STACK_MEMBER(int_thread_stack, CONFIG_VCNL36825T_THREAD_STACK_SIZE);
339 	struct k_thread int_thread;
340 	struct k_sem int_gpio_sem;
341 #elif CONFIG_VCNL36825T_TRIGGER_GLOBAL_THREAD
342 	struct k_work int_work;
343 #endif
344 #endif
345 };
346 
347 int vcnl36825t_read(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint16_t *value);
348 
349 int vcnl36825t_write(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint16_t value);
350 
351 int vcnl36825t_update(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint16_t mask,
352 		      uint16_t value);
353 
354 #if CONFIG_VCNL36825T_TRIGGER
355 int vcnl36825t_trigger_init(const struct device *dev);
356 
357 int vcnl36825t_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
358 			   sensor_trigger_handler_t handler);
359 
360 int vcnl36825t_trigger_attr_set(const struct device *dev, enum sensor_channel chan,
361 				enum sensor_attribute attr, const struct sensor_value *val);
362 
363 #endif
364 
365 #endif
366