]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iio: accel: bma220: add interrupt trigger
authorPetre Rodan <petre.rodan@subdimension.ro>
Sun, 5 Oct 2025 13:12:25 +0000 (16:12 +0300)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sun, 19 Oct 2025 10:59:20 +0000 (11:59 +0100)
Add interrupt trigger.

Signed-off-by: Petre Rodan <petre.rodan@subdimension.ro>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/accel/bma220_core.c

index 38a2f36783cd320fea57f1c9d4c0b2d64d2b798f..08c4dec67d5e183f3a97351bc982bf33a23ae1d1 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/iio/buffer.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
 
@@ -124,6 +125,7 @@ struct bma220_data {
        struct regmap *regmap;
        struct mutex lock;
        u8 range_idx;
+       struct iio_trigger *trig;
        struct {
                s8 chans[3];
                /* Ensure timestamp is naturally aligned. */
@@ -192,6 +194,22 @@ const struct regmap_config bma220_i2c_regmap_config = {
 };
 EXPORT_SYMBOL_NS_GPL(bma220_i2c_regmap_config, "IIO_BOSCH_BMA220");
 
+static int bma220_data_rdy_trigger_set_state(struct iio_trigger *trig,
+                                            bool state)
+{
+       struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+       struct bma220_data *data = iio_priv(indio_dev);
+
+       return regmap_update_bits(data->regmap, BMA220_REG_IE0,
+                                 BMA220_INT_EN_DRDY_MSK,
+                                 FIELD_PREP(BMA220_INT_EN_DRDY_MSK, state));
+}
+
+static const struct iio_trigger_ops bma220_trigger_ops = {
+       .set_trigger_state = &bma220_data_rdy_trigger_set_state,
+       .validate_device = &iio_trigger_validate_own_device,
+};
+
 static irqreturn_t bma220_trigger_handler(int irq, void *p)
 {
        int ret;
@@ -414,6 +432,23 @@ static void bma220_deinit(void *data_ptr)
                         ERR_PTR(ret));
 }
 
+static irqreturn_t bma220_irq_handler(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct bma220_data *data = iio_priv(indio_dev);
+       int ret;
+       unsigned int bma220_reg_if1;
+
+       ret = regmap_read(data->regmap, BMA220_REG_IF1, &bma220_reg_if1);
+       if (ret)
+               return IRQ_NONE;
+
+       if (FIELD_GET(BMA220_IF_DRDY, bma220_reg_if1))
+               iio_trigger_poll_nested(data->trig);
+
+       return IRQ_HANDLED;
+}
+
 int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq)
 {
        int ret;
@@ -442,6 +477,29 @@ int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq)
        indio_dev->num_channels = ARRAY_SIZE(bma220_channels);
        indio_dev->available_scan_masks = bma220_accel_scan_masks;
 
+       if (irq > 0) {
+               data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
+                                                   indio_dev->name,
+                                                   iio_device_id(indio_dev));
+               if (!data->trig)
+                       return -ENOMEM;
+
+               data->trig->ops = &bma220_trigger_ops;
+               iio_trigger_set_drvdata(data->trig, indio_dev);
+
+               ret = devm_iio_trigger_register(dev, data->trig);
+               if (ret)
+                       return dev_err_probe(dev, ret,
+                                            "iio trigger register fail\n");
+               indio_dev->trig = iio_trigger_get(data->trig);
+               ret = devm_request_threaded_irq(dev, irq, NULL,
+                                               &bma220_irq_handler, IRQF_ONESHOT,
+                                               indio_dev->name, indio_dev);
+               if (ret)
+                       return dev_err_probe(dev, ret,
+                                            "request irq %d failed\n", irq);
+       }
+
        ret = devm_add_action_or_reset(dev, bma220_deinit, data);
        if (ret)
                return ret;