/* Register offset definitions */
/* Advantech PCI-1730/3/4 */
-#define PCI1730_IDI 0 /* R: Isolated digital input 0-15 */
-#define PCI1730_IDO 0 /* W: Isolated digital output 0-15 */
-#define PCI1730_DI 2 /* R: Digital input 0-15 */
-#define PCI1730_DO 2 /* W: Digital output 0-15 */
-#define PCI1733_IDI 0 /* R: Isolated digital input 0-31 */
#define PCI1730_3_INT_EN 0x08 /* R/W: enable/disable interrupts */
#define PCI1730_3_INT_RF 0x0c /* R/W: set falling/raising edge for
* interrupts */
#define PCI1730_3_INT_CLR 0x10 /* R/W: clear interrupts */
-#define PCI1734_IDO 0 /* W: Isolated digital output 0-31 */
-#define PCI173x_BOARDID 4 /* R: Board I/D switch for 1730/3/4 */
-
-/* Advantech PCI-1735U */
-#define PCI1735_DI 0 /* R: Digital input 0-31 */
-#define PCI1735_DO 0 /* W: Digital output 0-31 */
-#define PCI1735_C8254 4 /* R/W: 8254 counter */
-#define PCI1735_BOARDID 8 /* R: Board I/D switch for 1735U */
/* Advantech PCI-1736UP */
-#define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */
-#define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */
#define PCI1736_3_INT_EN 0x08 /* R/W: enable/disable interrupts */
#define PCI1736_3_INT_RF 0x0c /* R/W: set falling/raising edge for
* interrupts */
#define PCI1736_3_INT_CLR 0x10 /* R/W: clear interrupts */
-#define PCI1736_BOARDID 4 /* R: Board I/D switch for 1736UP */
/* Advantech PCI-1739U */
-#define PCI1739_DIO 0 /* R/W: begin of 8255 registers block */
#define PCI1739_ICR 32 /* W: Interrupt control register */
#define PCI1739_ISR 32 /* R: Interrupt status register */
-#define PCI1739_BOARDID 8 /* R: Board I/D switch for 1739U */
/* Advantech PCI-1750 */
-#define PCI1750_IDI 0 /* R: Isolated digital input 0-15 */
-#define PCI1750_IDO 0 /* W: Isolated digital output 0-15 */
#define PCI1750_ICR 32 /* W: Interrupt control register */
#define PCI1750_ISR 32 /* R: Interrupt status register */
/* Advantech PCI-1751/3/3E */
-#define PCI1751_DIO 0 /* R/W: begin of 8255 registers block */
-#define PCI1751_CNT 24 /* R/W: begin of 8254 registers block */
#define PCI1751_ICR 32 /* W: Interrupt control register */
#define PCI1751_ISR 32 /* R: Interrupt status register */
-#define PCI1753_DIO 0 /* R/W: begin of 8255 registers block */
#define PCI1753_ICR0 16 /* R/W: Interrupt control register group 0 */
#define PCI1753_ICR1 17 /* R/W: Interrupt control register group 1 */
#define PCI1753_ICR2 18 /* R/W: Interrupt control register group 2 */
#define PCI1753_ICR3 19 /* R/W: Interrupt control register group 3 */
-#define PCI1753E_DIO 32 /* R/W: begin of 8255 registers block */
#define PCI1753E_ICR0 48 /* R/W: Interrupt control register group 0 */
#define PCI1753E_ICR1 49 /* R/W: Interrupt control register group 1 */
#define PCI1753E_ICR2 50 /* R/W: Interrupt control register group 2 */
#define PCI1753E_ICR3 51 /* R/W: Interrupt control register group 3 */
/* Advantech PCI-1752/4/6 */
-#define PCI1752_IDO 0 /* R/W: Digital output 0-31 */
-#define PCI1752_IDO2 4 /* R/W: Digital output 32-63 */
-#define PCI1754_IDI 0 /* R: Digital input 0-31 */
-#define PCI1754_IDI2 4 /* R: Digital input 32-64 */
-#define PCI1756_IDI 0 /* R: Digital input 0-31 */
-#define PCI1756_IDO 4 /* R/W: Digital output 0-31 */
#define PCI1754_6_ICR0 0x08 /* R/W: Interrupt control register group 0 */
#define PCI1754_6_ICR1 0x0a /* R/W: Interrupt control register group 1 */
#define PCI1754_ICR2 0x0c /* R/W: Interrupt control register group 2 */
#define PCI1754_ICR3 0x0e /* R/W: Interrupt control register group 3 */
#define PCI1752_6_CFC 0x12 /* R/W: set/read channel freeze function */
-#define PCI175x_BOARDID 0x10 /* R: Board I/D switch for 1752/4/6 */
/* Advantech PCI-1762 registers */
-#define PCI1762_RO 0 /* R/W: Relays status/output */
-#define PCI1762_IDI 2 /* R: Isolated input status */
-#define PCI1762_BOARDID 4 /* R: Board I/D switch */
#define PCI1762_ICR 6 /* W: Interrupt control register */
#define PCI1762_ISR 6 /* R: Interrupt status register */
struct diosubd_data {
- int chans; /* num of chans */
- int addr; /* PCI address ofset */
- int regs; /* number of registers to read or 8255
- subdevices */
+ int chans; /* num of chans or 8255 devices */
+ unsigned long addr; /* PCI address ofset */
};
struct dio_boardtype {
struct diosubd_data sdi[MAX_DI_SUBDEVS]; /* DI chans */
struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */
struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */
- struct diosubd_data boardid; /* card supports board ID switch */
+ unsigned long id_reg;
unsigned long timer_regbase;
unsigned int is_16bit:1;
};
.name = "pci1730",
.cardtype = TYPE_PCI1730,
.nsubdevs = 5,
- .sdi[0] = { 16, PCI1730_DI, 2, },
- .sdi[1] = { 16, PCI1730_IDI, 2, },
- .sdo[0] = { 16, PCI1730_DO, 2, },
- .sdo[1] = { 16, PCI1730_IDO, 2, },
- .boardid = { 4, PCI173x_BOARDID, 1, },
+ .sdi[0] = { 16, 0x02, }, /* DI 0-15 */
+ .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */
+ .sdo[0] = { 16, 0x02, }, /* DO 0-15 */
+ .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
+ .id_reg = 0x04,
},
[TYPE_PCI1733] = {
.name = "pci1733",
.cardtype = TYPE_PCI1733,
.nsubdevs = 2,
- .sdi[1] = { 32, PCI1733_IDI, 4, },
- .boardid = { 4, PCI173x_BOARDID, 1, },
+ .sdi[1] = { 32, 0x00, }, /* ISO DI 0-31 */
+ .id_reg = 0x04,
},
[TYPE_PCI1734] = {
.name = "pci1734",
.cardtype = TYPE_PCI1734,
.nsubdevs = 2,
- .sdo[1] = { 32, PCI1734_IDO, 4, },
- .boardid = { 4, PCI173x_BOARDID, 1, },
+ .sdo[1] = { 32, 0x00, }, /* ISO DO 0-31 */
+ .id_reg = 0x04,
},
[TYPE_PCI1735] = {
.name = "pci1735",
.cardtype = TYPE_PCI1735,
.nsubdevs = 4,
- .sdi[0] = { 32, PCI1735_DI, 4, },
- .sdo[0] = { 32, PCI1735_DO, 4, },
- .boardid = { 4, PCI1735_BOARDID, 1, },
- .timer_regbase = PCI1735_C8254,
+ .sdi[0] = { 32, 0x00, }, /* DI 0-31 */
+ .sdo[0] = { 32, 0x00, }, /* DO 0-31 */
+ .id_reg = 0x08,
+ .timer_regbase = 0x04,
},
[TYPE_PCI1736] = {
.name = "pci1736",
.cardtype = TYPE_PCI1736,
.nsubdevs = 3,
- .sdi[1] = { 16, PCI1736_IDI, 2, },
- .sdo[1] = { 16, PCI1736_IDO, 2, },
- .boardid = { 4, PCI1736_BOARDID, 1, },
+ .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */
+ .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
+ .id_reg = 0x04,
},
[TYPE_PCI1739] = {
.name = "pci1739",
.cardtype = TYPE_PCI1739,
- .nsubdevs = 2,
- .sdio[0] = { 48, PCI1739_DIO, 2, },
+ .nsubdevs = 3,
+ .sdio[0] = { 2, 0x00, }, /* 8255 DIO */
+ .id_reg = 0x08,
},
[TYPE_PCI1750] = {
.name = "pci1750",
.cardtype = TYPE_PCI1750,
.nsubdevs = 2,
- .sdi[1] = { 16, PCI1750_IDI, 2, },
- .sdo[1] = { 16, PCI1750_IDO, 2, },
+ .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */
+ .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
},
[TYPE_PCI1751] = {
.name = "pci1751",
.cardtype = TYPE_PCI1751,
.nsubdevs = 3,
- .sdio[0] = { 48, PCI1751_DIO, 2, },
- .timer_regbase = PCI1751_CNT,
+ .sdio[0] = { 2, 0x00, }, /* 8255 DIO */
+ .timer_regbase = 0x18,
},
[TYPE_PCI1752] = {
.name = "pci1752",
.cardtype = TYPE_PCI1752,
.nsubdevs = 3,
- .sdo[0] = { 32, PCI1752_IDO, 2, },
- .sdo[1] = { 32, PCI1752_IDO2, 2, },
- .boardid = { 4, PCI175x_BOARDID, 1, },
+ .sdo[0] = { 32, 0x00, }, /* DO 0-31 */
+ .sdo[1] = { 32, 0x04, }, /* DO 32-63 */
+ .id_reg = 0x10,
.is_16bit = 1,
},
[TYPE_PCI1753] = {
.name = "pci1753",
.cardtype = TYPE_PCI1753,
.nsubdevs = 4,
- .sdio[0] = { 96, PCI1753_DIO, 4, },
+ .sdio[0] = { 4, 0x00, }, /* 8255 DIO */
},
[TYPE_PCI1753E] = {
.name = "pci1753e",
.cardtype = TYPE_PCI1753E,
.nsubdevs = 8,
- .sdio[0] = { 96, PCI1753_DIO, 4, },
- .sdio[1] = { 96, PCI1753E_DIO, 4, },
+ .sdio[0] = { 4, 0x00, }, /* 8255 DIO */
+ .sdio[1] = { 4, 0x20, }, /* 8255 DIO */
},
[TYPE_PCI1754] = {
.name = "pci1754",
.cardtype = TYPE_PCI1754,
.nsubdevs = 3,
- .sdi[0] = { 32, PCI1754_IDI, 2, },
- .sdi[1] = { 32, PCI1754_IDI2, 2, },
- .boardid = { 4, PCI175x_BOARDID, 1, },
+ .sdi[0] = { 32, 0x00, }, /* DI 0-31 */
+ .sdi[1] = { 32, 0x04, }, /* DI 32-63 */
+ .id_reg = 0x10,
.is_16bit = 1,
},
[TYPE_PCI1756] = {
.name = "pci1756",
.cardtype = TYPE_PCI1756,
.nsubdevs = 3,
- .sdi[1] = { 32, PCI1756_IDI, 2, },
- .sdo[1] = { 32, PCI1756_IDO, 2, },
- .boardid = { 4, PCI175x_BOARDID, 1, },
+ .sdi[1] = { 32, 0x00, }, /* DI 0-31 */
+ .sdo[1] = { 32, 0x04, }, /* DO 0-31 */
+ .id_reg = 0x10,
.is_16bit = 1,
},
[TYPE_PCI1762] = {
.name = "pci1762",
.cardtype = TYPE_PCI1762,
.nsubdevs = 3,
- .sdi[1] = { 16, PCI1762_IDI, 1, },
- .sdo[1] = { 16, PCI1762_RO, 1, },
- .boardid = { 4, PCI1762_BOARDID, 1, },
+ .sdi[1] = { 16, 0x02, }, /* ISO DI 0-15 */
+ .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
+ .id_reg = 0x04,
.is_16bit = 1,
},
};
static int pci_dio_insn_bits_di_b(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- const struct diosubd_data *d = (const struct diosubd_data *)s->private;
- int i;
+ unsigned long reg = (unsigned long)s->private;
+ unsigned long iobase = dev->iobase + reg;
- data[1] = 0;
- for (i = 0; i < d->regs; i++)
- data[1] |= inb(dev->iobase + d->addr + i) << (8 * i);
+ data[1] = inb(iobase);
+ if (s->n_chan > 8)
+ data[1] |= (inb(iobase + 1) << 8);
+ if (s->n_chan > 16)
+ data[1] |= (inb(iobase + 2) << 16);
+ if (s->n_chan > 24)
+ data[1] |= (inb(iobase + 3) << 24);
return insn->n;
}
static int pci_dio_insn_bits_di_w(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- const struct diosubd_data *d = (const struct diosubd_data *)s->private;
- int i;
+ unsigned long reg = (unsigned long)s->private;
+ unsigned long iobase = dev->iobase + reg;
- data[1] = 0;
- for (i = 0; i < d->regs; i++)
- data[1] |= inw(dev->iobase + d->addr + 2 * i) << (16 * i);
+ data[1] = inw(iobase);
+ if (s->n_chan > 16)
+ data[1] |= (inw(iobase + 2) << 16);
return insn->n;
}
struct comedi_insn *insn,
unsigned int *data)
{
- const struct diosubd_data *d = (const struct diosubd_data *)s->private;
- int i;
+ unsigned long reg = (unsigned long)s->private;
+ unsigned long iobase = dev->iobase + reg;
if (comedi_dio_update_state(s, data)) {
- for (i = 0; i < d->regs; i++)
- outb((s->state >> (8 * i)) & 0xff,
- dev->iobase + d->addr + i);
+ outb(s->state & 0xff, iobase);
+ if (s->n_chan > 8)
+ outb((s->state >> 8) & 0xff, iobase + 1);
+ if (s->n_chan > 16)
+ outb((s->state >> 16) & 0xff, iobase + 2);
+ if (s->n_chan > 24)
+ outb((s->state >> 24) & 0xff, iobase + 3);
}
data[1] = s->state;
struct comedi_insn *insn,
unsigned int *data)
{
- const struct diosubd_data *d = (const struct diosubd_data *)s->private;
- int i;
+ unsigned long reg = (unsigned long)s->private;
+ unsigned long iobase = dev->iobase + reg;
if (comedi_dio_update_state(s, data)) {
- for (i = 0; i < d->regs; i++)
- outw((s->state >> (16 * i)) & 0xffff,
- dev->iobase + d->addr + 2 * i);
+ outw(s->state & 0xffff, iobase);
+ if (s->n_chan > 16)
+ outw((s->state >> 16) & 0xffff, iobase + 2);
}
data[1] = s->state;
{
const struct dio_boardtype *board = dev->board_ptr;
+ /* disable channel freeze function on the PCI-1752/1756 boards */
+ if (board->cardtype == TYPE_PCI1752 || board->cardtype == TYPE_PCI1756)
+ outw(0, dev->iobase + PCI1752_6_CFC);
+
switch (board->cardtype) {
case TYPE_PCI1730:
- outb(0, dev->iobase + PCI1730_DO); /* clear outputs */
- outb(0, dev->iobase + PCI1730_DO + 1);
- outb(0, dev->iobase + PCI1730_IDO);
- outb(0, dev->iobase + PCI1730_IDO + 1);
- /* fallthrough */
case TYPE_PCI1733:
/* disable interrupts */
outb(0, dev->iobase + PCI1730_3_INT_EN);
/* set rising edge trigger */
outb(0, dev->iobase + PCI1730_3_INT_RF);
break;
- case TYPE_PCI1734:
- outb(0, dev->iobase + PCI1734_IDO); /* clear outputs */
- outb(0, dev->iobase + PCI1734_IDO + 1);
- outb(0, dev->iobase + PCI1734_IDO + 2);
- outb(0, dev->iobase + PCI1734_IDO + 3);
- break;
- case TYPE_PCI1735:
- outb(0, dev->iobase + PCI1735_DO); /* clear outputs */
- outb(0, dev->iobase + PCI1735_DO + 1);
- outb(0, dev->iobase + PCI1735_DO + 2);
- outb(0, dev->iobase + PCI1735_DO + 3);
- break;
-
case TYPE_PCI1736:
- outb(0, dev->iobase + PCI1736_IDO);
- outb(0, dev->iobase + PCI1736_IDO + 1);
/* disable interrupts */
outb(0, dev->iobase + PCI1736_3_INT_EN);
/* clear interrupts */
/* set rising edge trigger */
outb(0, dev->iobase + PCI1736_3_INT_RF);
break;
-
case TYPE_PCI1739:
/* disable & clear interrupts */
outb(0x88, dev->iobase + PCI1739_ICR);
break;
-
case TYPE_PCI1750:
case TYPE_PCI1751:
/* disable & clear interrupts */
outb(0x88, dev->iobase + PCI1750_ICR);
break;
- case TYPE_PCI1752:
- outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze
- * function */
- outw(0, dev->iobase + PCI1752_IDO); /* clear outputs */
- outw(0, dev->iobase + PCI1752_IDO + 2);
- outw(0, dev->iobase + PCI1752_IDO2);
- outw(0, dev->iobase + PCI1752_IDO2 + 2);
- break;
case TYPE_PCI1753E:
outb(0x88, dev->iobase + PCI1753E_ICR0); /* disable & clear
* interrupts */
outw(0x08, dev->iobase + PCI1754_ICR3);
break;
case TYPE_PCI1756:
- outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze
- * function */
outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear
* interrupts */
outw(0x08, dev->iobase + PCI1754_6_ICR1);
- outw(0, dev->iobase + PCI1756_IDO); /* clear outputs */
- outw(0, dev->iobase + PCI1756_IDO + 2);
break;
case TYPE_PCI1762:
outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear
* interrupts */
break;
+ default:
+ break;
}
return 0;
else
dev->iobase = pci_resource_start(pcidev, 2);
+ pci_dio_reset(dev);
+
ret = comedi_alloc_subdevices(dev, board->nsubdevs);
if (ret)
return ret;
s->insn_bits = board->is_16bit
? pci_dio_insn_bits_di_w
: pci_dio_insn_bits_di_b;
- s->private = (void *)d;
+ s->private = (void *)d->addr;
}
}
s->insn_bits = board->is_16bit
? pci_dio_insn_bits_do_w
: pci_dio_insn_bits_do_b;
- s->private = (void *)d;
+ s->private = (void *)d->addr;
+
+ /* reset all outputs to 0 */
+ if (board->is_16bit) {
+ outw(0, dev->iobase + d->addr);
+ if (s->n_chan > 16)
+ outw(0, dev->iobase + d->addr + 2);
+ } else {
+ outb(0, dev->iobase + d->addr);
+ if (s->n_chan > 8)
+ outb(0, dev->iobase + d->addr + 1);
+ if (s->n_chan > 16)
+ outb(0, dev->iobase + d->addr + 2);
+ if (s->n_chan > 24)
+ outb(0, dev->iobase + d->addr + 3);
+ }
}
}
for (i = 0; i < MAX_DIO_SUBDEVG; i++) {
d = &board->sdio[i];
- for (j = 0; j < d->regs; j++) {
+ for (j = 0; j < d->chans; j++) {
s = &dev->subdevices[subdev++];
ret = subdev_8255_init(dev, s, NULL,
d->addr + j * I8255_SIZE);
}
}
- d = &board->boardid;
- if (d->chans) {
+ if (board->id_reg) {
s = &dev->subdevices[subdev++];
s->type = COMEDI_SUBD_DI;
s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
- s->n_chan = d->chans;
+ s->n_chan = 4;
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = board->is_16bit ? pci_dio_insn_bits_di_w
: pci_dio_insn_bits_di_b;
- s->private = (void *)d;
+ s->private = (void *)board->id_reg;
}
if (board->timer_regbase) {
comedi_8254_subdevice_init(s, dev->pacer);
}
- pci_dio_reset(dev);
-
return 0;
}
-static void pci_dio_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- pci_dio_reset(dev);
- comedi_pci_detach(dev);
-}
-
static struct comedi_driver adv_pci_dio_driver = {
.driver_name = "adv_pci_dio",
.module = THIS_MODULE,
.auto_attach = pci_dio_auto_attach,
- .detach = pci_dio_detach,
+ .detach = comedi_pci_detach,
};
static int adv_pci_dio_pci_probe(struct pci_dev *dev,