Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / drivers / media / pci / mgb4 / mgb4_trigger.c
blob923650d53d4c82e87b542f87c3a0fbf6170dadc8
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) 2021-2023 Digiteq Automotive
4 * author: Martin Tuma <martin.tuma@digiteqautomotive.com>
6 * This module handles the IIO trigger device. The card has two signal inputs
7 * for event triggers that can be used to record events related to the video
8 * stream. A standard linux IIO device with triggered buffer capability is
9 * created and configured that can be used to fetch the events with the same
10 * clock source as the video frames.
13 #include <linux/iio/iio.h>
14 #include <linux/iio/buffer.h>
15 #include <linux/iio/trigger.h>
16 #include <linux/iio/trigger_consumer.h>
17 #include <linux/iio/triggered_buffer.h>
18 #include <linux/pci.h>
19 #include <linux/dma/amd_xdma.h>
20 #include "mgb4_core.h"
21 #include "mgb4_trigger.h"
23 struct trigger_data {
24 struct mgb4_dev *mgbdev;
25 struct iio_trigger *trig;
28 static int trigger_read_raw(struct iio_dev *indio_dev,
29 struct iio_chan_spec const *chan, int *val,
30 int *val2, long mask)
32 struct trigger_data *st = iio_priv(indio_dev);
34 switch (mask) {
35 case IIO_CHAN_INFO_RAW:
36 if (iio_buffer_enabled(indio_dev))
37 return -EBUSY;
38 *val = mgb4_read_reg(&st->mgbdev->video, 0xA0);
40 return IIO_VAL_INT;
43 return -EINVAL;
46 static int trigger_set_state(struct iio_trigger *trig, bool state)
48 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
49 struct trigger_data *st = iio_priv(indio_dev);
50 int irq = xdma_get_user_irq(st->mgbdev->xdev, 11);
52 if (state)
53 xdma_enable_user_irq(st->mgbdev->xdev, irq);
54 else
55 xdma_disable_user_irq(st->mgbdev->xdev, irq);
57 return 0;
60 static const struct iio_trigger_ops trigger_ops = {
61 .set_trigger_state = &trigger_set_state,
64 static const struct iio_info trigger_info = {
65 .read_raw = trigger_read_raw,
68 #define TRIGGER_CHANNEL(_si) { \
69 .type = IIO_ACTIVITY, \
70 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
71 .scan_index = _si, \
72 .scan_type = { \
73 .sign = 'u', \
74 .realbits = 32, \
75 .storagebits = 32, \
76 .shift = 0, \
77 .endianness = IIO_CPU \
78 }, \
81 static const struct iio_chan_spec trigger_channels[] = {
82 TRIGGER_CHANNEL(0),
83 IIO_CHAN_SOFT_TIMESTAMP(1),
86 static irqreturn_t trigger_handler(int irq, void *p)
88 struct iio_poll_func *pf = p;
89 struct iio_dev *indio_dev = pf->indio_dev;
90 struct trigger_data *st = iio_priv(indio_dev);
91 struct {
92 u32 data;
93 s64 ts __aligned(8);
94 } scan;
96 scan.data = mgb4_read_reg(&st->mgbdev->video, 0xA0);
97 mgb4_write_reg(&st->mgbdev->video, 0xA0, scan.data);
99 iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);
100 iio_trigger_notify_done(indio_dev->trig);
102 mgb4_write_reg(&st->mgbdev->video, 0xB4, 1U << 11);
104 return IRQ_HANDLED;
107 static int probe_trigger(struct iio_dev *indio_dev, int irq)
109 int ret;
110 struct trigger_data *st = iio_priv(indio_dev);
112 st->trig = iio_trigger_alloc(&st->mgbdev->pdev->dev, "%s-dev%d",
113 indio_dev->name, iio_device_id(indio_dev));
114 if (!st->trig)
115 return -ENOMEM;
117 ret = request_irq(irq, &iio_trigger_generic_data_rdy_poll, 0,
118 "mgb4-trigger", st->trig);
119 if (ret)
120 goto error_free_trig;
122 st->trig->ops = &trigger_ops;
123 iio_trigger_set_drvdata(st->trig, indio_dev);
124 ret = iio_trigger_register(st->trig);
125 if (ret)
126 goto error_free_irq;
128 indio_dev->trig = iio_trigger_get(st->trig);
130 return 0;
132 error_free_irq:
133 free_irq(irq, st->trig);
134 error_free_trig:
135 iio_trigger_free(st->trig);
137 return ret;
140 static void remove_trigger(struct iio_dev *indio_dev, int irq)
142 struct trigger_data *st = iio_priv(indio_dev);
144 iio_trigger_unregister(st->trig);
145 free_irq(irq, st->trig);
146 iio_trigger_free(st->trig);
149 struct iio_dev *mgb4_trigger_create(struct mgb4_dev *mgbdev)
151 struct iio_dev *indio_dev;
152 struct trigger_data *data;
153 struct pci_dev *pdev = mgbdev->pdev;
154 struct device *dev = &pdev->dev;
155 int rv, irq;
157 indio_dev = iio_device_alloc(dev, sizeof(*data));
158 if (!indio_dev)
159 return NULL;
161 indio_dev->info = &trigger_info;
162 indio_dev->name = "mgb4";
163 indio_dev->modes = INDIO_DIRECT_MODE;
164 indio_dev->channels = trigger_channels;
165 indio_dev->num_channels = ARRAY_SIZE(trigger_channels);
167 data = iio_priv(indio_dev);
168 data->mgbdev = mgbdev;
170 irq = xdma_get_user_irq(mgbdev->xdev, 11);
171 rv = probe_trigger(indio_dev, irq);
172 if (rv < 0) {
173 dev_err(dev, "iio triggered setup failed\n");
174 goto error_alloc;
176 rv = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
177 trigger_handler, NULL);
178 if (rv < 0) {
179 dev_err(dev, "iio triggered buffer setup failed\n");
180 goto error_trigger;
182 rv = iio_device_register(indio_dev);
183 if (rv < 0) {
184 dev_err(dev, "iio device register failed\n");
185 goto error_buffer;
188 return indio_dev;
190 error_buffer:
191 iio_triggered_buffer_cleanup(indio_dev);
192 error_trigger:
193 remove_trigger(indio_dev, irq);
194 error_alloc:
195 iio_device_free(indio_dev);
197 return NULL;
200 void mgb4_trigger_free(struct iio_dev *indio_dev)
202 struct trigger_data *st = iio_priv(indio_dev);
204 iio_device_unregister(indio_dev);
205 iio_triggered_buffer_cleanup(indio_dev);
206 remove_trigger(indio_dev, xdma_get_user_irq(st->mgbdev->xdev, 11));
207 iio_device_free(indio_dev);