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