Skip to content

Commit 7adcebc

Browse files
deveritec-juschenrikbrixandersen
authored andcommitted
vcnl36825t: add trigger capability
Adds trigger capability to the Vishay VCNL36825T sensor. Signed-off-by: Juliane Schulze <[email protected]>
1 parent a61484f commit 7adcebc

File tree

10 files changed

+513
-9
lines changed

10 files changed

+513
-9
lines changed

drivers/sensor/vishay/vcnl36825t/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
zephyr_library()
55

66
zephyr_library_sources(vcnl36825t.c)
7+
zephyr_library_sources_ifdef(CONFIG_VCNL36825T_TRIGGER vcnl36825t_trigger.c)

drivers/sensor/vishay/vcnl36825t/Kconfig

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,49 @@ config VCNL36825T
1010
select I2C
1111
help
1212
Enable driver for VCNL36825T sensors.
13+
14+
if VCNL36825T
15+
16+
config VCNL36825T_TRIGGER
17+
bool
18+
19+
choice VCNL36825T_TRIGGER_CHOICE
20+
prompt "trigger mode"
21+
default VCNL36825T_TRIGGER_NONE
22+
help
23+
Specify the type of triggering to be used by the driver.
24+
Note: Since figuring out which interrupt was triggered, using the Zephyr
25+
standard types will deactivate the other interrupt.
26+
27+
config VCNL36825T_TRIGGER_NONE
28+
bool "no trigger"
29+
30+
config VCNL36825T_TRIGGER_GLOBAL_THREAD
31+
bool "use global thread"
32+
select VCNL36825T_TRIGGER
33+
34+
config VCNL36825T_TRIGGER_OWN_THREAD
35+
bool "use own thread"
36+
select VCNL36825T_TRIGGER
37+
38+
endchoice
39+
40+
if VCNL36825T_TRIGGER
41+
42+
config VCNL36825T_THREAD_PRIORITY
43+
int "thread priority"
44+
depends on VCNL36825T_TRIGGER_OWN_THREAD
45+
default 10
46+
help
47+
Priority of thread used by the driver to handle interrupts.
48+
49+
config VCNL36825T_THREAD_STACK_SIZE
50+
int "thread stack size"
51+
depends on VCNL36825T_TRIGGER_OWN_THREAD
52+
default 1024
53+
help
54+
Stack size of thread used by the driver to handle interrupts.
55+
56+
endif # VCNL36825T_TRIGGER
57+
58+
endif # VCNL36825T

drivers/sensor/vishay/vcnl36825t/vcnl36825t.c

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@
1111
#include <stdlib.h>
1212

1313
#include <zephyr/drivers/i2c.h>
14+
#include <zephyr/drivers/sensor.h>
1415
#include <zephyr/logging/log.h>
1516
#include <zephyr/pm/device.h>
1617
#include <zephyr/sys/byteorder.h>
18+
#include <zephyr/sys/check.h>
1719
#include <zephyr/sys/util.h>
1820

1921
LOG_MODULE_REGISTER(VCNL36825T, CONFIG_SENSOR_LOG_LEVEL);
2022

21-
static int 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)
2224
{
2325
uint8_t rx_buf[2];
2426
int rc;
@@ -33,16 +35,16 @@ static int vcnl36825t_read(const struct i2c_dt_spec *spec, uint8_t reg_addr, uin
3335
return 0;
3436
}
3537

36-
static int 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)
3739
{
3840
uint8_t tx_buf[3] = {reg_addr};
3941

4042
sys_put_le16(value, &tx_buf[1]);
4143
return i2c_write_dt(spec, tx_buf, sizeof(tx_buf));
4244
}
4345

