iio: adc: ad_sigma_delta: Add optional irq selection
authorDumitru Ceclan <mitrutzceclan@gmail.com>
Wed, 28 Feb 2024 11:06:19 +0000 (13:06 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Mon, 25 Mar 2024 20:10:11 +0000 (20:10 +0000)
Add optional irq_num attribute to ad_sigma_delta_info structure for
selecting the used interrupt line for ADC's conversion completion.

Signed-off-by: Dumitru Ceclan <mitrutzceclan@gmail.com>
Reviewed-by: Nuno Sa <nuno.sa@analog.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20240228110622.25114-2-mitrutzceclan@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ad_sigma_delta.c
include/linux/iio/adc/ad_sigma_delta.h

index a602429cdde4ef7c09cfdd7a4b64ab3f8e10d5ae..97a05f325df7cfac67a4bc060c158c4cdfd1fdb8 100644 (file)
@@ -222,11 +222,11 @@ int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
                goto out;
 
        sigma_delta->irq_dis = false;
-       enable_irq(sigma_delta->spi->irq);
+       enable_irq(sigma_delta->irq_line);
        timeout = wait_for_completion_timeout(&sigma_delta->completion, 2 * HZ);
        if (timeout == 0) {
                sigma_delta->irq_dis = true;
-               disable_irq_nosync(sigma_delta->spi->irq);
+               disable_irq_nosync(sigma_delta->irq_line);
                ret = -EIO;
        } else {
                ret = 0;
@@ -295,7 +295,7 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
        ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_SINGLE);
 
        sigma_delta->irq_dis = false;
-       enable_irq(sigma_delta->spi->irq);
+       enable_irq(sigma_delta->irq_line);
        ret = wait_for_completion_interruptible_timeout(
                        &sigma_delta->completion, HZ);
 
@@ -315,7 +315,7 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
 
 out:
        if (!sigma_delta->irq_dis) {
-               disable_irq_nosync(sigma_delta->spi->irq);
+               disable_irq_nosync(sigma_delta->irq_line);
                sigma_delta->irq_dis = true;
        }
 
@@ -396,7 +396,7 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
                goto err_unlock;
 
        sigma_delta->irq_dis = false;
-       enable_irq(sigma_delta->spi->irq);
+       enable_irq(sigma_delta->irq_line);
 
        return 0;
 
@@ -414,7 +414,7 @@ static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev)
        wait_for_completion_timeout(&sigma_delta->completion, HZ);
 
        if (!sigma_delta->irq_dis) {
-               disable_irq_nosync(sigma_delta->spi->irq);
+               disable_irq_nosync(sigma_delta->irq_line);
                sigma_delta->irq_dis = true;
        }
 
@@ -516,7 +516,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
 irq_handled:
        iio_trigger_notify_done(indio_dev->trig);
        sigma_delta->irq_dis = false;
-       enable_irq(sigma_delta->spi->irq);
+       enable_irq(sigma_delta->irq_line);
 
        return IRQ_HANDLED;
 }
@@ -587,13 +587,13 @@ static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_de
        sigma_delta->irq_dis = true;
 
        /* the IRQ core clears IRQ_DISABLE_UNLAZY flag when freeing an IRQ */
-       irq_set_status_flags(sigma_delta->spi->irq, IRQ_DISABLE_UNLAZY);
+       irq_set_status_flags(sigma_delta->irq_line, IRQ_DISABLE_UNLAZY);
 
        /* Allow overwriting the flags from firmware */
        if (!irq_flags)
                irq_flags = sigma_delta->info->irq_flags;
 
-       ret = devm_request_irq(dev, sigma_delta->spi->irq,
+       ret = devm_request_irq(dev, sigma_delta->irq_line,
                               ad_sd_data_rdy_trig_poll,
                               irq_flags | IRQF_NO_AUTOEN,
                               indio_dev->name,
@@ -673,6 +673,11 @@ int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
                }
        }
 
+       if (info->irq_line)
+               sigma_delta->irq_line = info->irq_line;
+       else
+               sigma_delta->irq_line = spi->irq;
+
        iio_device_set_drvdata(indio_dev, sigma_delta);
 
        return 0;
index 719cf9cc6e1ac4db6abbd1171b1590716dc50dc9..383614ebd760fb8e3acc8c6124eb5b1b981ab4e4 100644 (file)
@@ -48,6 +48,7 @@ struct iio_dev;
  *   be used.
  * @irq_flags: flags for the interrupt used by the triggered buffer
  * @num_slots: Number of sequencer slots
+ * @irq_line: IRQ for reading conversions. If 0, spi->irq will be used
  */
 struct ad_sigma_delta_info {
        int (*set_channel)(struct ad_sigma_delta *, unsigned int channel);
@@ -62,6 +63,7 @@ struct ad_sigma_delta_info {
        unsigned int data_reg;
        unsigned long irq_flags;
        unsigned int num_slots;
+       int irq_line;
 };
 
 /**
@@ -89,6 +91,7 @@ struct ad_sigma_delta {
        unsigned int            active_slots;
        unsigned int            current_slot;
        unsigned int            num_slots;
+       int             irq_line;
        bool                    status_appended;
        /* map slots to channels in order to know what to expect from devices */
        unsigned int            *slots;