drivers: sensor: hts221: cleanup related to devicetree and trigger idiom
Put all the devicetree configuration data into a config structure in flash, which removes some ultra-long identifiers from the code and makes it more readable, and prepares for multiple instance support. Consistently use the interrupt signal datasheet name for all objects that are specific to that signal, including configuration structure tags and function names. Update the trigger idiom for setup/handle/process stages. Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
parent
a08aec9999
commit
0d1d06ea79
3 changed files with 125 additions and 102 deletions
|
@ -24,7 +24,7 @@ static int hts221_channel_get(struct device *dev,
|
|||
enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
struct hts221_data *drv_data = dev->driver_data;
|
||||
struct hts221_data *data = dev->driver_data;
|
||||
s32_t conv_val;
|
||||
|
||||
/*
|
||||
|
@ -32,20 +32,19 @@ static int hts221_channel_get(struct device *dev,
|
|||
* for more details
|
||||
*/
|
||||
if (chan == SENSOR_CHAN_AMBIENT_TEMP) {
|
||||
conv_val = (s32_t)(drv_data->t1_degc_x8 -
|
||||
drv_data->t0_degc_x8) *
|
||||
(drv_data->t_sample - drv_data->t0_out) /
|
||||
(drv_data->t1_out - drv_data->t0_out) +
|
||||
drv_data->t0_degc_x8;
|
||||
conv_val = (s32_t)(data->t1_degc_x8 - data->t0_degc_x8) *
|
||||
(data->t_sample - data->t0_out) /
|
||||
(data->t1_out - data->t0_out) +
|
||||
data->t0_degc_x8;
|
||||
|
||||
/* convert temperature x8 to degrees Celsius */
|
||||
val->val1 = conv_val / 8;
|
||||
val->val2 = (conv_val % 8) * (1000000 / 8);
|
||||
} else if (chan == SENSOR_CHAN_HUMIDITY) {
|
||||
conv_val = (s32_t)(drv_data->h1_rh_x2 - drv_data->h0_rh_x2) *
|
||||
(drv_data->rh_sample - drv_data->h0_t0_out) /
|
||||
(drv_data->h1_t0_out - drv_data->h0_t0_out) +
|
||||
drv_data->h0_rh_x2;
|
||||
conv_val = (s32_t)(data->h1_rh_x2 - data->h0_rh_x2) *
|
||||
(data->rh_sample - data->h0_t0_out) /
|
||||
(data->h1_t0_out - data->h0_t0_out) +
|
||||
data->h0_rh_x2;
|
||||
|
||||
/* convert humidity x2 to percent */
|
||||
val->val1 = conv_val / 2;
|
||||
|
@ -59,43 +58,46 @@ static int hts221_channel_get(struct device *dev,
|
|||
|
||||
static int hts221_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
struct hts221_data *drv_data = dev->driver_data;
|
||||
struct hts221_data *data = dev->driver_data;
|
||||
const struct hts221_config *cfg = dev->config->config_info;
|
||||
u8_t buf[4];
|
||||
|
||||
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
|
||||
|
||||
if (i2c_burst_read(drv_data->i2c, DT_INST_0_ST_HTS221_BASE_ADDRESS,
|
||||
if (i2c_burst_read(data->i2c, cfg->i2c_addr,
|
||||
HTS221_REG_DATA_START | HTS221_AUTOINCREMENT_ADDR,
|
||||
buf, 4) < 0) {
|
||||
LOG_ERR("Failed to fetch data sample.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
drv_data->rh_sample = sys_le16_to_cpu(buf[0] | (buf[1] << 8));
|
||||
drv_data->t_sample = sys_le16_to_cpu(buf[2] | (buf[3] << 8));
|
||||
data->rh_sample = sys_le16_to_cpu(buf[0] | (buf[1] << 8));
|
||||
data->t_sample = sys_le16_to_cpu(buf[2] | (buf[3] << 8));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hts221_read_conversion_data(struct hts221_data *drv_data)
|
||||
static int hts221_read_conversion_data(struct device *dev)
|
||||
{
|
||||
struct hts221_data *data = dev->driver_data;
|
||||
const struct hts221_config *cfg = dev->config->config_info;
|
||||
u8_t buf[16];
|
||||
|
||||
if (i2c_burst_read(drv_data->i2c, DT_INST_0_ST_HTS221_BASE_ADDRESS,
|
||||
if (i2c_burst_read(data->i2c, cfg->i2c_addr,
|
||||
HTS221_REG_CONVERSION_START |
|
||||
HTS221_AUTOINCREMENT_ADDR, buf, 16) < 0) {
|
||||
LOG_ERR("Failed to read conversion data.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
drv_data->h0_rh_x2 = buf[0];
|
||||
drv_data->h1_rh_x2 = buf[1];
|
||||
drv_data->t0_degc_x8 = sys_le16_to_cpu(buf[2] | ((buf[5] & 0x3) << 8));
|
||||
drv_data->t1_degc_x8 = sys_le16_to_cpu(buf[3] | ((buf[5] & 0xC) << 6));
|
||||
drv_data->h0_t0_out = sys_le16_to_cpu(buf[6] | (buf[7] << 8));
|
||||
drv_data->h1_t0_out = sys_le16_to_cpu(buf[10] | (buf[11] << 8));
|
||||
drv_data->t0_out = sys_le16_to_cpu(buf[12] | (buf[13] << 8));
|
||||
drv_data->t1_out = sys_le16_to_cpu(buf[14] | (buf[15] << 8));
|
||||
data->h0_rh_x2 = buf[0];
|
||||
data->h1_rh_x2 = buf[1];
|
||||
data->t0_degc_x8 = sys_le16_to_cpu(buf[2] | ((buf[5] & 0x3) << 8));
|
||||
data->t1_degc_x8 = sys_le16_to_cpu(buf[3] | ((buf[5] & 0xC) << 6));
|
||||
data->h0_t0_out = sys_le16_to_cpu(buf[6] | (buf[7] << 8));
|
||||
data->h1_t0_out = sys_le16_to_cpu(buf[10] | (buf[11] << 8));
|
||||
data->t0_out = sys_le16_to_cpu(buf[12] | (buf[13] << 8));
|
||||
data->t1_out = sys_le16_to_cpu(buf[14] | (buf[15] << 8));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -110,18 +112,18 @@ static const struct sensor_driver_api hts221_driver_api = {
|
|||
|
||||
int hts221_init(struct device *dev)
|
||||
{
|
||||
struct hts221_data *drv_data = dev->driver_data;
|
||||
const struct hts221_config *cfg = dev->config->config_info;
|
||||
struct hts221_data *data = dev->driver_data;
|
||||
u8_t id, idx;
|
||||
|
||||
drv_data->i2c = device_get_binding(DT_INST_0_ST_HTS221_BUS_NAME);
|
||||
if (drv_data->i2c == NULL) {
|
||||
LOG_ERR("Could not get pointer to %s device.",
|
||||
DT_INST_0_ST_HTS221_BUS_NAME);
|
||||
data->i2c = device_get_binding(cfg->i2c_bus);
|
||||
if (data->i2c == NULL) {
|
||||
LOG_ERR("Could not get pointer to %s device.", cfg->i2c_bus);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check chip ID */
|
||||
if (i2c_reg_read_byte(drv_data->i2c, DT_INST_0_ST_HTS221_BASE_ADDRESS,
|
||||
if (i2c_reg_read_byte(data->i2c, cfg->i2c_addr,
|
||||
HTS221_REG_WHO_AM_I, &id) < 0) {
|
||||
LOG_ERR("Failed to read chip ID.");
|
||||
return -EIO;
|
||||
|
@ -144,7 +146,7 @@ int hts221_init(struct device *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (i2c_reg_write_byte(drv_data->i2c, DT_INST_0_ST_HTS221_BASE_ADDRESS,
|
||||
if (i2c_reg_write_byte(data->i2c, cfg->i2c_addr,
|
||||
HTS221_REG_CTRL1,
|
||||
(idx + 1) << HTS221_ODR_SHIFT | HTS221_BDU_BIT |
|
||||
HTS221_PD_BIT) < 0) {
|
||||
|
@ -158,7 +160,7 @@ int hts221_init(struct device *dev)
|
|||
*/
|
||||
k_sleep(K_MSEC(3));
|
||||
|
||||
if (hts221_read_conversion_data(drv_data) < 0) {
|
||||
if (hts221_read_conversion_data(dev) < 0) {
|
||||
LOG_ERR("Failed to read conversion data.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -173,8 +175,17 @@ int hts221_init(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct hts221_data hts221_driver;
|
||||
static struct hts221_data hts221_driver;
|
||||
static const struct hts221_config hts221_cfg = {
|
||||
.i2c_bus = DT_INST_0_ST_HTS221_BUS_NAME,
|
||||
.i2c_addr = DT_INST_0_ST_HTS221_BASE_ADDRESS,
|
||||
#ifdef CONFIG_HTS221_TRIGGER
|
||||
.drdy_pin = DT_INST_0_ST_HTS221_DRDY_GPIOS_PIN,
|
||||
.drdy_flags = DT_INST_0_ST_HTS221_DRDY_GPIOS_FLAGS,
|
||||
.drdy_controller = DT_INST_0_ST_HTS221_DRDY_GPIOS_CONTROLLER,
|
||||
#endif /* CONFIG_HTS221_TRIGGER */
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(hts221, DT_INST_0_ST_HTS221_LABEL, hts221_init, &hts221_driver,
|
||||
NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
|
||||
&hts221_driver_api);
|
||||
DEVICE_AND_API_INIT(hts221, DT_INST_0_ST_HTS221_LABEL, hts221_init,
|
||||
&hts221_driver, &hts221_cfg, POST_KERNEL,
|
||||
CONFIG_SENSOR_INIT_PRIORITY, &hts221_driver_api);
|
||||
|
|
|
@ -43,8 +43,9 @@ struct hts221_data {
|
|||
s16_t t1_out;
|
||||
|
||||
#ifdef CONFIG_HTS221_TRIGGER
|
||||
struct device *gpio;
|
||||
struct gpio_callback gpio_cb;
|
||||
struct device *dev;
|
||||
struct device *drdy_dev;
|
||||
struct gpio_callback drdy_cb;
|
||||
|
||||
struct sensor_trigger data_ready_trigger;
|
||||
sensor_trigger_handler_t data_ready_handler;
|
||||
|
@ -52,15 +53,24 @@ struct hts221_data {
|
|||
#if defined(CONFIG_HTS221_TRIGGER_OWN_THREAD)
|
||||
K_THREAD_STACK_MEMBER(thread_stack, CONFIG_HTS221_THREAD_STACK_SIZE);
|
||||
struct k_thread thread;
|
||||
struct k_sem gpio_sem;
|
||||
struct k_sem drdy_sem;
|
||||
#elif defined(CONFIG_HTS221_TRIGGER_GLOBAL_THREAD)
|
||||
struct k_work work;
|
||||
struct device *dev;
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_HTS221_TRIGGER */
|
||||
};
|
||||
|
||||
struct hts221_config {
|
||||
const char *i2c_bus;
|
||||
u16_t i2c_addr;
|
||||
#ifdef CONFIG_HTS221_TRIGGER
|
||||
gpio_pin_t drdy_pin;
|
||||
gpio_flags_t drdy_flags;
|
||||
const char *drdy_controller;
|
||||
#endif /* CONFIG_HTS221_TRIGGER */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HTS221_TRIGGER
|
||||
int hts221_trigger_set(struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
|
|
|
@ -15,94 +15,96 @@
|
|||
|
||||
LOG_MODULE_DECLARE(HTS221, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
static inline void setup_drdy(struct hts221_data *drv_data,
|
||||
static inline void setup_drdy(struct device *dev,
|
||||
bool enable)
|
||||
{
|
||||
struct hts221_data *data = dev->driver_data;
|
||||
const struct hts221_config *cfg = dev->config->config_info;
|
||||
unsigned int flags = enable
|
||||
? GPIO_INT_EDGE_TO_ACTIVE
|
||||
: GPIO_INT_DISABLE;
|
||||
|
||||
gpio_pin_interrupt_configure(drv_data->gpio,
|
||||
DT_INST_0_ST_HTS221_DRDY_GPIOS_PIN,
|
||||
flags);
|
||||
gpio_pin_interrupt_configure(data->drdy_dev, cfg->drdy_pin, flags);
|
||||
}
|
||||
|
||||
static inline void handle_drdy(struct hts221_data *drv_data)
|
||||
static inline void handle_drdy(struct device *dev)
|
||||
{
|
||||
setup_drdy(drv_data, false);
|
||||
struct hts221_data *data = dev->driver_data;
|
||||
|
||||
setup_drdy(dev, false);
|
||||
|
||||
#if defined(CONFIG_HTS221_TRIGGER_OWN_THREAD)
|
||||
k_sem_give(&drv_data->gpio_sem);
|
||||
k_sem_give(&data->drdy_sem);
|
||||
#elif defined(CONFIG_HTS221_TRIGGER_GLOBAL_THREAD)
|
||||
k_work_submit(&drv_data->work);
|
||||
k_work_submit(&data->work);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void process_drdy(struct device *dev)
|
||||
{
|
||||
struct hts221_data *data = dev->driver_data;
|
||||
|
||||
if (data->data_ready_handler != NULL) {
|
||||
data->data_ready_handler(dev, &data->data_ready_trigger);
|
||||
}
|
||||
|
||||
if (data->data_ready_handler != NULL) {
|
||||
setup_drdy(dev, true);
|
||||
}
|
||||
}
|
||||
|
||||
int hts221_trigger_set(struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
struct hts221_data *drv_data = dev->driver_data;
|
||||
struct hts221_data *data = dev->driver_data;
|
||||
const struct hts221_config *cfg = dev->config->config_info;
|
||||
|
||||
__ASSERT_NO_MSG(trig->type == SENSOR_TRIG_DATA_READY);
|
||||
|
||||
setup_drdy(drv_data, false);
|
||||
setup_drdy(dev, false);
|
||||
|
||||
drv_data->data_ready_handler = handler;
|
||||
data->data_ready_handler = handler;
|
||||
if (handler == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
drv_data->data_ready_trigger = *trig;
|
||||
data->data_ready_trigger = *trig;
|
||||
|
||||
setup_drdy(drv_data, true);
|
||||
setup_drdy(dev, true);
|
||||
|
||||
/* If DRDY is active we probably won't get the rising edge, so
|
||||
* invoke the callback manually.
|
||||
*/
|
||||
if (gpio_pin_get(drv_data->gpio,
|
||||
DT_INST_0_ST_HTS221_DRDY_GPIOS_PIN) > 0) {
|
||||
handle_drdy(drv_data);
|
||||
if (gpio_pin_get(data->drdy_dev, cfg->drdy_pin) > 0) {
|
||||
handle_drdy(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hts221_gpio_callback(struct device *dev,
|
||||
static void hts221_drdy_callback(struct device *dev,
|
||||
struct gpio_callback *cb, u32_t pins)
|
||||
{
|
||||
struct hts221_data *drv_data =
|
||||
CONTAINER_OF(cb, struct hts221_data, gpio_cb);
|
||||
struct hts221_data *data =
|
||||
CONTAINER_OF(cb, struct hts221_data, drdy_cb);
|
||||
|
||||
ARG_UNUSED(pins);
|
||||
|
||||
handle_drdy(drv_data);
|
||||
}
|
||||
|
||||
static void hts221_thread_cb(void *arg)
|
||||
{
|
||||
struct device *dev = arg;
|
||||
struct hts221_data *drv_data = dev->driver_data;
|
||||
|
||||
if (drv_data->data_ready_handler != NULL) {
|
||||
drv_data->data_ready_handler(dev,
|
||||
&drv_data->data_ready_trigger);
|
||||
}
|
||||
|
||||
setup_drdy(drv_data, true);
|
||||
handle_drdy(data->dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HTS221_TRIGGER_OWN_THREAD
|
||||
static void hts221_thread(int dev_ptr, int unused)
|
||||
{
|
||||
struct device *dev = INT_TO_POINTER(dev_ptr);
|
||||
struct hts221_data *drv_data = dev->driver_data;
|
||||
struct hts221_data *data = dev->driver_data;
|
||||
|
||||
ARG_UNUSED(unused);
|
||||
|
||||
while (1) {
|
||||
k_sem_take(&drv_data->gpio_sem, K_FOREVER);
|
||||
hts221_thread_cb(dev);
|
||||
k_sem_take(&data->drdy_sem, K_FOREVER);
|
||||
process_drdy(dev);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -110,59 +112,59 @@ static void hts221_thread(int dev_ptr, int unused)
|
|||
#ifdef CONFIG_HTS221_TRIGGER_GLOBAL_THREAD
|
||||
static void hts221_work_cb(struct k_work *work)
|
||||
{
|
||||
struct hts221_data *drv_data =
|
||||
struct hts221_data *data =
|
||||
CONTAINER_OF(work, struct hts221_data, work);
|
||||
|
||||
hts221_thread_cb(drv_data->dev);
|
||||
process_drdy(data->dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
int hts221_init_interrupt(struct device *dev)
|
||||
{
|
||||
struct hts221_data *drv_data = dev->driver_data;
|
||||
struct hts221_data *data = dev->driver_data;
|
||||
const struct hts221_config *cfg = dev->config->config_info;
|
||||
|
||||
data->dev = dev;
|
||||
|
||||
/* setup data ready gpio interrupt */
|
||||
drv_data->gpio =
|
||||
device_get_binding(DT_INST_0_ST_HTS221_DRDY_GPIOS_CONTROLLER);
|
||||
if (drv_data->gpio == NULL) {
|
||||
data->drdy_dev = device_get_binding(cfg->drdy_controller);
|
||||
if (data->drdy_dev == NULL) {
|
||||
LOG_ERR("Cannot get pointer to %s device.",
|
||||
DT_INST_0_ST_HTS221_DRDY_GPIOS_CONTROLLER);
|
||||
cfg->drdy_controller);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gpio_pin_configure(drv_data->gpio, DT_INST_0_ST_HTS221_DRDY_GPIOS_PIN,
|
||||
GPIO_INPUT | DT_INST_0_ST_HTS221_DRDY_GPIOS_FLAGS);
|
||||
gpio_pin_configure(data->drdy_dev, cfg->drdy_pin,
|
||||
GPIO_INPUT | cfg->drdy_flags);
|
||||
|
||||
gpio_init_callback(&drv_data->gpio_cb,
|
||||
hts221_gpio_callback,
|
||||
BIT(DT_INST_0_ST_HTS221_DRDY_GPIOS_PIN));
|
||||
gpio_init_callback(&data->drdy_cb, hts221_drdy_callback,
|
||||
BIT(cfg->drdy_pin));
|
||||
|
||||
if (gpio_add_callback(drv_data->gpio, &drv_data->gpio_cb) < 0) {
|
||||
if (gpio_add_callback(data->drdy_dev, &data->drdy_cb) < 0) {
|
||||
LOG_ERR("Could not set gpio callback.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* enable data-ready interrupt */
|
||||
if (i2c_reg_write_byte(drv_data->i2c, DT_INST_0_ST_HTS221_BASE_ADDRESS,
|
||||
if (i2c_reg_write_byte(data->i2c, cfg->i2c_addr,
|
||||
HTS221_REG_CTRL3, HTS221_DRDY_EN) < 0) {
|
||||
LOG_ERR("Could not enable data-ready interrupt.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_HTS221_TRIGGER_OWN_THREAD)
|
||||
k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX);
|
||||
k_sem_init(&data->drdy_sem, 0, UINT_MAX);
|
||||
|
||||
k_thread_create(&drv_data->thread, drv_data->thread_stack,
|
||||
k_thread_create(&data->thread, data->thread_stack,
|
||||
CONFIG_HTS221_THREAD_STACK_SIZE,
|
||||
(k_thread_entry_t)hts221_thread, dev,
|
||||
0, NULL, K_PRIO_COOP(CONFIG_HTS221_THREAD_PRIORITY),
|
||||
0, K_NO_WAIT);
|
||||
#elif defined(CONFIG_HTS221_TRIGGER_GLOBAL_THREAD)
|
||||
drv_data->work.handler = hts221_work_cb;
|
||||
drv_data->dev = dev;
|
||||
data->work.handler = hts221_work_cb;
|
||||
#endif
|
||||
|
||||
setup_drdy(drv_data, true);
|
||||
setup_drdy(dev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue