1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2021-2023 Digiteq Automotive 4 * author: Martin Tuma <martin.tuma@digiteqautomotive.com> 5 * 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. 11 */ 12 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 <linux/types.h> 21 #include "mgb4_core.h" 22 #include "mgb4_trigger.h" 23 24 struct trigger_data { 25 struct mgb4_dev *mgbdev; 26 struct iio_trigger *trig; 27 }; 28 29 static int trigger_read_raw(struct iio_dev *indio_dev, 30 struct iio_chan_spec const *chan, int *val, 31 int *val2, long mask) 32 { 33 struct trigger_data *st = iio_priv(indio_dev); 34 35 switch (mask) { 36 case IIO_CHAN_INFO_RAW: 37 if (iio_buffer_enabled(indio_dev)) 38 return -EBUSY; 39 *val = mgb4_read_reg(&st->mgbdev->video, 0xA0); 40 41 return IIO_VAL_INT; 42 } 43 44 return -EINVAL; 45 } 46 47 static int trigger_set_state(struct iio_trigger *trig, bool state) 48 { 49 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 50 struct trigger_data *st = iio_priv(indio_dev); 51 int irq = xdma_get_user_irq(st->mgbdev->xdev, 11); 52 53 if (state) 54 xdma_enable_user_irq(st->mgbdev->xdev, irq); 55 else 56 xdma_disable_user_irq(st->mgbdev->xdev, irq); 57 58 return 0; 59 } 60 61 static const struct iio_trigger_ops trigger_ops = { 62 .set_trigger_state = &trigger_set_state, 63 }; 64 65 static const struct iio_info trigger_info = { 66 .read_raw = trigger_read_raw, 67 }; 68 69 #define TRIGGER_CHANNEL(_si) { \ 70 .type = IIO_ACTIVITY, \ 71 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 72 .scan_index = _si, \ 73 .scan_type = { \ 74 .sign = 'u', \ 75 .realbits = 32, \ 76 .storagebits = 32, \ 77 .shift = 0, \ 78 .endianness = IIO_CPU \ 79 }, \ 80 } 81 82 static const struct iio_chan_spec trigger_channels[] = { 83 TRIGGER_CHANNEL(0), 84 IIO_CHAN_SOFT_TIMESTAMP(1), 85 }; 86 87 static irqreturn_t trigger_handler(int irq, void *p) 88 { 89 struct iio_poll_func *pf = p; 90 struct iio_dev *indio_dev = pf->indio_dev; 91 struct trigger_data *st = iio_priv(indio_dev); 92 struct { 93 u32 data; 94 aligned_s64 ts; 95 } scan = { }; 96 97 scan.data = mgb4_read_reg(&st->mgbdev->video, 0xA0); 98 mgb4_write_reg(&st->mgbdev->video, 0xA0, scan.data); 99 100 iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan), pf->timestamp); 101 iio_trigger_notify_done(indio_dev->trig); 102 103 mgb4_write_reg(&st->mgbdev->video, 0xB4, 1U << 11); 104 105 return IRQ_HANDLED; 106 } 107 108 static int probe_trigger(struct iio_dev *indio_dev, int irq) 109 { 110 int ret; 111 struct trigger_data *st = iio_priv(indio_dev); 112 113 st->trig = iio_trigger_alloc(&st->mgbdev->pdev->dev, "%s-dev%d", 114 indio_dev->name, iio_device_id(indio_dev)); 115 if (!st->trig) 116 return -ENOMEM; 117 118 ret = request_irq(irq, &iio_trigger_generic_data_rdy_poll, 0, 119 "mgb4-trigger", st->trig); 120 if (ret) 121 goto error_free_trig; 122 123 st->trig->ops = &trigger_ops; 124 iio_trigger_set_drvdata(st->trig, indio_dev); 125 ret = iio_trigger_register(st->trig); 126 if (ret) 127 goto error_free_irq; 128 129 indio_dev->trig = iio_trigger_get(st->trig); 130 131 return 0; 132 133 error_free_irq: 134 free_irq(irq, st->trig); 135 error_free_trig: 136 iio_trigger_free(st->trig); 137 138 return ret; 139 } 140 141 static void remove_trigger(struct iio_dev *indio_dev, int irq) 142 { 143 struct trigger_data *st = iio_priv(indio_dev); 144 145 iio_trigger_unregister(st->trig); 146 free_irq(irq, st->trig); 147 iio_trigger_free(st->trig); 148 } 149 150 struct iio_dev *mgb4_trigger_create(struct mgb4_dev *mgbdev) 151 { 152 struct iio_dev *indio_dev; 153 struct trigger_data *data; 154 struct pci_dev *pdev = mgbdev->pdev; 155 struct device *dev = &pdev->dev; 156 int rv, irq; 157 158 indio_dev = iio_device_alloc(dev, sizeof(*data)); 159 if (!indio_dev) 160 return NULL; 161 162 indio_dev->info = &trigger_info; 163 indio_dev->name = "mgb4"; 164 indio_dev->modes = INDIO_DIRECT_MODE; 165 indio_dev->channels = trigger_channels; 166 indio_dev->num_channels = ARRAY_SIZE(trigger_channels); 167 168 data = iio_priv(indio_dev); 169 data->mgbdev = mgbdev; 170 171 irq = xdma_get_user_irq(mgbdev->xdev, 11); 172 rv = probe_trigger(indio_dev, irq); 173 if (rv < 0) { 174 dev_err(dev, "iio triggered setup failed\n"); 175 goto error_alloc; 176 } 177 rv = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, 178 trigger_handler, NULL); 179 if (rv < 0) { 180 dev_err(dev, "iio triggered buffer setup failed\n"); 181 goto error_trigger; 182 } 183 rv = iio_device_register(indio_dev); 184 if (rv < 0) { 185 dev_err(dev, "iio device register failed\n"); 186 goto error_buffer; 187 } 188 189 return indio_dev; 190 191 error_buffer: 192 iio_triggered_buffer_cleanup(indio_dev); 193 error_trigger: 194 remove_trigger(indio_dev, irq); 195 error_alloc: 196 iio_device_free(indio_dev); 197 198 return NULL; 199 } 200 201 void mgb4_trigger_free(struct iio_dev *indio_dev) 202 { 203 struct trigger_data *st = iio_priv(indio_dev); 204 205 iio_device_unregister(indio_dev); 206 iio_triggered_buffer_cleanup(indio_dev); 207 remove_trigger(indio_dev, xdma_get_user_irq(st->mgbdev->xdev, 11)); 208 iio_device_free(indio_dev); 209 } 210