1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * comedi/drivers/ni_labpc_pci.c |
4 | * Driver for National Instruments Lab-PC PCI-1200 |
5 | * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net> |
6 | */ |
7 | |
8 | /* |
9 | * Driver: ni_labpc_pci |
10 | * Description: National Instruments Lab-PC PCI-1200 |
11 | * Devices: [National Instruments] PCI-1200 (ni_pci-1200) |
12 | * Author: Frank Mori Hess <fmhess@users.sourceforge.net> |
13 | * Status: works |
14 | * |
15 | * This is the PCI-specific support split off from the ni_labpc driver. |
16 | * |
17 | * Configuration Options: not applicable, uses PCI auto config |
18 | * |
19 | * NI manuals: |
20 | * 340914a (pci-1200) |
21 | */ |
22 | |
23 | #include <linux/module.h> |
24 | #include <linux/interrupt.h> |
25 | #include <linux/comedi/comedi_pci.h> |
26 | |
27 | #include "ni_labpc.h" |
28 | |
29 | enum labpc_pci_boardid { |
30 | BOARD_NI_PCI1200, |
31 | }; |
32 | |
33 | static const struct labpc_boardinfo labpc_pci_boards[] = { |
34 | [BOARD_NI_PCI1200] = { |
35 | .name = "ni_pci-1200" , |
36 | .ai_speed = 10000, |
37 | .ai_scan_up = 1, |
38 | .has_ao = 1, |
39 | .is_labpc1200 = 1, |
40 | }, |
41 | }; |
42 | |
43 | /* ripped from mite.h and mite_setup2() to avoid mite dependency */ |
44 | #define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ |
45 | #define WENAB BIT(7) /* window enable */ |
46 | |
47 | static int labpc_pci_mite_init(struct pci_dev *pcidev) |
48 | { |
49 | void __iomem *mite_base; |
50 | u32 main_phys_addr; |
51 | |
52 | /* ioremap the MITE registers (BAR 0) temporarily */ |
53 | mite_base = pci_ioremap_bar(pdev: pcidev, bar: 0); |
54 | if (!mite_base) |
55 | return -ENOMEM; |
56 | |
57 | /* set data window to main registers (BAR 1) */ |
58 | main_phys_addr = pci_resource_start(pcidev, 1); |
59 | writel(val: main_phys_addr | WENAB, addr: mite_base + MITE_IODWBSR); |
60 | |
61 | /* finished with MITE registers */ |
62 | iounmap(addr: mite_base); |
63 | return 0; |
64 | } |
65 | |
66 | static int labpc_pci_auto_attach(struct comedi_device *dev, |
67 | unsigned long context) |
68 | { |
69 | struct pci_dev *pcidev = comedi_to_pci_dev(dev); |
70 | const struct labpc_boardinfo *board = NULL; |
71 | int ret; |
72 | |
73 | if (context < ARRAY_SIZE(labpc_pci_boards)) |
74 | board = &labpc_pci_boards[context]; |
75 | if (!board) |
76 | return -ENODEV; |
77 | dev->board_ptr = board; |
78 | dev->board_name = board->name; |
79 | |
80 | ret = comedi_pci_enable(dev); |
81 | if (ret) |
82 | return ret; |
83 | |
84 | ret = labpc_pci_mite_init(pcidev); |
85 | if (ret) |
86 | return ret; |
87 | |
88 | dev->mmio = pci_ioremap_bar(pdev: pcidev, bar: 1); |
89 | if (!dev->mmio) |
90 | return -ENOMEM; |
91 | |
92 | return labpc_common_attach(dev, irq: pcidev->irq, IRQF_SHARED); |
93 | } |
94 | |
95 | static void labpc_pci_detach(struct comedi_device *dev) |
96 | { |
97 | labpc_common_detach(dev); |
98 | comedi_pci_detach(dev); |
99 | } |
100 | |
101 | static struct comedi_driver labpc_pci_comedi_driver = { |
102 | .driver_name = "labpc_pci" , |
103 | .module = THIS_MODULE, |
104 | .auto_attach = labpc_pci_auto_attach, |
105 | .detach = labpc_pci_detach, |
106 | }; |
107 | |
108 | static const struct pci_device_id labpc_pci_table[] = { |
109 | { PCI_VDEVICE(NI, 0x161), BOARD_NI_PCI1200 }, |
110 | { 0 } |
111 | }; |
112 | MODULE_DEVICE_TABLE(pci, labpc_pci_table); |
113 | |
114 | static int labpc_pci_probe(struct pci_dev *dev, |
115 | const struct pci_device_id *id) |
116 | { |
117 | return comedi_pci_auto_config(pcidev: dev, driver: &labpc_pci_comedi_driver, |
118 | context: id->driver_data); |
119 | } |
120 | |
121 | static struct pci_driver labpc_pci_driver = { |
122 | .name = "labpc_pci" , |
123 | .id_table = labpc_pci_table, |
124 | .probe = labpc_pci_probe, |
125 | .remove = comedi_pci_auto_unconfig, |
126 | }; |
127 | module_comedi_pci_driver(labpc_pci_comedi_driver, labpc_pci_driver); |
128 | |
129 | MODULE_DESCRIPTION("Comedi: National Instruments Lab-PC PCI-1200 driver" ); |
130 | MODULE_AUTHOR("Comedi https://www.comedi.org" ); |
131 | MODULE_LICENSE("GPL" ); |
132 | |