This source file includes following definitions.
- dnp_dio_insn_bits
- dnp_dio_insn_config
- dnp_attach
- dnp_detach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <linux/module.h>
22 #include "../comedidev.h"
23
24
25
26
27
28
29
30
31
32 #define CSCIR 0x22
33 #define CSCDR 0x23
34 #define PAMR 0xa5
35 #define PADR 0xa9
36 #define PBMR 0xa4
37 #define PBDR 0xa8
38 #define PCMR 0xa3
39 #define PCDR 0xa7
40
41 static int dnp_dio_insn_bits(struct comedi_device *dev,
42 struct comedi_subdevice *s,
43 struct comedi_insn *insn,
44 unsigned int *data)
45 {
46 unsigned int mask;
47 unsigned int val;
48
49
50
51
52
53
54
55 mask = comedi_dio_update_state(s, data);
56 if (mask) {
57 outb(PADR, CSCIR);
58 outb(s->state & 0xff, CSCDR);
59
60 outb(PBDR, CSCIR);
61 outb((s->state >> 8) & 0xff, CSCDR);
62
63 outb(PCDR, CSCIR);
64 val = inb(CSCDR) & 0x0f;
65 outb(((s->state >> 12) & 0xf0) | val, CSCDR);
66 }
67
68 outb(PADR, CSCIR);
69 val = inb(CSCDR);
70 outb(PBDR, CSCIR);
71 val |= (inb(CSCDR) << 8);
72 outb(PCDR, CSCIR);
73 val |= ((inb(CSCDR) & 0xf0) << 12);
74
75 data[1] = val;
76
77 return insn->n;
78 }
79
80 static int dnp_dio_insn_config(struct comedi_device *dev,
81 struct comedi_subdevice *s,
82 struct comedi_insn *insn,
83 unsigned int *data)
84 {
85 unsigned int chan = CR_CHAN(insn->chanspec);
86 unsigned int mask;
87 unsigned int val;
88 int ret;
89
90 ret = comedi_dio_insn_config(dev, s, insn, data, 0);
91 if (ret)
92 return ret;
93
94 if (chan < 8) {
95 mask = 1 << chan;
96 outb(PAMR, CSCIR);
97 } else if (chan < 16) {
98 mask = 1 << (chan - 8);
99 outb(PBMR, CSCIR);
100 } else {
101
102
103
104
105
106
107
108
109
110 mask = 1 << ((chan - 16) * 2);
111 outb(PCMR, CSCIR);
112 }
113
114 val = inb(CSCDR);
115 if (data[0] == COMEDI_OUTPUT)
116 val |= mask;
117 else
118 val &= ~mask;
119 outb(val, CSCDR);
120
121 return insn->n;
122 }
123
124 static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
125 {
126 struct comedi_subdevice *s;
127 int ret;
128
129
130
131
132
133
134
135 ret = comedi_alloc_subdevices(dev, 1);
136 if (ret)
137 return ret;
138
139 s = &dev->subdevices[0];
140
141 s->type = COMEDI_SUBD_DIO;
142 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
143 s->n_chan = 20;
144 s->maxdata = 1;
145 s->range_table = &range_digital;
146 s->insn_bits = dnp_dio_insn_bits;
147 s->insn_config = dnp_dio_insn_config;
148
149
150 outb(PAMR, CSCIR);
151 outb(0x00, CSCDR);
152 outb(PBMR, CSCIR);
153 outb(0x00, CSCDR);
154 outb(PCMR, CSCIR);
155 outb((inb(CSCDR) & 0xAA), CSCDR);
156
157 return 0;
158 }
159
160 static void dnp_detach(struct comedi_device *dev)
161 {
162 outb(PAMR, CSCIR);
163 outb(0x00, CSCDR);
164 outb(PBMR, CSCIR);
165 outb(0x00, CSCDR);
166 outb(PCMR, CSCIR);
167 outb((inb(CSCDR) & 0xAA), CSCDR);
168 }
169
170 static struct comedi_driver dnp_driver = {
171 .driver_name = "dnp-1486",
172 .module = THIS_MODULE,
173 .attach = dnp_attach,
174 .detach = dnp_detach,
175 };
176 module_comedi_driver(dnp_driver);
177
178 MODULE_AUTHOR("Comedi http://www.comedi.org");
179 MODULE_DESCRIPTION("Comedi low-level driver");
180 MODULE_LICENSE("GPL");