]> Git Repo - linux.git/blob - drivers/iio/imu/adis_trigger.c
Linux 6.14-rc3
[linux.git] / drivers / iio / imu / adis_trigger.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Common library for ADIS16XXX devices
4  *
5  * Copyright 2012 Analog Devices Inc.
6  *   Author: Lars-Peter Clausen <[email protected]>
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
18 static 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
25 static const struct iio_trigger_ops adis_trigger_ops = {
26         .set_trigger_state = &adis_data_rdy_trigger_set_state,
27 };
28
29 static 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 the
38          * rising edge or on the falling edge of the data ready pin.
39          * IMU devices with FIFO support have the watermark pin level driven
40          * either high or low when the FIFO is filled with the desired number
41          * of samples.
42          * It defaults to IRQF_TRIGGER_RISING for backward compatibility with
43          * 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 device
65  * @adis: The adis device
66  * @indio_dev: The IIO device
67  *
68  * Returns 0 on success or a negative error code
69  */
70 int 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         else
95                 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 }
105 EXPORT_SYMBOL_NS_GPL(devm_adis_probe_trigger, "IIO_ADISLIB");
106
This page took 0.035332 seconds and 4 git commands to generate.