1 // SPDX-License-Identifier: GPL-2.0-only
2
3 /*
4 * Hardware driver for NI Mite PCI interface chip,
5 * adapted from COMEDI
6 *
7 * Copyright (C) 1997-8 David A. Schleef
8 * Copyright (C) 2002 Frank Mori Hess
9 *
10 * The PCI-MIO E series driver was originally written by
11 * Tomasz Motylewski <...>, and ported to comedi by ds.
12 *
13 * References for specifications:
14 *
15 * 321747b.pdf Register Level Programmer Manual (obsolete)
16 * 321747c.pdf Register Level Programmer Manual (new)
17 * DAQ-STC reference manual
18 *
19 * Other possibly relevant info:
20 *
21 * 320517c.pdf User manual (obsolete)
22 * 320517f.pdf User manual (new)
23 * 320889a.pdf delete
24 * 320906c.pdf maximum signal ratings
25 * 321066a.pdf about 16x
26 * 321791a.pdf discontinuation of at-mio-16e-10 rev. c
27 * 321808a.pdf about at-mio-16e-10 rev P
28 * 321837a.pdf discontinuation of at-mio-16de-10 rev d
29 * 321838a.pdf about at-mio-16de-10 rev N
30 */
31
32 #include <linux/module.h>
33 #include <linux/kernel.h>
34 #include <linux/errno.h>
35 #include <linux/ioport.h>
36 #include <linux/delay.h>
37 #include <linux/mm.h>
38 #include <linux/interrupt.h>
39 #include <linux/pci.h>
40 #include <linux/io.h>
41 #include <linux/slab.h>
42
43 #include "mite.h"
44
45 #define PCI_MITE_SIZE 4096
46 #define PCI_DAQ_SIZE 4096
47
48 struct mite_struct *mite_devices;
49
50 #define TOP_OF_PAGE(x) ((x) | (~(PAGE_MASK)))
51
mite_init(void)52 void mite_init(void)
53 {
54 struct pci_dev *pcidev;
55 struct mite_struct *mite;
56
57 for (pcidev = pci_get_device(PCI_VENDOR_ID_NATINST, PCI_ANY_ID, NULL);
58 pcidev;
59 pcidev = pci_get_device(PCI_VENDOR_ID_NATINST, PCI_ANY_ID, pcidev)) {
60 mite = kzalloc(sizeof(*mite), GFP_KERNEL);
61 if (!mite)
62 return;
63
64 mite->pcidev = pcidev;
65 pci_dev_get(mite->pcidev);
66 mite->next = mite_devices;
67 mite_devices = mite;
68 }
69 }
70
mite_setup(struct mite_struct * mite)71 int mite_setup(struct mite_struct *mite)
72 {
73 u32 addr;
74
75 if (pci_enable_device(mite->pcidev)) {
76 pr_err("mite: error enabling mite.\n");
77 return -EIO;
78 }
79 pci_set_master(mite->pcidev);
80 if (pci_request_regions(mite->pcidev, "mite")) {
81 pr_err("mite: failed to request mite io regions.\n");
82 return -EIO;
83 }
84 addr = pci_resource_start(mite->pcidev, 0);
85 mite->mite_phys_addr = addr;
86 mite->mite_io_addr = ioremap(addr, pci_resource_len(mite->pcidev, 0));
87 if (!mite->mite_io_addr) {
88 pr_err("mite: failed to remap mite io memory address.\n");
89 return -ENOMEM;
90 }
91 pr_info("mite: 0x%08lx mapped to %p\n", mite->mite_phys_addr, mite->mite_io_addr);
92 addr = pci_resource_start(mite->pcidev, 1);
93 mite->daq_phys_addr = addr;
94 mite->daq_io_addr = ioremap(mite->daq_phys_addr, pci_resource_len(mite->pcidev, 1));
95 if (!mite->daq_io_addr) {
96 pr_err("mite: failed to remap daq io memory address.\n");
97 return -ENOMEM;
98 }
99 pr_info("mite: daq: 0x%08lx mapped to %p\n", mite->daq_phys_addr, mite->daq_io_addr);
100 writel(mite->daq_phys_addr | WENAB, mite->mite_io_addr + MITE_IODWBSR);
101 mite->used = 1;
102 return 0;
103 }
104
mite_cleanup(void)105 void mite_cleanup(void)
106 {
107 struct mite_struct *mite, *next;
108
109 for (mite = mite_devices; mite; mite = next) {
110 next = mite->next;
111 if (mite->pcidev)
112 pci_dev_put(mite->pcidev);
113 kfree(mite);
114 }
115 }
116
mite_unsetup(struct mite_struct * mite)117 void mite_unsetup(struct mite_struct *mite)
118 {
119 if (!mite)
120 return;
121 if (mite->mite_io_addr) {
122 iounmap(mite->mite_io_addr);
123 mite->mite_io_addr = NULL;
124 }
125 if (mite->daq_io_addr) {
126 iounmap(mite->daq_io_addr);
127 mite->daq_io_addr = NULL;
128 }
129 if (mite->mite_phys_addr) {
130 pci_release_regions(mite->pcidev);
131 pci_disable_device(mite->pcidev);
132 mite->mite_phys_addr = 0;
133 }
134 mite->used = 0;
135 }
136
mite_list_devices(void)137 void mite_list_devices(void)
138 {
139 struct mite_struct *mite, *next;
140
141 pr_info("Available NI PCI device IDs:");
142 if (mite_devices)
143 for (mite = mite_devices; mite; mite = next) {
144 next = mite->next;
145 pr_info(" 0x%04x", mite_device_id(mite));
146 if (mite->used)
147 pr_info("(used)");
148 }
149 pr_info("\n");
150 }
151