45 #include "../comedidev.h"
47 #include <linux/slab.h>
49 #define DRIVER_NAME "unioxx5"
50 #define UNIOXX5_SIZE 0x10
51 #define UNIOXX5_SUBDEV_BASE 0xA000
52 #define UNIOXX5_SUBDEV_ODDS 0x400
55 #define MODULE_DIGITAL 0
56 #define MODULE_OUTPUT_MASK 0x80
59 #define UNIOXX5_NUM_OF_CHANS 24
68 #define Rx2CA_ERR_MASK 0x04
69 #define Rx4CA_ERR_MASK 0x08
73 #define ALL_2_OUTPUT 1
86 static int __unioxx5_define_chan_offset(
int chan_num)
89 if (chan_num < 0 || chan_num > 23)
92 return (chan_num >> 3) + 1;
101 printk(
"COMEDI: mode = %d\n", mask);
105 for (i = 0; i < 3; i++)
115 int chan_a, chan_b, conf, channel_offset;
117 channel_offset = __unioxx5_define_chan_offset(channel);
122 if (channel % 2 == 0) {
123 chan_a <<= channel & 0x07;
124 chan_b <<= (channel + 1) & 0x07;
126 chan_a <<= (channel - 1) & 0x07;
127 chan_b <<= channel & 0x07;
141 unsigned int *
data,
int channel,
int minor)
143 int channel_offset, mask = 1 << (channel & 0x07);
145 channel_offset = __unioxx5_define_chan_offset(channel);
146 if (channel_offset < 0) {
148 "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
157 if (channel_offset > 1)
158 channel -= 2 << channel_offset;
164 unsigned int *data,
int channel,
int minor)
166 int module_no, read_ch;
169 module_no = channel / 2;
170 read_ch = channel % 2;
175 "comedi%d: module in position %d with id 0x%02x is for output only",
180 __unioxx5_analog_config(usp, channel);
192 printk(
"COMEDI: 4 bytes error\n");
205 unsigned int *data,
int channel,
int minor)
207 int channel_offset,
val;
208 int mask = 1 << (channel & 0x07);
210 channel_offset = __unioxx5_define_chan_offset(channel);
211 if (channel_offset < 0) {
213 "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
234 unsigned int *data,
int channel,
int minor)
238 module = channel / 2;
239 i = (channel % 2) << 1;
244 "comedi%d: module in position %d with id 0x%0x is for input only!\n",
249 __unioxx5_analog_config(usp, channel);
261 for (i = 0; i < 4; i++) {
282 if (!__unioxx5_digital_read(usp, data, channel, dev->
minor))
285 if (!__unioxx5_analog_read(usp, data, channel, dev->
minor))
304 if (!__unioxx5_digital_write(usp, data, channel, dev->
minor))
307 if (!__unioxx5_analog_write(usp, data, channel, dev->
minor))
321 int mask = 1 << (channel & 0x07);
327 "comedi%d: channel configuration accessible only for digital modules\n",
332 channel_offset = __unioxx5_define_chan_offset(channel);
333 if (channel_offset < 0) {
335 "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
336 dev->
minor, channel);
372 int subdev_iobase,
int minor)
375 int i, to, ndef_flag = 0;
393 for (i = 0; i < 12; i++) {
396 __unioxx5_analog_config(usp, i * 2);
398 outb(i + 1, subdev_iobase + 5);
399 outb(
'H', subdev_iobase + 6);
400 while (!(
inb(subdev_iobase + 0) &
TxBE))
402 outb(0, subdev_iobase + 6);
405 while (!(
inb(subdev_iobase + 0) &
Rx2CA)) {
459 if (
id !=
'g' || num != 1)
468 "your card must has at least 2 'g01' subdevices\n");
478 if (__unioxx5_subdev_init(&dev->
subdevices[i], iobase,
504 .attach = unioxx5_attach,
505 .detach = unioxx5_detach,