1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * This is the driver for the MGB4 video grabber card by Digiteq Automotive.
4 *
5 * Copyright (C) 2021-2023 Digiteq Automotive
6 * author: Martin Tuma <martin.tuma@digiteqautomotive.com>
7 *
8 * This is the main driver module. The DMA, I2C and SPI sub-drivers are
9 * initialized here and the input/output v4l2 devices are created.
10 *
11 * The mgb4 card uses different expansion modules for different video sources
12 * (GMSL and FPDL3 for now) so in probe() we detect the module type based on
13 * what we see on the I2C bus and check if it matches the FPGA bitstream (there
14 * are different bitstreams for different expansion modules). When no expansion
15 * module is present, we still let the driver initialize to allow flashing of
16 * the FPGA firmware using the SPI FLASH device. No v4l2 video devices are
17 * created in this case.
18 */
19
20#include <linux/types.h>
21#include <linux/module.h>
22#include <linux/pci.h>
23#include <linux/platform_device.h>
24#include <linux/clk.h>
25#include <linux/clk-provider.h>
26#include <linux/clkdev.h>
27#include <linux/i2c.h>
28#include <linux/delay.h>
29#include <linux/dma/amd_xdma.h>
30#include <linux/platform_data/amd_xdma.h>
31#include <linux/spi/xilinx_spi.h>
32#include <linux/mtd/mtd.h>
33#include <linux/hwmon.h>
34#include <linux/debugfs.h>
35#include "mgb4_dma.h"
36#include "mgb4_i2c.h"
37#include "mgb4_sysfs.h"
38#include "mgb4_vout.h"
39#include "mgb4_vin.h"
40#include "mgb4_trigger.h"
41#include "mgb4_core.h"
42
43#define MGB4_USER_IRQS 16
44#define MGB4_MGB4_BAR_ID 0
45#define MGB4_XDMA_BAR_ID 1
46
47#define DIGITEQ_VID 0x1ed8
48#define T100_DID 0x0101
49#define T200_DID 0x0201
50
51ATTRIBUTE_GROUPS(mgb4_pci);
52
53static int flashid;
54
55static struct xdma_chan_info h2c_chan_info = {
56 .dir = DMA_MEM_TO_DEV,
57};
58
59static struct xdma_chan_info c2h_chan_info = {
60 .dir = DMA_DEV_TO_MEM,
61};
62
63static struct xspi_platform_data spi_platform_data = {
64 .num_chipselect = 1,
65 .bits_per_word = 8
66};
67
68static const struct i2c_board_info extender_info = {
69 I2C_BOARD_INFO("extender", 0x21)
70};
71
72#if IS_REACHABLE(CONFIG_HWMON)
73static umode_t temp_is_visible(const void *data, enum hwmon_sensor_types type,
74 u32 attr, int channel)
75{
76 if (type == hwmon_temp &&
77 (attr == hwmon_temp_input || attr == hwmon_temp_label))
78 return 0444;
79 else
80 return 0;
81}
82
83static int temp_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
84 int channel, long *val)
85{
86 struct mgb4_dev *mgbdev = dev_get_drvdata(dev);
87 u32 val10, raw;
88
89 if (type != hwmon_temp || attr != hwmon_temp_input)
90 return -EOPNOTSUPP;
91
92 raw = mgb4_read_reg(&mgbdev->video, 0xD0);
93 /* register value -> Celsius degrees formula given by Xilinx */
94 val10 = ((((raw >> 20) & 0xFFF) * 503975) - 1118822400) / 409600;
95 *val = val10 * 100;
96
97 return 0;
98}
99
100static int temp_read_string(struct device *dev, enum hwmon_sensor_types type,
101 u32 attr, int channel, const char **str)
102{
103 if (type != hwmon_temp || attr != hwmon_temp_label)
104 return -EOPNOTSUPP;
105
106 *str = "FPGA Temperature";
107
108 return 0;
109}
110
111static const struct hwmon_ops temp_ops = {
112 .is_visible = temp_is_visible,
113 .read = temp_read,
114 .read_string = temp_read_string
115};
116
117static const struct hwmon_channel_info *temp_channel_info[] = {
118 HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_LABEL),
119 NULL
120};
121
122static const struct hwmon_chip_info temp_chip_info = {
123 .ops = &temp_ops,
124 .info = temp_channel_info,
125};
126#endif
127
128static int match_i2c_adap(struct device *dev, const void *data)
129{
130 return i2c_verify_adapter(dev) ? 1 : 0;
131}
132
133static struct i2c_adapter *get_i2c_adap(struct platform_device *pdev)
134{
135 struct device *dev;
136
137 mutex_lock(&pdev->dev.mutex);
138 dev = device_find_child(parent: &pdev->dev, NULL, match: match_i2c_adap);
139 mutex_unlock(lock: &pdev->dev.mutex);
140
141 return dev ? to_i2c_adapter(dev) : NULL;
142}
143
144static int match_spi_adap(struct device *dev, const void *data)
145{
146 return to_spi_device(dev) ? 1 : 0;
147}
148
149static struct spi_controller *get_spi_adap(struct platform_device *pdev)
150{
151 struct device *dev;
152
153 mutex_lock(&pdev->dev.mutex);
154 dev = device_find_child(parent: &pdev->dev, NULL, match: match_spi_adap);
155 mutex_unlock(lock: &pdev->dev.mutex);
156
157 return dev ? container_of(dev, struct spi_controller, dev) : NULL;
158}
159
160static int init_spi(struct mgb4_dev *mgbdev, u32 devid)
161{
162 struct resource spi_resources[] = {
163 {
164 .start = 0x400,
165 .end = 0x47f,
166 .flags = IORESOURCE_MEM,
167 .name = "io-memory",
168 },
169 {
170 .start = 14,
171 .end = 14,
172 .flags = IORESOURCE_IRQ,
173 .name = "irq",
174 },
175 };
176 struct spi_board_info spi_info = {
177 .max_speed_hz = 10000000,
178 .modalias = "m25p80",
179 .chip_select = 0,
180 .mode = SPI_MODE_3,
181 };
182 struct pci_dev *pdev = mgbdev->pdev;
183 struct device *dev = &pdev->dev;
184 struct spi_controller *ctlr;
185 struct spi_device *spi_dev;
186 u32 irq;
187 int rv, id;
188 resource_size_t mapbase = pci_resource_start(pdev, MGB4_MGB4_BAR_ID);
189
190 request_module("platform:xilinx_spi");
191
192 irq = xdma_get_user_irq(pdev: mgbdev->xdev, user_irq_index: 14);
193 xdma_enable_user_irq(pdev: mgbdev->xdev, irq_num: irq);
194
195 spi_resources[0].parent = &pdev->resource[MGB4_MGB4_BAR_ID];
196 spi_resources[0].start += mapbase;
197 spi_resources[0].end += mapbase;
198 spi_resources[1].start = irq;
199 spi_resources[1].end = irq;
200
201 id = pci_dev_id(dev: pdev);
202 mgbdev->spi_pdev = platform_device_register_resndata(parent: dev, name: "xilinx_spi",
203 id, res: spi_resources,
204 ARRAY_SIZE(spi_resources),
205 data: &spi_platform_data,
206 size: sizeof(spi_platform_data));
207 if (IS_ERR(ptr: mgbdev->spi_pdev)) {
208 dev_err(dev, "failed to register SPI device\n");
209 return PTR_ERR(ptr: mgbdev->spi_pdev);
210 }
211
212 ctlr = get_spi_adap(pdev: mgbdev->spi_pdev);
213 if (!ctlr) {
214 dev_err(dev, "failed to get SPI adapter\n");
215 rv = -EINVAL;
216 goto err_pdev;
217 }
218
219 snprintf(buf: mgbdev->fw_part_name, size: sizeof(mgbdev->fw_part_name),
220 fmt: "mgb4-fw.%d", flashid);
221 mgbdev->partitions[0].name = mgbdev->fw_part_name;
222 if (devid == T200_DID) {
223 mgbdev->partitions[0].size = 0x950000;
224 mgbdev->partitions[0].offset = 0x1000000;
225 } else {
226 mgbdev->partitions[0].size = 0x400000;
227 mgbdev->partitions[0].offset = 0x400000;
228 }
229 mgbdev->partitions[0].mask_flags = 0;
230
231 snprintf(buf: mgbdev->data_part_name, size: sizeof(mgbdev->data_part_name),
232 fmt: "mgb4-data.%d", flashid);
233 mgbdev->partitions[1].name = mgbdev->data_part_name;
234 mgbdev->partitions[1].size = 0x10000;
235 mgbdev->partitions[1].offset = 0xFF0000;
236 mgbdev->partitions[1].mask_flags = MTD_CAP_NORFLASH;
237
238 snprintf(buf: mgbdev->flash_name, size: sizeof(mgbdev->flash_name),
239 fmt: "mgb4-flash.%d", flashid);
240 mgbdev->flash_data.name = mgbdev->flash_name;
241 mgbdev->flash_data.parts = mgbdev->partitions;
242 mgbdev->flash_data.nr_parts = ARRAY_SIZE(mgbdev->partitions);
243 mgbdev->flash_data.type = "spi-nor";
244
245 spi_info.platform_data = &mgbdev->flash_data;
246
247 spi_dev = spi_new_device(ctlr, &spi_info);
248 put_device(dev: &ctlr->dev);
249 if (!spi_dev) {
250 dev_err(dev, "failed to create MTD device\n");
251 rv = -EINVAL;
252 goto err_pdev;
253 }
254
255 return 0;
256
257err_pdev:
258 platform_device_unregister(mgbdev->spi_pdev);
259
260 return rv;
261}
262
263static void free_spi(struct mgb4_dev *mgbdev)
264{
265 platform_device_unregister(mgbdev->spi_pdev);
266}
267
268static int init_i2c(struct mgb4_dev *mgbdev)
269{
270 struct resource i2c_resources[] = {
271 {
272 .start = 0x200,
273 .end = 0x3ff,
274 .flags = IORESOURCE_MEM,
275 .name = "io-memory",
276 },
277 {
278 .start = 15,
279 .end = 15,
280 .flags = IORESOURCE_IRQ,
281 .name = "irq",
282 },
283 };
284 struct pci_dev *pdev = mgbdev->pdev;
285 struct device *dev = &pdev->dev;
286 char clk_name[16];
287 u32 irq;
288 int rv, id;
289 resource_size_t mapbase = pci_resource_start(pdev, MGB4_MGB4_BAR_ID);
290
291 request_module("platform:xiic-i2c");
292
293 irq = xdma_get_user_irq(pdev: mgbdev->xdev, user_irq_index: 15);
294 xdma_enable_user_irq(pdev: mgbdev->xdev, irq_num: irq);
295
296 i2c_resources[0].parent = &pdev->resource[MGB4_MGB4_BAR_ID];
297 i2c_resources[0].start += mapbase;
298 i2c_resources[0].end += mapbase;
299 i2c_resources[1].start = irq;
300 i2c_resources[1].end = irq;
301
302 id = pci_dev_id(dev: pdev);
303
304 /* create dummy clock required by the xiic-i2c adapter */
305 snprintf(buf: clk_name, size: sizeof(clk_name), fmt: "xiic-i2c.%d", id);
306 mgbdev->i2c_clk = clk_hw_register_fixed_rate(NULL, clk_name, NULL,
307 0, MGB4_HW_FREQ);
308 if (IS_ERR(ptr: mgbdev->i2c_clk)) {
309 dev_err(dev, "failed to register I2C clock\n");
310 return PTR_ERR(ptr: mgbdev->i2c_clk);
311 }
312 mgbdev->i2c_cl = clkdev_hw_create(hw: mgbdev->i2c_clk, NULL, dev_fmt: "xiic-i2c.%d",
313 id);
314 if (!mgbdev->i2c_cl) {
315 dev_err(dev, "failed to register I2C clockdev\n");
316 rv = -ENOMEM;
317 goto err_clk;
318 }
319
320 mgbdev->i2c_pdev = platform_device_register_resndata(parent: dev, name: "xiic-i2c",
321 id, res: i2c_resources,
322 ARRAY_SIZE(i2c_resources),
323 NULL, size: 0);
324 if (IS_ERR(ptr: mgbdev->i2c_pdev)) {
325 dev_err(dev, "failed to register I2C device\n");
326 rv = PTR_ERR(ptr: mgbdev->i2c_pdev);
327 goto err_clkdev;
328 }
329
330 mgbdev->i2c_adap = get_i2c_adap(pdev: mgbdev->i2c_pdev);
331 if (!mgbdev->i2c_adap) {
332 dev_err(dev, "failed to get I2C adapter\n");
333 rv = -EINVAL;
334 goto err_pdev;
335 }
336
337 mutex_init(&mgbdev->i2c_lock);
338
339 return 0;
340
341err_pdev:
342 platform_device_unregister(mgbdev->i2c_pdev);
343err_clkdev:
344 clkdev_drop(cl: mgbdev->i2c_cl);
345err_clk:
346 clk_hw_unregister(hw: mgbdev->i2c_clk);
347
348 return rv;
349}
350
351static void free_i2c(struct mgb4_dev *mgbdev)
352{
353 put_device(dev: &mgbdev->i2c_adap->dev);
354 platform_device_unregister(mgbdev->i2c_pdev);
355 clkdev_drop(cl: mgbdev->i2c_cl);
356 clk_hw_unregister(hw: mgbdev->i2c_clk);
357}
358
359static int get_serial_number(struct mgb4_dev *mgbdev)
360{
361 struct device *dev = &mgbdev->pdev->dev;
362 struct mtd_info *mtd;
363 size_t rs;
364 int rv;
365
366 mgbdev->serial_number = 0;
367
368 mtd = get_mtd_device_nm(name: mgbdev->data_part_name);
369 if (IS_ERR(ptr: mtd)) {
370 dev_warn(dev, "failed to get data MTD device\n");
371 return -ENOENT;
372 }
373 rv = mtd_read(mtd, from: 0, len: sizeof(mgbdev->serial_number), retlen: &rs,
374 buf: (u_char *)&mgbdev->serial_number);
375 put_mtd_device(mtd);
376 if (rv < 0 || rs != sizeof(mgbdev->serial_number)) {
377 dev_warn(dev, "error reading MTD device\n");
378 return -EIO;
379 }
380
381 return 0;
382}
383
384static int get_module_version(struct mgb4_dev *mgbdev)
385{
386 struct device *dev = &mgbdev->pdev->dev;
387 struct mgb4_i2c_client extender;
388 s32 version;
389 u32 fw_version;
390 int rv;
391
392 rv = mgb4_i2c_init(client: &extender, adap: mgbdev->i2c_adap, info: &extender_info, addr_size: 8);
393 if (rv < 0) {
394 dev_err(dev, "failed to create extender I2C device\n");
395 return rv;
396 }
397 version = mgb4_i2c_read_byte(client: &extender, reg: 0x00);
398 mgb4_i2c_free(client: &extender);
399 if (version < 0) {
400 dev_err(dev, "error reading module version\n");
401 return -EIO;
402 }
403
404 mgbdev->module_version = ~((u32)version) & 0xff;
405 if (!(MGB4_IS_FPDL3(mgbdev) || MGB4_IS_GMSL(mgbdev))) {
406 dev_err(dev, "unknown module type\n");
407 return -EINVAL;
408 }
409 fw_version = mgb4_read_reg(&mgbdev->video, 0xC4) >> 24;
410 if ((MGB4_IS_FPDL3(mgbdev) && fw_version != 1) ||
411 (MGB4_IS_GMSL(mgbdev) && fw_version != 2)) {
412 dev_err(dev, "module/firmware type mismatch\n");
413 return -EINVAL;
414 }
415
416 dev_info(dev, "%s module detected\n",
417 MGB4_IS_FPDL3(mgbdev) ? "FPDL3" : "GMSL");
418
419 return 0;
420}
421
422static int map_regs(struct pci_dev *pdev, struct resource *res,
423 struct mgb4_regs *regs)
424{
425 int rv;
426 resource_size_t mapbase = pci_resource_start(pdev, MGB4_MGB4_BAR_ID);
427
428 res->start += mapbase;
429 res->end += mapbase;
430
431 rv = mgb4_regs_map(res, regs);
432 if (rv < 0) {
433 dev_err(&pdev->dev, "failed to map %s registers\n", res->name);
434 return rv;
435 }
436
437 return 0;
438}
439
440static int init_xdma(struct mgb4_dev *mgbdev)
441{
442 struct xdma_platdata data;
443 struct resource res[2] = { 0 };
444 struct dma_slave_map *map;
445 struct pci_dev *pdev = mgbdev->pdev;
446 struct device *dev = &pdev->dev;
447 int i;
448
449 res[0].start = pci_resource_start(pdev, MGB4_XDMA_BAR_ID);
450 res[0].end = pci_resource_end(pdev, MGB4_XDMA_BAR_ID);
451 res[0].flags = IORESOURCE_MEM;
452 res[0].parent = &pdev->resource[MGB4_XDMA_BAR_ID];
453 res[1].start = pci_irq_vector(dev: pdev, nr: 0);
454 res[1].end = res[1].start + MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES
455 + MGB4_USER_IRQS - 1;
456 res[1].flags = IORESOURCE_IRQ;
457
458 data.max_dma_channels = MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES;
459 data.device_map = mgbdev->slave_map;
460 data.device_map_cnt = MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES;
461
462 for (i = 0; i < MGB4_VIN_DEVICES; i++) {
463 sprintf(buf: mgbdev->channel_names[i], fmt: "c2h%d", i);
464 map = &data.device_map[i];
465 map->slave = mgbdev->channel_names[i];
466 map->devname = dev_name(dev);
467 map->param = XDMA_FILTER_PARAM(&c2h_chan_info);
468 }
469 for (i = 0; i < MGB4_VOUT_DEVICES; i++) {
470 sprintf(buf: mgbdev->channel_names[i + MGB4_VIN_DEVICES], fmt: "h2c%d", i);
471 map = &data.device_map[i + MGB4_VIN_DEVICES];
472 map->slave = mgbdev->channel_names[i + MGB4_VIN_DEVICES];
473 map->devname = dev_name(dev);
474 map->param = XDMA_FILTER_PARAM(&h2c_chan_info);
475 }
476
477 mgbdev->xdev = platform_device_register_resndata(parent: dev, name: "xdma",
478 PLATFORM_DEVID_AUTO, res,
479 num: 2, data: &data, size: sizeof(data));
480 if (IS_ERR(ptr: mgbdev->xdev)) {
481 dev_err(dev, "failed to register XDMA device\n");
482 return PTR_ERR(ptr: mgbdev->xdev);
483 }
484
485 return 0;
486}
487
488static void free_xdma(struct mgb4_dev *mgbdev)
489{
490 platform_device_unregister(mgbdev->xdev);
491}
492
493static int mgb4_probe(struct pci_dev *pdev, const struct pci_device_id *id)
494{
495 int i, rv;
496 struct mgb4_dev *mgbdev;
497 struct resource video = {
498 .start = 0x0,
499 .end = 0xff,
500 .flags = IORESOURCE_MEM,
501 .name = "mgb4-video",
502 };
503 struct resource cmt = {
504 .start = 0x1000,
505 .end = 0x17ff,
506 .flags = IORESOURCE_MEM,
507 .name = "mgb4-cmt",
508 };
509 int irqs = pci_msix_vec_count(dev: pdev);
510
511 mgbdev = kzalloc(sizeof(*mgbdev), GFP_KERNEL);
512 if (!mgbdev)
513 return -ENOMEM;
514
515 mgbdev->pdev = pdev;
516 pci_set_drvdata(pdev, data: mgbdev);
517
518 /* PCIe related stuff */
519 rv = pci_enable_device(dev: pdev);
520 if (rv) {
521 dev_err(&pdev->dev, "error enabling PCI device\n");
522 goto err_mgbdev;
523 }
524
525 rv = pcie_capability_set_word(dev: pdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
526 if (rv)
527 dev_warn(&pdev->dev, "error enabling PCIe relaxed ordering\n");
528 rv = pcie_capability_set_word(dev: pdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_EXT_TAG);
529 if (rv)
530 dev_warn(&pdev->dev, "error enabling PCIe extended tag field\n");
531 rv = pcie_set_readrq(dev: pdev, rq: 512);
532 if (rv)
533 dev_warn(&pdev->dev, "error setting PCIe max. memory read size\n");
534 pci_set_master(dev: pdev);
535
536 rv = pci_alloc_irq_vectors(dev: pdev, min_vecs: irqs, max_vecs: irqs, PCI_IRQ_MSIX);
537 if (rv < 0) {
538 dev_err(&pdev->dev, "error allocating MSI-X IRQs\n");
539 goto err_enable_pci;
540 }
541
542 rv = dma_set_mask_and_coherent(dev: &pdev->dev, DMA_BIT_MASK(64));
543 if (rv) {
544 dev_err(&pdev->dev, "error setting DMA mask\n");
545 goto err_enable_pci;
546 }
547
548 /* DMA + IRQ engine */
549 rv = init_xdma(mgbdev);
550 if (rv)
551 goto err_alloc_irq;
552 rv = mgb4_dma_channel_init(mgbdev);
553 if (rv)
554 goto err_dma_chan;
555
556 /* mgb4 video registers */
557 rv = map_regs(pdev, res: &video, regs: &mgbdev->video);
558 if (rv < 0)
559 goto err_dma_chan;
560 /* mgb4 cmt registers */
561 rv = map_regs(pdev, res: &cmt, regs: &mgbdev->cmt);
562 if (rv < 0)
563 goto err_video_regs;
564
565 /* SPI FLASH */
566 rv = init_spi(mgbdev, devid: id->device);
567 if (rv < 0)
568 goto err_cmt_regs;
569
570 /* I2C controller */
571 rv = init_i2c(mgbdev);
572 if (rv < 0)
573 goto err_spi;
574
575 /* PCI card related sysfs attributes */
576 rv = device_add_groups(dev: &pdev->dev, groups: mgb4_pci_groups);
577 if (rv < 0)
578 goto err_i2c;
579
580#if IS_REACHABLE(CONFIG_HWMON)
581 /* HWmon (card temperature) */
582 mgbdev->hwmon_dev = hwmon_device_register_with_info(dev: &pdev->dev, name: "mgb4",
583 drvdata: mgbdev,
584 info: &temp_chip_info,
585 NULL);
586#endif
587
588 mgbdev->debugfs = debugfs_create_dir(name: dev_name(dev: &pdev->dev), NULL);
589
590 /* Get card serial number. On systems without MTD flash support we may
591 * get an error thus ignore the return value. An invalid serial number
592 * should not break anything...
593 */
594 if (get_serial_number(mgbdev) < 0)
595 dev_warn(&pdev->dev, "error reading card serial number\n");
596
597 /* Get module type. If no valid module is found, skip the video device
598 * creation part but do not exit with error to allow flashing the card.
599 */
600 rv = get_module_version(mgbdev);
601 if (rv < 0)
602 goto exit;
603 /* Propagate the module type(version) to the FPGA */
604 mgb4_write_reg(&mgbdev->video, 0xD4, mgbdev->module_version);
605
606 /* Video input v4l2 devices */
607 for (i = 0; i < MGB4_VIN_DEVICES; i++)
608 mgbdev->vin[i] = mgb4_vin_create(mgbdev, id: i);
609
610 /* Video output v4l2 devices */
611 if (MGB4_HAS_VOUT(mgbdev)) {
612 for (i = 0; i < MGB4_VOUT_DEVICES; i++)
613 mgbdev->vout[i] = mgb4_vout_create(mgbdev, id: i);
614 }
615
616 /* Triggers */
617 mgbdev->indio_dev = mgb4_trigger_create(mgbdev);
618
619exit:
620 flashid++;
621
622 return 0;
623
624err_i2c:
625 free_i2c(mgbdev);
626err_spi:
627 free_spi(mgbdev);
628err_cmt_regs:
629 mgb4_regs_free(regs: &mgbdev->cmt);
630err_video_regs:
631 mgb4_regs_free(regs: &mgbdev->video);
632err_dma_chan:
633 mgb4_dma_channel_free(mgbdev);
634 free_xdma(mgbdev);
635err_alloc_irq:
636 pci_disable_msix(dev: pdev);
637err_enable_pci:
638 pci_disable_device(dev: pdev);
639err_mgbdev:
640 kfree(objp: mgbdev);
641
642 return rv;
643}
644
645static void mgb4_remove(struct pci_dev *pdev)
646{
647 struct mgb4_dev *mgbdev = pci_get_drvdata(pdev);
648 int i;
649
650#if IS_REACHABLE(CONFIG_HWMON)
651 hwmon_device_unregister(dev: mgbdev->hwmon_dev);
652#endif
653
654 debugfs_remove_recursive(dentry: mgbdev->debugfs);
655
656 if (mgbdev->indio_dev)
657 mgb4_trigger_free(indio_dev: mgbdev->indio_dev);
658
659 for (i = 0; i < MGB4_VOUT_DEVICES; i++)
660 if (mgbdev->vout[i])
661 mgb4_vout_free(voutdev: mgbdev->vout[i]);
662 for (i = 0; i < MGB4_VIN_DEVICES; i++)
663 if (mgbdev->vin[i])
664 mgb4_vin_free(vindev: mgbdev->vin[i]);
665
666 device_remove_groups(dev: &mgbdev->pdev->dev, groups: mgb4_pci_groups);
667 free_spi(mgbdev);
668 free_i2c(mgbdev);
669 mgb4_regs_free(regs: &mgbdev->video);
670 mgb4_regs_free(regs: &mgbdev->cmt);
671
672 mgb4_dma_channel_free(mgbdev);
673 free_xdma(mgbdev);
674
675 pci_disable_msix(dev: mgbdev->pdev);
676 pci_disable_device(dev: mgbdev->pdev);
677
678 kfree(objp: mgbdev);
679}
680
681static const struct pci_device_id mgb4_pci_ids[] = {
682 { PCI_DEVICE(DIGITEQ_VID, T100_DID), },
683 { PCI_DEVICE(DIGITEQ_VID, T200_DID), },
684 { 0, }
685};
686MODULE_DEVICE_TABLE(pci, mgb4_pci_ids);
687
688static struct pci_driver mgb4_pci_driver = {
689 .name = KBUILD_MODNAME,
690 .id_table = mgb4_pci_ids,
691 .probe = mgb4_probe,
692 .remove = mgb4_remove,
693};
694
695module_pci_driver(mgb4_pci_driver);
696
697MODULE_AUTHOR("Digiteq Automotive s.r.o.");
698MODULE_DESCRIPTION("Digiteq Automotive MGB4 Driver");
699MODULE_LICENSE("GPL");
700MODULE_SOFTDEP("pre: platform:xiic-i2c platform:xilinx_spi spi-nor");
701

source code of linux/drivers/media/pci/mgb4/mgb4_core.c