107 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Common library for ADIS16XXX devices4 *5 * Copyright 2012 Analog Devices Inc.6 * Author: Lars-Peter Clausen <lars@metafoo.de>7 */8 9#include <linux/interrupt.h>10#include <linux/kernel.h>11#include <linux/spi/spi.h>12#include <linux/export.h>13 14#include <linux/iio/iio.h>15#include <linux/iio/trigger.h>16#include <linux/iio/imu/adis.h>17 18static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state)19{20 struct adis *adis = iio_trigger_get_drvdata(trig);21 22 return adis_enable_irq(adis, state);23}24 25static const struct iio_trigger_ops adis_trigger_ops = {26 .set_trigger_state = &adis_data_rdy_trigger_set_state,27};28 29static int adis_validate_irq_flag(struct adis *adis)30{31 unsigned long direction = adis->irq_flag & IRQF_TRIGGER_MASK;32 33 /* We cannot mask the interrupt so ensure it's not enabled at request */34 if (adis->data->unmasked_drdy)35 adis->irq_flag |= IRQF_NO_AUTOEN;36 /*37 * Typically adis devices without FIFO have data ready either on the38 * rising edge or on the falling edge of the data ready pin.39 * IMU devices with FIFO support have the watermark pin level driven40 * either high or low when the FIFO is filled with the desired number41 * of samples.42 * It defaults to IRQF_TRIGGER_RISING for backward compatibility with43 * devices that don't support changing the pin polarity.44 */45 if (direction == IRQF_TRIGGER_NONE) {46 adis->irq_flag |= IRQF_TRIGGER_RISING;47 return 0;48 } else if (direction != IRQF_TRIGGER_RISING &&49 direction != IRQF_TRIGGER_FALLING && !adis->data->has_fifo) {50 dev_err(&adis->spi->dev, "Invalid IRQ mask: %08lx\n",51 adis->irq_flag);52 return -EINVAL;53 } else if (direction != IRQF_TRIGGER_HIGH &&54 direction != IRQF_TRIGGER_LOW && adis->data->has_fifo) {55 dev_err(&adis->spi->dev, "Invalid IRQ mask: %08lx\n",56 adis->irq_flag);57 return -EINVAL;58 }59 60 return 0;61}62 63/**64 * devm_adis_probe_trigger() - Sets up trigger for a managed adis device65 * @adis: The adis device66 * @indio_dev: The IIO device67 *68 * Returns 0 on success or a negative error code69 */70int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)71{72 int ret;73 74 adis->trig = devm_iio_trigger_alloc(&adis->spi->dev, "%s-dev%d",75 indio_dev->name,76 iio_device_id(indio_dev));77 if (!adis->trig)78 return -ENOMEM;79 80 adis->trig->ops = &adis_trigger_ops;81 iio_trigger_set_drvdata(adis->trig, adis);82 83 ret = adis_validate_irq_flag(adis);84 if (ret)85 return ret;86 87 if (adis->data->has_fifo)88 ret = devm_request_threaded_irq(&adis->spi->dev, adis->spi->irq,89 NULL,90 &iio_trigger_generic_data_rdy_poll,91 adis->irq_flag | IRQF_ONESHOT,92 indio_dev->name,93 adis->trig);94 else95 ret = devm_request_irq(&adis->spi->dev, adis->spi->irq,96 &iio_trigger_generic_data_rdy_poll,97 adis->irq_flag,98 indio_dev->name,99 adis->trig);100 if (ret)101 return ret;102 103 return devm_iio_trigger_register(&adis->spi->dev, adis->trig);104}105EXPORT_SYMBOL_NS_GPL(devm_adis_probe_trigger, IIO_ADISLIB);106 107