Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Common library for ADIS16XXX devices
0004  *
0005  * Copyright 2012 Analog Devices Inc.
0006  *   Author: Lars-Peter Clausen <lars@metafoo.de>
0007  */
0008 
0009 #include <linux/interrupt.h>
0010 #include <linux/kernel.h>
0011 #include <linux/spi/spi.h>
0012 #include <linux/export.h>
0013 
0014 #include <linux/iio/iio.h>
0015 #include <linux/iio/trigger.h>
0016 #include <linux/iio/imu/adis.h>
0017 
0018 static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state)
0019 {
0020     struct adis *adis = iio_trigger_get_drvdata(trig);
0021 
0022     return adis_enable_irq(adis, state);
0023 }
0024 
0025 static const struct iio_trigger_ops adis_trigger_ops = {
0026     .set_trigger_state = &adis_data_rdy_trigger_set_state,
0027 };
0028 
0029 static int adis_validate_irq_flag(struct adis *adis)
0030 {
0031     unsigned long direction = adis->irq_flag & IRQF_TRIGGER_MASK;
0032 
0033     /* We cannot mask the interrupt so ensure it's not enabled at request */
0034     if (adis->data->unmasked_drdy)
0035         adis->irq_flag |= IRQF_NO_AUTOEN;
0036     /*
0037      * Typically this devices have data ready either on the rising edge or
0038      * on the falling edge of the data ready pin. This checks enforces that
0039      * one of those is set in the drivers... It defaults to
0040      * IRQF_TRIGGER_RISING for backward compatibility with devices that
0041      * don't support changing the pin polarity.
0042      */
0043     if (direction == IRQF_TRIGGER_NONE) {
0044         adis->irq_flag |= IRQF_TRIGGER_RISING;
0045         return 0;
0046     } else if (direction != IRQF_TRIGGER_RISING &&
0047            direction != IRQF_TRIGGER_FALLING) {
0048         dev_err(&adis->spi->dev, "Invalid IRQ mask: %08lx\n",
0049             adis->irq_flag);
0050         return -EINVAL;
0051     }
0052 
0053     return 0;
0054 }
0055 
0056 /**
0057  * devm_adis_probe_trigger() - Sets up trigger for a managed adis device
0058  * @adis: The adis device
0059  * @indio_dev: The IIO device
0060  *
0061  * Returns 0 on success or a negative error code
0062  */
0063 int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
0064 {
0065     int ret;
0066 
0067     adis->trig = devm_iio_trigger_alloc(&adis->spi->dev, "%s-dev%d",
0068                         indio_dev->name,
0069                         iio_device_id(indio_dev));
0070     if (!adis->trig)
0071         return -ENOMEM;
0072 
0073     adis->trig->ops = &adis_trigger_ops;
0074     iio_trigger_set_drvdata(adis->trig, adis);
0075 
0076     ret = adis_validate_irq_flag(adis);
0077     if (ret)
0078         return ret;
0079 
0080     ret = devm_request_irq(&adis->spi->dev, adis->spi->irq,
0081                    &iio_trigger_generic_data_rdy_poll,
0082                    adis->irq_flag,
0083                    indio_dev->name,
0084                    adis->trig);
0085     if (ret)
0086         return ret;
0087 
0088     return devm_iio_trigger_register(&adis->spi->dev, adis->trig);
0089 }
0090 EXPORT_SYMBOL_NS_GPL(devm_adis_probe_trigger, IIO_ADISLIB);
0091