80 #include <linux/slab.h>
81 #include "../comedidev.h"
83 #include <linux/pci.h>
86 #define CHANS_PER_PORT 8
87 #define PORTS_PER_ASIC 6
88 #define INTR_PORTS_PER_ASIC 3
89 #define MAX_CHANS_PER_SUBDEV 24
90 #define PORTS_PER_SUBDEV (MAX_CHANS_PER_SUBDEV/CHANS_PER_PORT)
91 #define CHANS_PER_ASIC (CHANS_PER_PORT*PORTS_PER_ASIC)
92 #define INTR_CHANS_PER_ASIC 24
93 #define INTR_PORTS_PER_SUBDEV (INTR_CHANS_PER_ASIC/CHANS_PER_PORT)
94 #define MAX_DIO_CHANS (PORTS_PER_ASIC*1*CHANS_PER_PORT)
95 #define MAX_ASICS (MAX_DIO_CHANS/CHANS_PER_ASIC)
96 #define SDEV_NO ((int)(s - dev->subdevices))
97 #define CALC_N_DIO_SUBDEVS(nchans) ((nchans)/MAX_CHANS_PER_SUBDEV + (!!((nchans)%MAX_CHANS_PER_SUBDEV)) )
99 #define ASIC_IOSIZE (0x0B)
100 #define PCMMIO48_IOSIZE ASIC_IOSIZE
115 #define REG_PORT0 0x0
116 #define REG_PORT1 0x1
117 #define REG_PORT2 0x2
118 #define REG_PORT3 0x3
119 #define REG_PORT4 0x4
120 #define REG_PORT5 0x5
121 #define REG_INT_PENDING 0x6
122 #define REG_PAGELOCK 0x7
130 #define REG_ENAB0 0x8
131 #define REG_ENAB1 0x9
132 #define REG_ENAB2 0xA
133 #define REG_INT_ID0 0x8
134 #define REG_INT_ID1 0x9
135 #define REG_INT_ID2 0xA
137 #define NUM_PAGED_REGS 3
139 #define FIRST_PAGED_REG 0x8
140 #define REG_PAGE_BITOFFSET 6
141 #define REG_LOCK_BITOFFSET 0
142 #define REG_PAGE_MASK (~((0x1<<REG_PAGE_BITOFFSET)-1))
143 #define REG_LOCK_MASK (~(REG_PAGE_MASK))
146 #define PAGE_INT_ID 3
265 #define devpriv ((struct pcmmio_private *)dev->private)
266 #define subpriv ((struct pcmmio_subdev_private *)s->private)
290 #ifdef DAMMIT_ITS_BROKEN
299 unsigned long ioaddr =
subpriv->iobases[byte_no],
303 unsigned char byte = 0,
305 write_mask_byte = (data[0] >>
offset) & 0xff,
307 data_byte = (data[1] >>
offset) & 0xff;
311 #ifdef DAMMIT_ITS_BROKEN
314 (
KERN_DEBUG "byte %d wmb %02x db %02x offset %02d io %04x,"
315 " data_in %02x ", byte_no, (
unsigned)write_mask_byte,
316 (
unsigned)data_byte,
offset, ioaddr, (
unsigned)byte);
319 if (write_mask_byte) {
325 byte &= ~write_mask_byte;
327 byte |= ~data_byte & write_mask_byte;
331 #ifdef DAMMIT_ITS_BROKEN
342 #ifdef DAMMIT_ITS_BROKEN
360 unsigned long ioaddr;
364 ioaddr =
subpriv->iobases[byte_no];
442 unsigned long baseaddr =
devpriv->asics[
asic].iobase;
444 switch_page(dev, asic, 0);
454 switch_page(dev, asic, page);
457 outb(0, baseaddr + reg);
468 switch_page(dev, asic, 0);
473 static void lock_port(
struct comedi_device *dev,
int asic,
int port)
489 static void unlock_port(
struct comedi_device *dev,
int asic,
int port)
513 subpriv->dio.intr.enabled_mask = 0;
519 for (port = firstport; port < firstport + nports; ++
port) {
532 if (irq ==
devpriv->asics[asic].irq) {
534 unsigned triggered = 0;
537 unsigned char int_pend;
548 if (int_pend & (0x1 << port)) {
550 io_lines_with_edges = 0;
551 switch_page(dev, asic,
553 io_lines_with_edges =
557 if (io_lines_with_edges)
567 io_lines_with_edges <<
575 spin_unlock_irqrestore(&
devpriv->asics[asic].spinlock,
585 (
KERN_DEBUG "got edge detect interrupt %d asic %d which_chans: %06x\n",
586 irq, asic, triggered);
593 if (
subpriv->dio.intr.asic == asic) {
601 oldevents = s->
async->events;
603 if (
subpriv->dio.intr.active) {
623 async->cmd.chanlist_len;
628 if (mytrig & (1
U << ch))
648 if (!
subpriv->dio.intr.continuous) {
650 if (
subpriv->dio.intr.stop_count > 0) {
651 subpriv->dio.intr.stop_count--;
652 if (
subpriv->dio.intr.stop_count == 0) {
664 spin_unlock_irqrestore
688 if (!
subpriv->dio.intr.continuous &&
subpriv->dio.intr.stop_count == 0) {
694 unsigned bits = 0, pol_bits = 0,
n;
702 subpriv->dio.intr.enabled_mask = 0;
715 bits &= ((0x1 <<
subpriv->dio.intr.num_asic_chans) -
716 1) <<
subpriv->dio.intr.first_chan;
731 b = dev->
irq & ((1 << 4) - 1);
737 for (port = firstport; port < firstport + nports; ++
port) {
739 bits >> (
subpriv->dio.intr.first_chan + (port -
742 pol_bits >> (
subpriv->dio.intr.first_chan +
743 (port - firstport) * 8) & 0xff;
761 pcmmio_stop_intr(dev, s);
762 spin_unlock_irqrestore(&
subpriv->dio.intr.spinlock, flags);
772 unsigned int trignum)
783 event = pcmmio_start_intr(dev, s);
784 spin_unlock_irqrestore(&
subpriv->dio.intr.spinlock, flags);
807 subpriv->dio.intr.continuous = 0;
812 subpriv->dio.intr.continuous = 1;
813 subpriv->dio.intr.stop_count = 0;
820 s->
async->inttrig = pcmmio_inttrig_start_intr;
824 event = pcmmio_start_intr(dev, s);
827 spin_unlock_irqrestore(&
subpriv->dio.intr.spinlock, flags);
842 static int adc_wait_ready(
unsigned long iobase)
844 unsigned long retry = 100000;
846 if (
inb(iobase + 3) & 0x80)
856 unsigned long iobase =
subpriv->iobase;
870 for (n = 0; n < insn->
n; n++) {
873 unsigned char command_byte = 0;
874 unsigned iooffset = 0;
875 short sample, adc_adjust = 0;
878 chan -= 8, iooffset = 4;
885 command_byte |= 1 << 7;
900 command_byte |= 1 << 6;
907 command_byte |= ((chan / 2) & 0x3) << 4;
910 command_byte |= (
range & 0x3) << 2;
914 outb(command_byte, iobase + iooffset + 2);
917 adc_wait_ready(iobase + iooffset);
920 outb(command_byte, iobase + iooffset + 2);
922 adc_wait_ready(iobase + iooffset);
925 sample =
inb(iobase + iooffset + 0);
928 sample |=
inb(iobase + iooffset + 1) << 8;
929 sample += adc_adjust;
940 for (n = 0; n < insn->
n; n++) {
943 data[
n] =
subpriv->ao.shadow_samples[chan];
948 static int wait_dac_ready(
unsigned long iobase)
950 unsigned long retry = 100000
L;
959 if (
inb(iobase + 3) & 0x80)
970 unsigned iobase =
subpriv->iobase, iooffset = 0;
972 for (n = 0; n < insn->
n; n++) {
976 unsigned char command_byte = 0, range_byte =
977 range & ((1 << 4) - 1);
979 chan -= 4, iooffset += 4;
981 outb(range_byte, iobase + iooffset + 0);
982 outb(0, iobase + iooffset + 1);
985 command_byte = (chan << 1) | 0x60;
986 outb(command_byte, iobase + iooffset + 2);
988 wait_dac_ready(iobase + iooffset);
991 outb(data[n] & 0xff, iobase + iooffset + 0);
994 outb((data[n] >> 8) & 0xff, iobase + iooffset + 1);
1000 command_byte = 0x70 | (chan << 1);
1002 outb(command_byte, iobase + iooffset + 2);
1004 wait_dac_ready(iobase + iooffset);
1007 subpriv->ao.shadow_samples[chan] = data[
n];
1017 int sdev_no, chans_left, n_dio_subdevs, n_subdevs,
port,
asic,
1018 thisasic_chanct = 0;
1027 dev->
driver->driver_name, iobase);
1033 dev->
driver->driver_name)) {
1045 printk(
KERN_ERR "comedi%d: cannot allocate private data structure\n",
1064 n_subdevs = n_dio_subdevs + 2;
1069 printk(
KERN_ERR "comedi%d: cannot allocate subdevice private data structures\n",
1111 for (sdev_no = 2; sdev_no < dev->
n_subdevices; ++sdev_no) {
1124 subpriv->dio.intr.first_chan = -1;
1125 subpriv->dio.intr.asic_chan = -1;
1126 subpriv->dio.intr.num_asic_chans = -1;
1133 if (port >= PORTS_PER_ASIC) {
1136 thisasic_chanct = 0;
1141 if (thisasic_chanct <
1143 &&
subpriv->dio.intr.asic < 0) {
1150 subpriv->dio.intr.stop_count = 0;
1151 subpriv->dio.intr.first_chan = byte_no * 8;
1152 subpriv->dio.intr.asic_chan = thisasic_chanct;
1153 subpriv->dio.intr.num_asic_chans =
1155 s->
cancel = pcmmio_cancel;
1159 subpriv->dio.intr.num_asic_chans;
1186 for (i = asic - 1; i >= 0; --
i) {
1230 .ai_range_table = &ranges_ai,
1231 .ao_range_table = &ranges_ao,
1239 .driver_name =
"pcmmio",
1241 .attach = pcmmio_attach,
1242 .detach = pcmmio_detach,
1243 .board_name = &pcmmio_boards[0].
name,