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