diff options
Diffstat (limited to 'drivers/iio/adc')
-rw-r--r-- | drivers/iio/adc/max1027.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c index dbfff2ef2e65..3f4be6859e2d 100644 --- a/drivers/iio/adc/max1027.c +++ b/drivers/iio/adc/max1027.c @@ -271,15 +271,26 @@ struct max1027_state { struct iio_trigger *trig; __be16 *buffer; struct mutex lock; + struct completion complete; u8 reg ____cacheline_aligned; }; static int max1027_wait_eoc(struct iio_dev *indio_dev) { + struct max1027_state *st = iio_priv(indio_dev); unsigned int conversion_time = MAX1027_CONVERSION_UDELAY; + int ret; - usleep_range(conversion_time, conversion_time * 2); + if (st->spi->irq) { + ret = wait_for_completion_timeout(&st->complete, + msecs_to_jiffies(1000)); + reinit_completion(&st->complete); + if (!ret) + return ret; + } else { + usleep_range(conversion_time, conversion_time * 2); + } return 0; } @@ -474,6 +485,30 @@ static int max1027_read_scan(struct iio_dev *indio_dev) return 0; } +static irqreturn_t max1027_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct max1027_state *st = iio_priv(indio_dev); + + /* + * If buffers are disabled (raw read), we just need to unlock the + * waiters which will then handle the data. + * + * When using the internal trigger, we must hand-off the choice of the + * handler to the core which will then lookup through the interrupt tree + * for the right handler registered with iio_triggered_buffer_setup() + * to execute, as this trigger might very well be used in conjunction + * with another device. The core will then call the relevant handler to + * perform the data processing step. + */ + if (!iio_buffer_enabled(indio_dev)) + complete(&st->complete); + else + iio_trigger_poll(indio_dev->trig); + + return IRQ_HANDLED; +} + static irqreturn_t max1027_trigger_handler(int irq, void *private) { struct iio_poll_func *pf = private; @@ -518,6 +553,7 @@ static int max1027_probe(struct spi_device *spi) st->info = &max1027_chip_info_tbl[spi_get_device_id(spi)->driver_data]; mutex_init(&st->lock); + init_completion(&st->complete); indio_dev->name = spi_get_device_id(spi)->name; indio_dev->info = &max1027_info; @@ -561,10 +597,9 @@ static int max1027_probe(struct spi_device *spi) return ret; } - ret = devm_request_irq(&spi->dev, spi->irq, - iio_trigger_generic_data_rdy_poll, + ret = devm_request_irq(&spi->dev, spi->irq, max1027_handler, IRQF_TRIGGER_FALLING, - spi->dev.driver->name, st->trig); + spi->dev.driver->name, indio_dev); if (ret < 0) { dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n"); return ret; |