iio: imu: adis: Add irq flag variable
authorNuno Sá <nuno.sa@analog.com>
Mon, 13 Apr 2020 08:24:41 +0000 (10:24 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sat, 25 Apr 2020 15:09:30 +0000 (16:09 +0100)
There are some ADIS devices that can configure the data ready pin
polarity. Hence, we cannot hardcode our IRQ mask as IRQF_TRIGGER_RISING
since we might want to have it as IRQF_TRIGGER_FALLING.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/imu/adis_trigger.c
include/linux/iio/imu/adis.h

index a36810e..8afe719 100644 (file)
@@ -34,6 +34,27 @@ static void adis_trigger_setup(struct adis *adis)
        iio_trigger_set_drvdata(adis->trig, adis);
 }
 
+static int adis_validate_irq_flag(struct adis *adis)
+{
+       /*
+        * Typically this devices have data ready either on the rising edge or
+        * on the falling edge of the data ready pin. This checks enforces that
+        * one of those is set in the drivers... It defaults to
+        * IRQF_TRIGGER_RISING for backward compatibility wiht devices that
+        * don't support changing the pin polarity.
+        */
+       if (!adis->irq_flag) {
+               adis->irq_flag = IRQF_TRIGGER_RISING;
+               return 0;
+       } else if (adis->irq_flag != IRQF_TRIGGER_RISING &&
+                  adis->irq_flag != IRQF_TRIGGER_FALLING) {
+               dev_err(&adis->spi->dev, "Invalid IRQ mask: %08lx\n",
+                       adis->irq_flag);
+               return -EINVAL;
+       }
+
+       return 0;
+}
 /**
  * adis_probe_trigger() - Sets up trigger for a adis device
  * @adis: The adis device
@@ -54,9 +75,13 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
 
        adis_trigger_setup(adis);
 
+       ret = adis_validate_irq_flag(adis);
+       if (ret)
+               return ret;
+
        ret = request_irq(adis->spi->irq,
                          &iio_trigger_generic_data_rdy_poll,
-                         IRQF_TRIGGER_RISING,
+                         adis->irq_flag,
                          indio_dev->name,
                          adis->trig);
        if (ret)
@@ -96,9 +121,13 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
 
        adis_trigger_setup(adis);
 
+       ret = adis_validate_irq_flag(adis);
+       if (ret)
+               return ret;
+
        ret = devm_request_irq(&adis->spi->dev, adis->spi->irq,
                               &iio_trigger_generic_data_rdy_poll,
-                              IRQF_TRIGGER_RISING,
+                              adis->irq_flag,
                               indio_dev->name,
                               adis->trig);
        if (ret)
index e70814d..70e4d1d 100644 (file)
@@ -87,6 +87,7 @@ struct adis_data {
  * @msg: SPI message object
  * @xfer: SPI transfer objects to be used for a @msg
  * @current_page: Some ADIS devices have registers, this selects current page
+ * @irq_flag: IRQ handling flags as passed to request_irq()
  * @buffer: Data buffer for information read from the device
  * @tx: DMA safe TX buffer for SPI transfers
  * @rx: DMA safe RX buffer for SPI transfers
@@ -113,6 +114,7 @@ struct adis {
        struct spi_message      msg;
        struct spi_transfer     *xfer;
        unsigned int            current_page;
+       unsigned long           irq_flag;
        void                    *buffer;
 
        uint8_t                 tx[10] ____cacheline_aligned;