brintos

brintos / linux-shallow public Read only

0
0
Text · 3.0 KiB · a8740b0 Raw
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