diff options
Diffstat (limited to 'drivers/iio/imu/adis_trigger.c')
| -rw-r--r-- | drivers/iio/imu/adis_trigger.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c index 48eedc29b28a..d76e13cbac68 100644 --- a/drivers/iio/imu/adis_trigger.c +++ b/drivers/iio/imu/adis_trigger.c @@ -15,8 +15,7 @@ #include <linux/iio/trigger.h> #include <linux/iio/imu/adis.h> -static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) +static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state) { struct adis *adis = iio_trigger_get_drvdata(trig); @@ -30,18 +29,29 @@ static const struct iio_trigger_ops adis_trigger_ops = { static int adis_validate_irq_flag(struct adis *adis) { unsigned long direction = adis->irq_flag & IRQF_TRIGGER_MASK; + + /* We cannot mask the interrupt so ensure it's not enabled at request */ + if (adis->data->unmasked_drdy) + adis->irq_flag |= IRQF_NO_AUTOEN; /* - * 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 with devices that - * don't support changing the pin polarity. + * Typically adis devices without FIFO have data ready either on the + * rising edge or on the falling edge of the data ready pin. + * IMU devices with FIFO support have the watermark pin level driven + * either high or low when the FIFO is filled with the desired number + * of samples. + * It defaults to IRQF_TRIGGER_RISING for backward compatibility with + * devices that don't support changing the pin polarity. */ if (direction == IRQF_TRIGGER_NONE) { adis->irq_flag |= IRQF_TRIGGER_RISING; return 0; } else if (direction != IRQF_TRIGGER_RISING && - direction != IRQF_TRIGGER_FALLING) { + direction != IRQF_TRIGGER_FALLING && !adis->data->has_fifo) { + dev_err(&adis->spi->dev, "Invalid IRQ mask: %08lx\n", + adis->irq_flag); + return -EINVAL; + } else if (direction != IRQF_TRIGGER_HIGH && + direction != IRQF_TRIGGER_LOW && adis->data->has_fifo) { dev_err(&adis->spi->dev, "Invalid IRQ mask: %08lx\n", adis->irq_flag); return -EINVAL; @@ -74,15 +84,23 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) if (ret) return ret; - ret = devm_request_irq(&adis->spi->dev, adis->spi->irq, - &iio_trigger_generic_data_rdy_poll, - adis->irq_flag, - indio_dev->name, - adis->trig); + if (adis->data->has_fifo) + ret = devm_request_threaded_irq(&adis->spi->dev, adis->spi->irq, + NULL, + &iio_trigger_generic_data_rdy_poll, + adis->irq_flag | IRQF_ONESHOT, + indio_dev->name, + adis->trig); + else + ret = devm_request_irq(&adis->spi->dev, adis->spi->irq, + &iio_trigger_generic_data_rdy_poll, + adis->irq_flag, + indio_dev->name, + adis->trig); if (ret) return ret; return devm_iio_trigger_register(&adis->spi->dev, adis->trig); } -EXPORT_SYMBOL_GPL(devm_adis_probe_trigger); +EXPORT_SYMBOL_NS_GPL(devm_adis_probe_trigger, "IIO_ADISLIB"); |