44-
static int vcnl36825t_update(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint16_t mask,
45-
uint16_t value)
46+
int vcnl36825t_update(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint16_t mask,
47+
uint16_t value)
4648
{
4749
int rc;
4850
uint16_t old_value, new_value;
@@ -210,6 +212,36 @@ static int vcnl36825t_channel_get(const struct device *dev, enum sensor_channel
210212
return 0;
211213
}
212214

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+
213245
/**
214246
* @brief calculate measurement timeout in us
215247
*
@@ -485,6 +517,12 @@ static int vcnl36825t_init(const struct device *dev)
485517
return rc;
486518
}
487519

520+
#if CONFIG_VCNL36825T_TRIGGER
521+
rc = vcnl36825t_trigger_init(dev);
522+
if (rc < 0) {
523+
return rc;
524+
}
525+
#endif
488526
rc = vcnl36825t_update(&config->i2c, VCNL36825T_REG_PS_CONF2, VCNL36825T_PS_ST_MSK,
489527
VCNL36825T_PS_ST_START);
490528
if (rc < 0) {
@@ -498,6 +536,10 @@ static int vcnl36825t_init(const struct device *dev)
498536
static const struct sensor_driver_api vcnl36825t_driver_api = {
499537
.sample_fetch = vcnl36825t_sample_fetch,
500538
.channel_get = vcnl36825t_channel_get,
539+
.attr_set = vcnl36825t_attr_set,
540+
#if CONFIG_VCNL36825T_TRIGGER
541+
.trigger_set = vcnl36825t_trigger_set,
542+
#endif
501543
};
502544

503545
#define VCNL36825T_DEFINE(inst) \
@@ -524,7 +566,11 @@ static const struct sensor_driver_api vcnl36825t_driver_api = {
524566
.laser_current = DT_INST_ENUM_IDX(inst, laser_current), \
525567
.high_dynamic_output = DT_INST_PROP(inst, high_dynamic_output), \
526568
.sunlight_cancellation = DT_INST_PROP(inst, sunlight_cancellation), \
527-
}; \
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)))}; \
528574
IF_ENABLED(CONFIG_PM_DEVICE, (PM_DEVICE_DT_INST_DEFINE(inst, vcnl36825t_pm_action))); \
529575
SENSOR_DEVICE_DT_INST_DEFINE( \
530576
inst, vcnl36825t_init, \

drivers/sensor/vishay/vcnl36825t/vcnl36825t.h

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@
5656
#define VCNL36825T_PS_MPS_POS 12
5757
#define VCNL36825T_PS_IT_POS 14
5858

59-
#define VCNL36825T_PS_ST_MSK GENMASK(0, 0)
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)
6063

6164
#define VCNL36825T_PS_ST_START (0 << VCNL36825T_PS_ST_POS)
6265
#define VCNL36825T_PS_ST_STOP (1 << VCNL36825T_PS_ST_POS)
@@ -65,9 +68,9 @@
6568
#define VCNL36825T_PS_SMART_PERS_ENABLED (1 << VCNL36825T_PS_PS_SMART_PERS_POS)
6669

6770
#define VCNL36825T_PS_INT_DISABLE (0 << VCNL36825T_PS_INT_POS)
68-
#define VCNL36825T_PS_INT_THDH_PERS_LATCHED (1 << VCNL36825T_PS_INT_POS)
69-
#define VCNL36825T_PS_INT_THDH_FIRST_LATCHED (2 << VCNL36825T_PS_INT_POS)
70-
#define VCNL36825T_PS_INT_ENABLED (3 << 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)
7174

7275
#define VCNL36825T_PS_PERS_1 (0 << VCNL36825T_PS_PERS_POS)
7376
#define VCNL36825T_PS_PERS_2 (1 << VCNL36825T_PS_PERS_POS)
@@ -281,6 +284,12 @@ enum vcnl38625t_laser_current {
281284
VCNL36825T_LASER_CURRENT_20MS,
282285
};
283286

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+
284293
struct vcnl36825t_config {
285294
struct i2c_dt_spec i2c;
286295

@@ -297,6 +306,13 @@ struct vcnl36825t_config {
297306
enum vcnl38625t_laser_current laser_current;
298307
bool high_dynamic_output;
299308
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
300316
};
301317

302318
struct vcnl36825t_data {
@@ -308,6 +324,42 @@ struct vcnl36825t_data {
308324
unsigned int meas_timeout_running_us;
309325
unsigned int meas_timeout_wakeup_us;
310326
#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
311345
};
312346

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+
313365
#endif

0 commit comments

Comments
 (0)