Message ID | 20240828205128.92145-7-vassilisamir@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | pressure: bmp280: Minor cleanup and interrupt support | expand |
On Wed, Aug 28, 2024 at 10:51:26PM +0200, Vasileios Amoiridis wrote: > The BMP3xx and BMP5xx sensors have an interrupt pin which can be used as > a trigger for when there are data ready in the sensor for pick up. > > This use case is used along with NORMAL_MODE in the sensor, which allows > the sensor to do consecutive measurements depending on the ODR rate value. > > The trigger pin can be configured to be open-drain or push-pull and either > rising or falling edge. > > No support is added yet for interrupts for FIFO, WATERMARK and out of range > values. > Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com> > --- > drivers/iio/pressure/bmp280-core.c | 231 ++++++++++++++++++++++++++++- > drivers/iio/pressure/bmp280.h | 21 +++ > 2 files changed, 250 insertions(+), 2 deletions(-) ... > +static int __bmp280_trigger_probe(struct iio_dev *indio_dev, > + const struct iio_trigger_ops *trigger_ops, > + int (*int_config)(struct bmp280_data *data), > + irq_handler_t irq_thread_handler) > +{ > + struct bmp280_data *data = iio_priv(indio_dev); With struct device *dev = data->dev; you may shorten some lines below and collapse a few. > + struct fwnode_handle *fwnode; > + int ret, irq, irq_type; Why irq_type is signed? Also try to make that returned variable is closer to the end of the definition block. And it might be worth to follow reversed xmas tree order (longer lines first). > + struct irq_data *desc; > + > + irq = fwnode_irq_get(dev_fwnode(data->dev), 0); > + if (irq < 0) > + return dev_err_probe(data->dev, irq, "No interrupt found.\n"); > + > + desc = irq_get_irq_data(irq); > + irq_type = irqd_get_trigger_type(desc); So, altogether it may be written as irq_type = irqd_get_trigger_type(irq_get_irq_data(irq)); And looking further, we have a helper for that: irq_get_trigger_type(). Why not use it? > + switch (irq_type) { > + case IRQF_TRIGGER_RISING: > + data->trig_active_high = true; > + break; > + case IRQF_TRIGGER_FALLING: > + data->trig_active_high = false; > + break; > + default: > + return dev_err_probe(data->dev, -EINVAL, > + "Invalid interrupt type specified.\n"); > + } > + > + data->trig_open_drain = > + fwnode_property_read_bool(fwnode, "int-open-drain"); > + > + ret = int_config(data); > + if (ret) > + return ret; > + > + data->trig = devm_iio_trigger_alloc(data->dev, "%s-dev%d", > + indio_dev->name, > + iio_device_id(indio_dev)); > + if (!data->trig) > + return -ENOMEM; > + > + data->trig->ops = trigger_ops; > + iio_trigger_set_drvdata(data->trig, data); > + > + ret = devm_request_threaded_irq(data->dev, irq, NULL, > + irq_thread_handler, IRQF_ONESHOT, > + indio_dev->name, indio_dev); > + if (ret) > + return dev_err_probe(data->dev, ret, "request irq failed.\n"); > + > + ret = devm_iio_trigger_register(data->dev, data->trig); > + if (ret) > + return dev_err_probe(data->dev, ret, > + "iio trigger register failed.\n"); > + > + indio_dev->trig = iio_trigger_get(data->trig); > + > + return 0; > +} ... > +static int bmp380_int_config(struct bmp280_data *data) > +{ > + int pin_drive_cfg = FIELD_PREP(BMP380_INT_CTRL_OPEN_DRAIN, > + data->trig_open_drain); > + int pin_level_cfg = FIELD_PREP(BMP380_INT_CTRL_LEVEL, > + data->trig_active_high); > + int ret, int_cfg = pin_drive_cfg | pin_level_cfg; > + > + ret = regmap_update_bits(data->regmap, BMP380_REG_INT_CONTROL, > + BMP380_INT_CTRL_SETTINGS_MASK, int_cfg); > + if (ret) { > + dev_err(data->dev, "Could not set interrupt settings\n"); > + return ret; > + } > + > + return ret; One of them is redundant or the last one should be return 0, but why not just leave one of them? > +} ... > +static int bmp580_int_config(struct bmp280_data *data) > +{ > + int ret, int_cfg = FIELD_PREP(BMP580_INT_CONFIG_OPEN_DRAIN, > + data->trig_open_drain) | > + FIELD_PREP(BMP580_INT_CONFIG_LEVEL, > + data->trig_active_high); > + > + ret = regmap_update_bits(data->regmap, BMP580_REG_INT_CONFIG, > + BMP580_INT_CONFIG_MASK, int_cfg); > + if (ret) { > + dev_err(data->dev, "Could not set interrupt settings\n"); > + return ret; > + } > + > + ret = regmap_set_bits(data->regmap, BMP580_REG_INT_SOURCE, > + BMP580_INT_SOURCE_DRDY); > + if (ret) { > + dev_err(data->dev, "Could not set interrupt source\n"); > + return ret; > + } > + > + return 0; So far you have three different styles in the same patch for this! Choose one and be consistent with it. > +} ... > + int (*trigger_probe)(struct iio_dev *indio_dev); > irqreturn_t (*trigger_handler)(int irq, void *p); Yeah, at some point this can be changed to irq_handler_t trigger_handler;
On Thu, Aug 29, 2024 at 03:40:34PM +0300, Andy Shevchenko wrote: > On Wed, Aug 28, 2024 at 10:51:26PM +0200, Vasileios Amoiridis wrote: > > The BMP3xx and BMP5xx sensors have an interrupt pin which can be used as > > a trigger for when there are data ready in the sensor for pick up. > > > > This use case is used along with NORMAL_MODE in the sensor, which allows > > the sensor to do consecutive measurements depending on the ODR rate value. > > > > The trigger pin can be configured to be open-drain or push-pull and either > > rising or falling edge. > > > > No support is added yet for interrupts for FIFO, WATERMARK and out of range > > values. > > > Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com> > > --- > > drivers/iio/pressure/bmp280-core.c | 231 ++++++++++++++++++++++++++++- > > drivers/iio/pressure/bmp280.h | 21 +++ > > 2 files changed, 250 insertions(+), 2 deletions(-) > > ... > > > +static int __bmp280_trigger_probe(struct iio_dev *indio_dev, > > + const struct iio_trigger_ops *trigger_ops, > > + int (*int_config)(struct bmp280_data *data), > > + irq_handler_t irq_thread_handler) > > +{ > > + struct bmp280_data *data = iio_priv(indio_dev); > > With > > struct device *dev = data->dev; > > you may shorten some lines below and collapse a few. > ACK. > > + struct fwnode_handle *fwnode; > > + int ret, irq, irq_type; > > Why irq_type is signed? > True, this can be made u32. > Also try to make that returned variable is closer to the end of the definition > block. And it might be worth to follow reversed xmas tree order (longer lines > first). > > > + struct irq_data *desc; > > + > > + irq = fwnode_irq_get(dev_fwnode(data->dev), 0); > > + if (irq < 0) > > + return dev_err_probe(data->dev, irq, "No interrupt found.\n"); > > + > > + desc = irq_get_irq_data(irq); > > + irq_type = irqd_get_trigger_type(desc); > > So, altogether it may be written as > > irq_type = irqd_get_trigger_type(irq_get_irq_data(irq)); > > And looking further, we have a helper for that: > irq_get_trigger_type(). Why not use it? > I was not aware of that, I can definitely change it. > > + switch (irq_type) { > > + case IRQF_TRIGGER_RISING: > > + data->trig_active_high = true; > > + break; > > + case IRQF_TRIGGER_FALLING: > > + data->trig_active_high = false; > > + break; > > + default: > > + return dev_err_probe(data->dev, -EINVAL, > > + "Invalid interrupt type specified.\n"); > > + } > > + > > + data->trig_open_drain = > > + fwnode_property_read_bool(fwnode, "int-open-drain"); > > + > > + ret = int_config(data); > > + if (ret) > > + return ret; > > + > > + data->trig = devm_iio_trigger_alloc(data->dev, "%s-dev%d", > > + indio_dev->name, > > + iio_device_id(indio_dev)); > > + if (!data->trig) > > + return -ENOMEM; > > + > > + data->trig->ops = trigger_ops; > > + iio_trigger_set_drvdata(data->trig, data); > > + > > + ret = devm_request_threaded_irq(data->dev, irq, NULL, > > + irq_thread_handler, IRQF_ONESHOT, > > + indio_dev->name, indio_dev); > > + if (ret) > > + return dev_err_probe(data->dev, ret, "request irq failed.\n"); > > + > > + ret = devm_iio_trigger_register(data->dev, data->trig); > > + if (ret) > > + return dev_err_probe(data->dev, ret, > > + "iio trigger register failed.\n"); > > + > > + indio_dev->trig = iio_trigger_get(data->trig); > > + > > + return 0; > > +} > > ... > > > +static int bmp380_int_config(struct bmp280_data *data) > > +{ > > + int pin_drive_cfg = FIELD_PREP(BMP380_INT_CTRL_OPEN_DRAIN, > > + data->trig_open_drain); > > + int pin_level_cfg = FIELD_PREP(BMP380_INT_CTRL_LEVEL, > > + data->trig_active_high); > > + int ret, int_cfg = pin_drive_cfg | pin_level_cfg; > > + > > + ret = regmap_update_bits(data->regmap, BMP380_REG_INT_CONTROL, > > + BMP380_INT_CTRL_SETTINGS_MASK, int_cfg); > > + if (ret) { > > + dev_err(data->dev, "Could not set interrupt settings\n"); > > > + return ret; > > + } > > + > > + return ret; > > One of them is redundant or the last one should be return 0, but why not just > leave one of them? > I can just leave one of them, true! > > +} > > ... > > > +static int bmp580_int_config(struct bmp280_data *data) > > +{ > > + int ret, int_cfg = FIELD_PREP(BMP580_INT_CONFIG_OPEN_DRAIN, > > + data->trig_open_drain) | > > + FIELD_PREP(BMP580_INT_CONFIG_LEVEL, > > + data->trig_active_high); > > + > > + ret = regmap_update_bits(data->regmap, BMP580_REG_INT_CONFIG, > > + BMP580_INT_CONFIG_MASK, int_cfg); > > + if (ret) { > > + dev_err(data->dev, "Could not set interrupt settings\n"); > > + return ret; > > + } > > + > > + ret = regmap_set_bits(data->regmap, BMP580_REG_INT_SOURCE, > > + BMP580_INT_SOURCE_DRDY); > > + if (ret) { > > + dev_err(data->dev, "Could not set interrupt source\n"); > > + return ret; > > + } > > + > > + return 0; > > So far you have three different styles in the same patch for this! > Choose one and be consistent with it. > > > +} > > ... > > > + int (*trigger_probe)(struct iio_dev *indio_dev); > > irqreturn_t (*trigger_handler)(int irq, void *p); > > Yeah, at some point this can be changed to > > irq_handler_t trigger_handler; > I can definitely try that in a separate patch, thanks for pointing all these out! Cheers, Vasilis > -- > With Best Regards, > Andy Shevchenko > >
On Thu, 29 Aug 2024 21:19:57 +0200 Vasileios Amoiridis <vassilisamir@gmail.com> wrote: > On Thu, Aug 29, 2024 at 03:40:34PM +0300, Andy Shevchenko wrote: > > On Wed, Aug 28, 2024 at 10:51:26PM +0200, Vasileios Amoiridis wrote: > > > The BMP3xx and BMP5xx sensors have an interrupt pin which can be used as > > > a trigger for when there are data ready in the sensor for pick up. > > > > > > This use case is used along with NORMAL_MODE in the sensor, which allows > > > the sensor to do consecutive measurements depending on the ODR rate value. > > > > > > The trigger pin can be configured to be open-drain or push-pull and either > > > rising or falling edge. > > > > > > No support is added yet for interrupts for FIFO, WATERMARK and out of range > > > values. > > > > > Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com> > > > --- > > > drivers/iio/pressure/bmp280-core.c | 231 ++++++++++++++++++++++++++++- > > > drivers/iio/pressure/bmp280.h | 21 +++ > > > 2 files changed, 250 insertions(+), 2 deletions(-) > > > > ... > > > > > +static int __bmp280_trigger_probe(struct iio_dev *indio_dev, > > > + const struct iio_trigger_ops *trigger_ops, > > > + int (*int_config)(struct bmp280_data *data), > > > + irq_handler_t irq_thread_handler) > > > +{ > > > + struct bmp280_data *data = iio_priv(indio_dev); > > > > With > > > > struct device *dev = data->dev; > > > > you may shorten some lines below and collapse a few. > > > > ACK. > > > > + struct fwnode_handle *fwnode; > > > + int ret, irq, irq_type; > > > > Why irq_type is signed? > > > > True, this can be made u32. > > > Also try to make that returned variable is closer to the end of the definition > > block. And it might be worth to follow reversed xmas tree order (longer lines > > first). > > > > > + struct irq_data *desc; > > > + > > > + irq = fwnode_irq_get(dev_fwnode(data->dev), 0); > > > + if (irq < 0) > > > + return dev_err_probe(data->dev, irq, "No interrupt found.\n"); > > > + > > > + desc = irq_get_irq_data(irq); > > > + irq_type = irqd_get_trigger_type(desc); > > > > So, altogether it may be written as > > > > irq_type = irqd_get_trigger_type(irq_get_irq_data(irq)); > > > > And looking further, we have a helper for that: > > irq_get_trigger_type(). Why not use it? > > > > I was not aware of that, I can definitely change it. Nice. A quick grep suggests a bunch of other places where this cleanup applies. Maybe I'll do it this weekend, but if not patches welcome ;) Jonathan
diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index e716bcb1dc96..c37c56446183 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -42,12 +42,14 @@ #include <linux/module.h> #include <linux/nvmem-provider.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/random.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/iio/buffer.h> #include <linux/iio/iio.h> +#include <linux/iio/trigger.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> @@ -1282,6 +1284,66 @@ static irqreturn_t bme280_trigger_handler(int irq, void *p) return IRQ_HANDLED; } +static int __bmp280_trigger_probe(struct iio_dev *indio_dev, + const struct iio_trigger_ops *trigger_ops, + int (*int_config)(struct bmp280_data *data), + irq_handler_t irq_thread_handler) +{ + struct bmp280_data *data = iio_priv(indio_dev); + struct fwnode_handle *fwnode; + int ret, irq, irq_type; + struct irq_data *desc; + + irq = fwnode_irq_get(dev_fwnode(data->dev), 0); + if (irq < 0) + return dev_err_probe(data->dev, irq, "No interrupt found.\n"); + + desc = irq_get_irq_data(irq); + irq_type = irqd_get_trigger_type(desc); + switch (irq_type) { + case IRQF_TRIGGER_RISING: + data->trig_active_high = true; + break; + case IRQF_TRIGGER_FALLING: + data->trig_active_high = false; + break; + default: + return dev_err_probe(data->dev, -EINVAL, + "Invalid interrupt type specified.\n"); + } + + data->trig_open_drain = + fwnode_property_read_bool(fwnode, "int-open-drain"); + + ret = int_config(data); + if (ret) + return ret; + + data->trig = devm_iio_trigger_alloc(data->dev, "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!data->trig) + return -ENOMEM; + + data->trig->ops = trigger_ops; + iio_trigger_set_drvdata(data->trig, data); + + ret = devm_request_threaded_irq(data->dev, irq, NULL, + irq_thread_handler, IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) + return dev_err_probe(data->dev, ret, "request irq failed.\n"); + + ret = devm_iio_trigger_register(data->dev, data->trig); + if (ret) + return dev_err_probe(data->dev, ret, + "iio trigger register failed.\n"); + + indio_dev->trig = iio_trigger_get(data->trig); + + return 0; +} + static const u8 bme280_chip_ids[] = { BME280_CHIP_ID }; static const int bme280_humid_coeffs[] = { 1000, 1024 }; @@ -1785,6 +1847,83 @@ static int bmp380_chip_config(struct bmp280_data *data) return 0; } +static void bmp380_trigger_reenable(struct iio_trigger *trig) +{ + struct bmp280_data *data = iio_trigger_get_drvdata(trig); + unsigned int tmp; + int ret; + + ret = regmap_read(data->regmap, BMP380_REG_INT_STATUS, &tmp); + if (ret) + dev_err(data->dev, "Failed to reset interrupt\n"); +} + +static int bmp380_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct bmp280_data *data = iio_trigger_get_drvdata(trig); + int ret; + + guard(mutex)(&data->lock); + + ret = regmap_update_bits(data->regmap, BMP380_REG_INT_CONTROL, + BMP380_INT_CTRL_DRDY_EN, + FIELD_PREP(BMP380_INT_CTRL_DRDY_EN, !!state)); + if (ret) + dev_err(data->dev, + "Could not %s interrupt\n", str_enable_disable(state)); + return ret; +} + +static const struct iio_trigger_ops bmp380_trigger_ops = { + .set_trigger_state = &bmp380_data_rdy_trigger_set_state, + .reenable = &bmp380_trigger_reenable, +}; + +static int bmp380_int_config(struct bmp280_data *data) +{ + int pin_drive_cfg = FIELD_PREP(BMP380_INT_CTRL_OPEN_DRAIN, + data->trig_open_drain); + int pin_level_cfg = FIELD_PREP(BMP380_INT_CTRL_LEVEL, + data->trig_active_high); + int ret, int_cfg = pin_drive_cfg | pin_level_cfg; + + ret = regmap_update_bits(data->regmap, BMP380_REG_INT_CONTROL, + BMP380_INT_CTRL_SETTINGS_MASK, int_cfg); + if (ret) { + dev_err(data->dev, "Could not set interrupt settings\n"); + return ret; + } + + return ret; +} + +static irqreturn_t bmp380_irq_thread_handler(int irq, void *p) +{ + struct iio_dev *indio_dev = p; + struct bmp280_data *data = iio_priv(indio_dev); + unsigned int int_ctrl; + int ret; + + scoped_guard(mutex, &data->lock) { + ret = regmap_read(data->regmap, BMP380_REG_INT_STATUS, &int_ctrl); + if (ret) + return IRQ_NONE; + } + + if (FIELD_GET(BMP380_INT_STATUS_DRDY, int_ctrl)) + iio_trigger_poll_nested(data->trig); + + return IRQ_HANDLED; +} + +static int bmp380_trigger_probe(struct iio_dev *indio_dev) +{ + return __bmp280_trigger_probe(indio_dev, &bmp380_trigger_ops, + bmp380_int_config, + bmp380_irq_thread_handler); +} + static irqreturn_t bmp380_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -1879,6 +2018,7 @@ const struct bmp280_chip_info bmp380_chip_info = { .wait_conv = bmp380_wait_conv, .preinit = bmp380_preinit, + .trigger_probe = bmp380_trigger_probe, .trigger_handler = bmp380_trigger_handler, }; EXPORT_SYMBOL_NS(bmp380_chip_info, IIO_BMP280); @@ -2421,6 +2561,89 @@ static int bmp580_chip_config(struct bmp280_data *data) return 0; } +static void bmp580_trigger_reenable(struct iio_trigger *trig) +{ + struct bmp280_data *data = iio_trigger_get_drvdata(trig); + unsigned int tmp; + int ret; + + ret = regmap_read(data->regmap, BMP580_REG_INT_STATUS, &tmp); + if (ret) + dev_err(data->dev, "Failed to reset interrupt\n"); +} + +static int bmp580_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct bmp280_data *data = iio_trigger_get_drvdata(trig); + int ret; + + guard(mutex)(&data->lock); + + ret = regmap_update_bits(data->regmap, BMP580_REG_INT_CONFIG, + BMP580_INT_CONFIG_INT_EN, + FIELD_PREP(BMP580_INT_CONFIG_INT_EN, !!state)); + if (ret) + dev_err(data->dev, + "Could not %s interrupt\n", str_enable_disable(state)); + return ret; +} + +static const struct iio_trigger_ops bmp580_trigger_ops = { + .set_trigger_state = &bmp580_data_rdy_trigger_set_state, + .reenable = &bmp580_trigger_reenable, +}; + +static int bmp580_int_config(struct bmp280_data *data) +{ + int ret, int_cfg = FIELD_PREP(BMP580_INT_CONFIG_OPEN_DRAIN, + data->trig_open_drain) | + FIELD_PREP(BMP580_INT_CONFIG_LEVEL, + data->trig_active_high); + + ret = regmap_update_bits(data->regmap, BMP580_REG_INT_CONFIG, + BMP580_INT_CONFIG_MASK, int_cfg); + if (ret) { + dev_err(data->dev, "Could not set interrupt settings\n"); + return ret; + } + + ret = regmap_set_bits(data->regmap, BMP580_REG_INT_SOURCE, + BMP580_INT_SOURCE_DRDY); + if (ret) { + dev_err(data->dev, "Could not set interrupt source\n"); + return ret; + } + + return 0; +} + +static irqreturn_t bmp580_irq_thread_handler(int irq, void *p) +{ + struct iio_dev *indio_dev = p; + struct bmp280_data *data = iio_priv(indio_dev); + unsigned int int_ctrl; + int ret; + + scoped_guard(mutex, &data->lock) { + ret = regmap_read(data->regmap, BMP580_REG_INT_STATUS, &int_ctrl); + if (ret) + return IRQ_NONE; + } + + if (FIELD_GET(BMP580_INT_STATUS_DRDY_MASK, int_ctrl)) + iio_trigger_poll_nested(data->trig); + + return IRQ_HANDLED; +} + +static int bmp580_trigger_probe(struct iio_dev *indio_dev) +{ + return __bmp280_trigger_probe(indio_dev, &bmp580_trigger_ops, + bmp580_int_config, + bmp580_irq_thread_handler); +} + static irqreturn_t bmp580_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -2497,6 +2720,7 @@ const struct bmp280_chip_info bmp580_chip_info = { .wait_conv = bmp580_wait_conv, .preinit = bmp580_preinit, + .trigger_probe = bmp580_trigger_probe, .trigger_handler = bmp580_trigger_handler, }; EXPORT_SYMBOL_NS(bmp580_chip_info, IIO_BMP280); @@ -3044,8 +3268,11 @@ int bmp280_common_probe(struct device *dev, * however as it happens, the BMP085 shares the chip ID of BMP180 * so we look for an IRQ if we have that. */ - if (irq > 0 && (chip_id == BMP180_CHIP_ID)) { - ret = bmp085_fetch_eoc_irq(dev, name, irq, data); + if (irq > 0) { + if (chip_id == BMP180_CHIP_ID) + ret = bmp085_fetch_eoc_irq(dev, name, irq, data); + if (data->chip_info->trigger_probe) + ret = data->chip_info->trigger_probe(indio_dev); if (ret) return ret; } diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h index c9840b8d58b0..0c32b6430677 100644 --- a/drivers/iio/pressure/bmp280.h +++ b/drivers/iio/pressure/bmp280.h @@ -55,8 +55,17 @@ #define BMP580_CMD_NVM_WRITE_SEQ_1 0xA0 #define BMP580_CMD_SOFT_RESET 0xB6 +#define BMP580_INT_STATUS_DRDY_MASK BIT(0) #define BMP580_INT_STATUS_POR_MASK BIT(4) +#define BMP580_INT_SOURCE_DRDY BIT(0) + +#define BMP580_INT_CONFIG_MASK GENMASK(3, 0) +#define BMP580_INT_CONFIG_LATCH BIT(0) +#define BMP580_INT_CONFIG_LEVEL BIT(1) +#define BMP580_INT_CONFIG_OPEN_DRAIN BIT(2) +#define BMP580_INT_CONFIG_INT_EN BIT(3) + #define BMP580_STATUS_CORE_RDY_MASK BIT(0) #define BMP580_STATUS_NVM_RDY_MASK BIT(1) #define BMP580_STATUS_NVM_ERR_MASK BIT(2) @@ -175,6 +184,14 @@ #define BMP380_TEMP_MEAS_OFFSET 163 #define BMP380_PRESS_MEAS_OFFSET 392 +#define BMP380_INT_STATUS_DRDY BIT(3) + +#define BMP380_INT_CTRL_SETTINGS_MASK GENMASK(2, 0) +#define BMP380_INT_CTRL_OPEN_DRAIN BIT(0) +#define BMP380_INT_CTRL_LEVEL BIT(1) +#define BMP380_INT_CTRL_LATCH BIT(2) +#define BMP380_INT_CTRL_DRDY_EN BIT(6) + #define BMP380_MIN_TEMP -4000 #define BMP380_MAX_TEMP 8500 #define BMP380_MIN_PRES 3000000 @@ -406,6 +423,9 @@ struct bmp280_data { struct regmap *regmap; struct completion done; bool use_eoc; + bool trig_open_drain; + bool trig_active_high; + struct iio_trigger *trig; const struct bmp280_chip_info *chip_info; union { struct bmp180_calib bmp180; @@ -510,6 +530,7 @@ struct bmp280_chip_info { int (*set_mode)(struct bmp280_data *data, enum bmp280_op_mode mode); int (*wait_conv)(struct bmp280_data *data); + int (*trigger_probe)(struct iio_dev *indio_dev); irqreturn_t (*trigger_handler)(int irq, void *p); };
The BMP3xx and BMP5xx sensors have an interrupt pin which can be used as a trigger for when there are data ready in the sensor for pick up. This use case is used along with NORMAL_MODE in the sensor, which allows the sensor to do consecutive measurements depending on the ODR rate value. The trigger pin can be configured to be open-drain or push-pull and either rising or falling edge. No support is added yet for interrupts for FIFO, WATERMARK and out of range values. Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com> --- drivers/iio/pressure/bmp280-core.c | 231 ++++++++++++++++++++++++++++- drivers/iio/pressure/bmp280.h | 21 +++ 2 files changed, 250 insertions(+), 2 deletions(-)