Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
staging
comedi
drivers
dt2817.c
Go to the documentation of this file.
1
/*
2
comedi/drivers/dt2817.c
3
Hardware driver for Data Translation DT2817
4
5
COMEDI - Linux Control and Measurement Device Interface
6
Copyright (C) 1998 David A. Schleef <
[email protected]
>
7
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
12
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
17
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22
*/
23
/*
24
Driver: dt2817
25
Description: Data Translation DT2817
26
Author: ds
27
Status: complete
28
Devices: [Data Translation] DT2817 (dt2817)
29
30
A very simple digital I/O card. Four banks of 8 lines, each bank
31
is configurable for input or output. One wonders why it takes a
32
50 page manual to describe this thing.
33
34
The driver (which, btw, is much less than 50 pages) has 1 subdevice
35
with 32 channels, configurable in groups of 8.
36
37
Configuration options:
38
[0] - I/O port base base address
39
*/
40
41
#include "../comedidev.h"
42
43
#include <
linux/ioport.h
>
44
45
#define DT2817_SIZE 5
46
47
#define DT2817_CR 0
48
#define DT2817_DATA 1
49
50
static
int
dt2817_dio_insn_config(
struct
comedi_device
*
dev
,
51
struct
comedi_subdevice
*
s
,
52
struct
comedi_insn
*
insn
,
unsigned
int
*
data
)
53
{
54
int
mask
;
55
int
chan
;
56
int
oe = 0;
57
58
if
(insn->
n
!= 1)
59
return
-
EINVAL
;
60
61
chan =
CR_CHAN
(insn->
chanspec
);
62
if
(chan < 8)
63
mask = 0xff;
64
else
if
(chan < 16)
65
mask = 0xff00;
66
else
if
(chan < 24)
67
mask = 0xff0000;
68
else
69
mask = 0xff000000;
70
if
(data[0])
71
s->
io_bits
|=
mask
;
72
else
73
s->
io_bits
&= ~mask;
74
75
if
(s->
io_bits
& 0x000000ff)
76
oe |= 0x1;
77
if
(s->
io_bits
& 0x0000ff00)
78
oe |= 0x2;
79
if
(s->
io_bits
& 0x00ff0000)
80
oe |= 0x4;
81
if
(s->
io_bits
& 0xff000000)
82
oe |= 0x8;
83
84
outb
(oe, dev->
iobase
+
DT2817_CR
);
85
86
return
1;
87
}
88
89
static
int
dt2817_dio_insn_bits(
struct
comedi_device
*
dev
,
90
struct
comedi_subdevice
*
s
,
91
struct
comedi_insn
*
insn
,
unsigned
int
*
data
)
92
{
93
unsigned
int
changed
;
94
95
/* It's questionable whether it is more important in
96
* a driver like this to be deterministic or fast.
97
* We choose fast. */
98
99
if
(data[0]) {
100
changed = s->
state
;
101
s->
state
&= ~data[0];
102
s->
state
|= (data[0] & data[1]);
103
changed ^= s->
state
;
104
changed &= s->
io_bits
;
105
if
(changed & 0x000000ff)
106
outb
(s->
state
& 0xff, dev->
iobase
+
DT2817_DATA
+ 0);
107
if
(changed & 0x0000ff00)
108
outb
((s->
state
>> 8) & 0xff,
109
dev->
iobase
+
DT2817_DATA
+ 1);
110
if
(changed & 0x00ff0000)
111
outb
((s->
state
>> 16) & 0xff,
112
dev->
iobase
+
DT2817_DATA
+ 2);
113
if
(changed & 0xff000000)
114
outb
((s->
state
>> 24) & 0xff,
115
dev->
iobase
+
DT2817_DATA
+ 3);
116
}
117
data[1] =
inb
(dev->
iobase
+
DT2817_DATA
+ 0);
118
data[1] |= (
inb
(dev->
iobase
+
DT2817_DATA
+ 1) << 8);
119
data[1] |= (
inb
(dev->
iobase
+
DT2817_DATA
+ 2) << 16);
120
data[1] |= (
inb
(dev->
iobase
+
DT2817_DATA
+ 3) << 24);
121
122
return
insn->
n
;
123
}
124
125
static
int
dt2817_attach(
struct
comedi_device
*dev,
struct
comedi_devconfig
*it)
126
{
127
int
ret
;
128
struct
comedi_subdevice
*
s
;
129
unsigned
long
iobase
;
130
131
iobase = it->
options
[0];
132
printk
(
KERN_INFO
"comedi%d: dt2817: 0x%04lx "
, dev->
minor
, iobase);
133
if
(!
request_region
(iobase,
DT2817_SIZE
,
"dt2817"
)) {
134
printk
(
"I/O port conflict\n"
);
135
return
-
EIO
;
136
}
137
dev->
iobase
=
iobase
;
138
dev->
board_name
=
"dt2817"
;
139
140
ret =
comedi_alloc_subdevices
(dev, 1);
141
if
(ret)
142
return
ret
;
143
144
s = &dev->
subdevices
[0];
145
146
s->
n_chan
= 32;
147
s->
type
=
COMEDI_SUBD_DIO
;
148
s->
subdev_flags
=
SDF_READABLE
|
SDF_WRITABLE
;
149
s->
range_table
= &
range_digital
;
150
s->
maxdata
= 1;
151
s->
insn_bits
= dt2817_dio_insn_bits;
152
s->
insn_config
= dt2817_dio_insn_config;
153
154
s->
state
= 0;
155
outb
(0, dev->
iobase
+
DT2817_CR
);
156
157
printk
(
KERN_INFO
"\n"
);
158
159
return
0;
160
}
161
162
static
void
dt2817_detach(
struct
comedi_device
*dev)
163
{
164
if
(dev->
iobase
)
165
release_region
(dev->
iobase
,
DT2817_SIZE
);
166
}
167
168
static
struct
comedi_driver
dt2817_driver = {
169
.driver_name =
"dt2817"
,
170
.module =
THIS_MODULE
,
171
.attach = dt2817_attach,
172
.detach = dt2817_detach,
173
};
174
module_comedi_driver
(dt2817_driver);
175
176
MODULE_AUTHOR
(
"Comedi http://www.comedi.org"
);
177
MODULE_DESCRIPTION
(
"Comedi low-level driver"
);
178
MODULE_LICENSE
(
"GPL"
);
Generated on Thu Jan 10 2013 14:26:57 for Linux Kernel by
1.8.2