diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index ca65a4128003c5..679d9c3c6e4ab0 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -62,6 +62,7 @@ add_subdirectory_ifdef(CONFIG_TH02 th02) add_subdirectory_ifdef(CONFIG_TSIC_XX6 tsic_xx6) add_subdirectory_ifdef(CONFIG_VEAA_X_3 veaa_x_3) add_subdirectory_ifdef(CONFIG_VOLTAGE_DIVIDER voltage_divider) +add_subdirectory_ifdef(CONFIG_XBR818 xbr818) add_subdirectory_ifdef(CONFIG_TACH_ENE_KB1200 ene_tach_kb1200) zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/sensor.h) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 452d8182eb7983..4c6bfc3c413da1 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -146,6 +146,7 @@ source "drivers/sensor/th02/Kconfig" source "drivers/sensor/tsic_xx6/Kconfig" source "drivers/sensor/veaa_x_3/Kconfig" source "drivers/sensor/voltage_divider/Kconfig" +source "drivers/sensor/xbr818/Kconfig" source "drivers/sensor/ene_tach_kb1200/Kconfig" endif # SENSOR diff --git a/drivers/sensor/xbr818/CMakeLists.txt b/drivers/sensor/xbr818/CMakeLists.txt new file mode 100644 index 00000000000000..96d6c578d64dbc --- /dev/null +++ b/drivers/sensor/xbr818/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_XBR818 xbr818.c) diff --git a/drivers/sensor/xbr818/Kconfig b/drivers/sensor/xbr818/Kconfig new file mode 100644 index 00000000000000..75b91c758ac784 --- /dev/null +++ b/drivers/sensor/xbr818/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2024 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +config XBR818 + bool "XBR818 Radar" + default y + depends on DT_HAS_PHOSENSE_XBR818_ENABLED + select I2C + help + Enable driver for the Phosense XBR818 Radar Sensor diff --git a/drivers/sensor/xbr818/xbr818.c b/drivers/sensor/xbr818/xbr818.c new file mode 100644 index 00000000000000..131a061a0f29ad --- /dev/null +++ b/drivers/sensor/xbr818/xbr818.c @@ -0,0 +1,533 @@ +/* + * Copyright (c) 2024 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT phosense_xbr818 + +#include +#include + +#include +LOG_MODULE_REGISTER(XBR818, CONFIG_SENSOR_LOG_LEVEL); + +#include "xbr818.h" +#include + +static int xbr818_enable_i2c(const struct device *dev) +{ + const struct xbr818_config *config = dev->config; + int ret; + + if (config->i2c_en.port) { + ret = gpio_pin_set_dt(&config->i2c_en, 1); + if (ret != 0) { + LOG_ERR("%s: could not set i2c_en pin", dev->name); + } + k_usleep(10); + return ret; + } + return 0; +} + +static int xbr818_disable_i2c(const struct device *dev) +{ + const struct xbr818_config *config = dev->config; + int ret; + + if (config->i2c_en.port) { + ret = gpio_pin_set_dt(&config->i2c_en, 0); + if (ret != 0) { + LOG_ERR("%s: could not unset i2c_en pin", dev->name); + } + return ret; + } + return 0; +} + +static int xbr818_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + const struct xbr818_config *config = dev->config; + struct xbr818_data *data = dev->data; + int ret; + + if (chan != SENSOR_CHAN_PROX && chan != SENSOR_CHAN_ALL) { + LOG_ERR("%s: requesting unsupported channel %i", dev->name, chan); + return -ENOTSUP; + } + + ret = gpio_pin_get_dt(&config->io_val); + if (ret < 0) { + return ret; + } + data->value = (ret == 1 ? true : false); + + return 0; +} + +static int xbr818_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct xbr818_data *data = dev->data; + + if (chan != SENSOR_CHAN_PROX) { + LOG_ERR("%s: requesting unsupported channel %i", dev->name, chan); + return -ENOTSUP; + } + + val->val1 = (data->value ? 1 : 0); + val->val2 = 0; + + return 0; +} + +static int xbr818_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + const struct xbr818_config *config = dev->config; + int ret; + uint32_t tmp; + uint64_t tmpf; + + if (chan != SENSOR_CHAN_PROX) { + LOG_ERR("%s: requesting unsupported channel %i", dev->name, chan); + return -ENOTSUP; + } + + if (val->val1 < 0) { + return -EINVAL; + } + + ret = xbr818_enable_i2c(dev); + if (ret != 0) { + return ret; + } + + /* this cast is necessary due to the additional attributes not being part of the + * initial enum and causing a build error without it. + */ + switch ((int)attr) { + case SENSOR_ATTR_LOWER_THRESH: + if (val->val1 > 0xFFFF) { + return -EINVAL; + } + tmp = val->val1 & 0xFF; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_THRESHOLD_1, tmp); + if (ret != 0) { + break; + } + tmp = (val->val1 & 0xFF00) >> 8; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_THRESHOLD_2, tmp); + break; + case SENSOR_ATTR_XBR818_NOISE_FLOOR: + if (val->val1 > 0xFFFF) { + return -EINVAL; + } + tmp = val->val1 & 0xFF; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_THRESHOLD_NOISE_1, tmp); + if (ret != 0) { + break; + } + tmp = (val->val1 & 0xFF00) >> 8; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_THRESHOLD_NOISE_2, tmp); + break; + case SENSOR_ATTR_XBR818_DELAY_TIME: + tmpf = (uint64_t)val->val1 * 1000000 + (uint64_t)val->val2; + tmpf = (tmpf * SENSOR_XBR818_CLOCKRATE) / 1000000; + if (tmpf > 0xFFFFFF) { + return -EINVAL; + } + tmp = tmpf & 0xFF; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_DELAY_TIME_1, tmp); + if (ret != 0) { + break; + } + tmp = (tmpf & 0xFF00) >> 8; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_DELAY_TIME_2, tmp); + if (ret != 0) { + break; + } + tmp = (tmpf & 0xFF0000) >> 16; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_DELAY_TIME_3, tmp); + break; + case SENSOR_ATTR_XBR818_LOCK_TIME: + tmpf = (uint64_t)val->val1 * 1000000 + (uint64_t)val->val2; + tmpf = (tmpf * SENSOR_XBR818_CLOCKRATE) / 1000000; + if (tmpf > 0xFFFFFF) { + return -EINVAL; + } + tmp = tmpf & 0xFF; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_LOCK_TIME_1, tmp); + if (ret != 0) { + break; + } + tmp = (tmpf & 0xFF00) >> 8; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_LOCK_TIME_2, tmp); + if (ret != 0) { + break; + } + tmp = (tmpf & 0xFF0000) >> 16; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_LOCK_TIME_3, tmp); + break; + case SENSOR_ATTR_XBR818_RF_POWER: + if (val->val1 > 0x7) { + return -EINVAL; + } + tmp = val->val1 & 0x7; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_RF_POWER, tmp); + break; + case SENSOR_ATTR_SAMPLING_FREQUENCY: + if (val->val1 > SENSOR_XBR818_CLOCKRATE) { + return -EINVAL; + } + tmp = SENSOR_XBR818_CLOCKRATE / val->val1; + if (tmp > 0xFF) { + return -EINVAL; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_SAMPLE_RATE_DIVIDER, tmp); + break; + default: + ret = -ENODEV; + + break; + } + + if (ret != 0) { + return ret; + } + + ret = xbr818_disable_i2c(dev); + if (ret != 0) { + return ret; + } + + return ret; +} + +static int xbr818_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + const struct xbr818_config *config = dev->config; + int ret; + uint8_t tmp = 0; + uint64_t tmpf; + + if (chan != SENSOR_CHAN_PROX) { + LOG_ERR("%s: requesting unsupported channel %i", dev->name, chan); + return -ENOTSUP; + } + + ret = xbr818_enable_i2c(dev); + if (ret != 0) { + return ret; + } + + /* this cast is necessary due to the additional attributes not being part of the + * initial enum and causing a build error without it. + */ + switch ((int)attr) { + case SENSOR_ATTR_LOWER_THRESH: + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_THRESHOLD_1, &tmp); + if (ret != 0) { + break; + } + val->val1 = tmp & 0xFF; + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_THRESHOLD_2, &tmp); + if (ret != 0) { + break; + } + val->val1 |= tmp << 8; + break; + case SENSOR_ATTR_XBR818_NOISE_FLOOR: + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_THRESHOLD_NOISE_1, &tmp); + if (ret != 0) { + break; + } + val->val1 = tmp & 0xFF; + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_THRESHOLD_NOISE_2, &tmp); + if (ret != 0) { + break; + } + val->val1 |= tmp << 8; + break; + case SENSOR_ATTR_XBR818_DELAY_TIME: + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_DELAY_TIME_1, &tmp); + if (ret != 0) { + break; + } + val->val1 = tmp & 0xFF; + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_DELAY_TIME_2, &tmp); + if (ret != 0) { + break; + } + val->val1 |= tmp << 8; + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_DELAY_TIME_3, &tmp); + if (ret != 0) { + break; + } + val->val1 |= tmp << 16; + tmpf = (uint64_t)val->val1 * 1000000; + tmpf /= SENSOR_XBR818_CLOCKRATE; + val->val1 = tmpf / 1000000; + val->val2 = tmpf - val->val1 * 1000000; + break; + case SENSOR_ATTR_XBR818_LOCK_TIME: + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_LOCK_TIME_1, &tmp); + if (ret != 0) { + break; + } + val->val1 = tmp & 0xFF; + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_LOCK_TIME_2, &tmp); + if (ret != 0) { + break; + } + val->val1 |= tmp << 8; + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_LOCK_TIME_3, &tmp); + if (ret != 0) { + break; + } + val->val1 |= tmp << 16; + tmpf = (uint64_t)val->val1 * 1000000; + tmpf /= SENSOR_XBR818_CLOCKRATE; + val->val1 = tmpf / 1000000; + val->val2 = tmpf - val->val1 * 1000000; + break; + case SENSOR_ATTR_XBR818_RF_POWER: + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_RF_POWER, &tmp); + if (ret != 0) { + break; + } + val->val1 = tmp & 0x7; + break; + case SENSOR_ATTR_SAMPLING_FREQUENCY: + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_SAMPLE_RATE_DIVIDER, &tmp); + if (ret != 0) { + break; + } + val->val1 = SENSOR_XBR818_CLOCKRATE / tmp; + break; + default: + ret = -ENODEV; + + break; + } + + ret = xbr818_disable_i2c(dev); + if (ret != 0) { + return ret; + } + + return ret; +} + +static void xbr818_work(struct k_work *work) +{ + struct xbr818_data *data = CONTAINER_OF(work, struct xbr818_data, work); + + if (likely(data->handler != NULL)) { + data->handler(data->dev, data->trigger); + } +} + +static void xbr818_gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + struct xbr818_data *data = CONTAINER_OF(cb, struct xbr818_data, gpio_cb); + + k_work_submit(&data->work); +} + +static int xbr818_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + const struct xbr818_config *config = dev->config; + struct xbr818_data *data = dev->data; + int ret; + + if (trig->chan != SENSOR_CHAN_PROX) { + LOG_ERR("%s: requesting unsupported channel %i", dev->name, trig->chan); + return -ENOTSUP; + } + + if (trig->type != SENSOR_TRIG_MOTION) { + LOG_ERR("%s: requesting unsupported trigger %i", dev->name, trig->type); + return -ENOTSUP; + } + + data->handler = handler; + data->trigger = trig; + ret = gpio_pin_interrupt_configure_dt(&config->io_val, GPIO_INT_EDGE_RISING); + if (ret < 0) { + return ret; + } + + if (handler) { + ret = gpio_add_callback(config->io_val.port, &data->gpio_cb); + } else { + ret = gpio_remove_callback(config->io_val.port, &data->gpio_cb); + } + + return ret; +} + +static int xbr818_init_defaults(const struct device *dev) +{ + const struct xbr818_config *config = dev->config; + int ret; + + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_IO_ACTIVE_VALUE_REG, 0x03); + if (ret != 0) { + return ret; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_RF_EN_SEL, 0x20); + if (ret != 0) { + return ret; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_SAMPLE_RATE_DIVIDER, 0x20); + if (ret != 0) { + return ret; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_RF_POWER, 0x45); + if (ret != 0) { + return ret; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_TIMER_CTRL, 0x21); + if (ret != 0) { + return ret; + } + + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_THRESHOLD_1, 0x5a); + if (ret != 0) { + return ret; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_THRESHOLD_2, 0x01); + if (ret != 0) { + return ret; + } + + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_THRESHOLD_NOISE_1, 0x55); + if (ret != 0) { + return ret; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_THRESHOLD_NOISE_2, 0x01); + if (ret != 0) { + return ret; + } + + /* 0.1 seconds */ + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_DELAY_TIME_1, 0x80); + if (ret != 0) { + return ret; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_DELAY_TIME_2, 0x0C); + if (ret != 0) { + return ret; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_DELAY_TIME_3, 0x00); + if (ret != 0) { + return ret; + } + + /* 0.5 seconds */ + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_LOCK_TIME_1, 0x80); + if (ret != 0) { + return ret; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_LOCK_TIME_2, 0x3E); + if (ret != 0) { + return ret; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_LOCK_TIME_3, 0x00); + if (ret != 0) { + return ret; + } + + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_PIN_SETTINGS, 0x0C); + if (ret != 0) { + return ret; + } + + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_I2C_OUT, 0x1); + if (ret != 0) { + return ret; + } + + return 0; +} + +static int xbr818_init(const struct device *dev) +{ + const struct xbr818_config *config = dev->config; + struct xbr818_data *data = dev->data; + int ret; + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C device not ready"); + return -ENODEV; + } + + data->dev = dev; + data->work.handler = xbr818_work; + + ret = gpio_pin_configure_dt(&config->io_val, GPIO_INPUT); + if (ret != 0) { + LOG_ERR("%s: could not configure io_val(int) pin", dev->name); + return ret; + } + + if (config->i2c_en.port) { + ret = gpio_pin_configure_dt(&config->i2c_en, GPIO_OUTPUT); + if (ret != 0) { + LOG_ERR("%s: could not configure i2c_en pin", dev->name); + return ret; + } + } + + ret = xbr818_enable_i2c(dev); + if (ret != 0) { + return ret; + } + + ret = xbr818_init_defaults(dev); + if (ret != 0) { + LOG_ERR("%s: unable to configure", dev->name); + } + + ret = xbr818_disable_i2c(dev); + if (ret != 0) { + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&config->io_val, GPIO_INT_DISABLE); + if (ret) { + LOG_ERR("%s: failed to configure gpio interrupt: %d", dev->name, ret); + return ret; + } + + gpio_init_callback(&data->gpio_cb, xbr818_gpio_callback, BIT(config->io_val.pin)); + + return ret; +} + +static const struct sensor_driver_api xbr818_api = { + .sample_fetch = xbr818_sample_fetch, + .channel_get = xbr818_channel_get, + .attr_set = xbr818_attr_set, + .attr_get = xbr818_attr_get, + .trigger_set = xbr818_trigger_set, +}; + +#define XBR818_INIT(inst) \ + static const struct xbr818_config xbr818_##inst##_config = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .i2c_en = GPIO_DT_SPEC_GET_OR(DT_INST(inst, phosense_xbr818), i2c_en_gpios, {0}), \ + .io_val = GPIO_DT_SPEC_GET(DT_INST(inst, phosense_xbr818), int_gpios), \ + }; \ + \ + static struct xbr818_data xbr818_##inst##_data; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, xbr818_init, NULL, &xbr818_##inst##_data, \ + &xbr818_##inst##_config, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &xbr818_api); + +DT_INST_FOREACH_STATUS_OKAY(XBR818_INIT); diff --git a/drivers/sensor/xbr818/xbr818.h b/drivers/sensor/xbr818/xbr818.h new file mode 100644 index 00000000000000..f30f6d5ed0d48b --- /dev/null +++ b/drivers/sensor/xbr818/xbr818.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_XBR818_XBR818_H_ +#define ZEPHYR_DRIVERS_SENSOR_XBR818_XBR818_H_ + +#include +#include +#include +#include + +/* 32Khz clockrate, most time values are multiple of this */ +#define SENSOR_XBR818_CLOCKRATE 32000 + +struct xbr818_config { + struct i2c_dt_spec i2c; + struct gpio_dt_spec i2c_en; + struct gpio_dt_spec io_val; +}; + +struct xbr818_data { + bool value; + uint32_t trigger_type; + sensor_trigger_handler_t handler; + struct gpio_callback gpio_cb; + const struct sensor_trigger *trigger; + const struct device *dev; + struct k_work work; +}; + +/* reference rd-04 module manual for more information */ +/* [0-2]: power of PA + * [4-6]: mixer trim + */ +#define XBR818_RF_POWER 0x03 +#define XBR818_RF_EN_SEL 0x04 +/* minimum value of 2 */ +#define XBR818_SAMPLE_RATE_DIVIDER 0x10 +/* [0]: enable detection + * [1-2]: readable data. 0: det_dc_sum 1: det_ac_sum 2: det_dc_used 3: det_noise + * [3]: enable read on 0x28-0x29 + * [4]: signal detection threshold. 0: auto by pin 1: register + * [7]: enable read on 0x26-0x29 + */ +#define XBR818_I2C_OUT 0x13 +/* Threshold for detection + * [0-7] + */ +#define XBR818_THRESHOLD_1 0x18 +/* [8-15] */ +#define XBR818_THRESHOLD_2 0x19 +/* Threshold for noise + * [0-7] + */ +#define XBR818_THRESHOLD_NOISE_1 0x1A +/* [8-15] */ +#define XBR818_THRESHOLD_NOISE_2 0x1B +/* Delay Time (in 1/32000 seconds) + * [0-7] + */ +#define XBR818_DELAY_TIME_1 0x1D +/* [8-15] */ +#define XBR818_DELAY_TIME_2 0x1E +/* [16-23] */ +#define XBR818_DELAY_TIME_3 0x1F +/* [0]: enable + * [1-2]: light sensor timer. 0: disabled 1: 4 sec 2: 1 minute 3: 1 hour + * [3-4]: output timer. 0: 1 sec 1: 1 minute 2: 1 hour 3: 1 day + * [5]: delay time. 0: 'configure by pin' 1: configure by register + */ +#define XBR818_TIMER_CTRL 0x1C +/* Lock Time (in 1/32000 seconds) + * [0-7] + */ +#define XBR818_LOCK_TIME_1 0x20 +/* [8-15] */ +#define XBR818_LOCK_TIME_2 0x21 +/* [16-23] */ +#define XBR818_LOCK_TIME_3 0x22 +/* Pin settings + * [0-3]: IO_VAL pin + * 0xc: io_value_out, 0xd: io_value_out inverted, 0xf: GPIO + * [4-7]: INT_IRQ pin + * 0x0: t3_int_irq, 0x9: io_value_out, 0xa: io_value_out inverted, 0xf: GPIO + */ +#define XBR818_PIN_SETTINGS 0x23 +/* [0]: ADC1 is configured for VCO trimming. 0: enable, 1: disable + * [1]: Low power mode is pin or register. 0: pin 1: register + * [2]: If IO_VAL pin is GPIO, output. 0: no 1: yes + * [3]: if INT_IRQ pin is GPIO, output. 0:no 1:yes + */ +#define XBR818_IO_ACTIVE_VALUE_REG 0x24 + +#endif /* ZEPHYR_DRIVERS_SENSOR_XBR818_XBR818_H_ */ diff --git a/dts/bindings/sensor/phosense,xbr818.yaml b/dts/bindings/sensor/phosense,xbr818.yaml new file mode 100644 index 00000000000000..9eeedba0584723 --- /dev/null +++ b/dts/bindings/sensor/phosense,xbr818.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +description: | + Phosense XBR818 I2C-capable 10 GHz Radar Sensor + +compatible: "phosense,xbr818" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + int-gpios: + type: phandle-array + required: true + description: GPIO pin connected to IO pin (IO_VAL) + + i2c-en-gpios: + type: phandle-array + description: GPIO pin connected to I2C enable (I2C_EN) diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index ee115b920f6fd3..1d06e4b8201d75 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -508,6 +508,7 @@ pda Precision Design Associates, Inc. pericom Pericom Technology Inc. pervasive Pervasive Displays, Inc. phicomm PHICOMM Co., Ltd. +phosense Beijing Phosense Electronic Technology Co., Ltd. phytec PHYTEC picochip Picochip Ltd pine64 Pine64 diff --git a/include/zephyr/drivers/sensor/xbr818.h b/include/zephyr/drivers/sensor/xbr818.h new file mode 100644 index 00000000000000..06cac96cbde5d6 --- /dev/null +++ b/include/zephyr/drivers/sensor/xbr818.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024, MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Extended public API for Phosense XBR818 10 GHz Radar + * + * This exposes 4 additional attributes used to configure the IC + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_XBR818_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_XBR818_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum sensor_attribute_xbr818 { + /*! + * Time of received activity before output is triggered, in seconds + */ + SENSOR_ATTR_XBR818_DELAY_TIME = SENSOR_ATTR_PRIV_START, + /*! + * How long output stays triggered after no more activity is detected, in seconds + */ + SENSOR_ATTR_XBR818_LOCK_TIME, + /*! + * Noise floor Threshold for Radar, 16 first LSBs of the integer part. + */ + SENSOR_ATTR_XBR818_NOISE_FLOOR, + /*! + * RF Power for Radar, 0 to 7, LSB of the integer part. + */ + SENSOR_ATTR_XBR818_RF_POWER +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_XBR818_H_ */ diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 9a84104e1eddfb..af19aad8bdc28c 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -1211,3 +1211,10 @@ test_i2c_tmag3001: tmag3001@a8 { operation-mode = ; angle-magnitude-axis = ; }; + +test_i2c_xbr818: xrb818@a9 { + compatible = "phosense,xbr818"; + reg = <0xa9>; + int-gpios = <&test_gpio 0 0>; + i2c-en-gpios = <&test_gpio 0 0>; +};