2 * Driver for Advantech PCL-730 and clones
7 Description: Advantech PCL-730 (& compatibles)
8 Author: José Luis Sánchez (jsanchezv@teleline.es)
10 Devices: [Advantech] PCL-730 (pcl730), [ICP] ISO-730 (iso730),
11 [Adlink] ACL-7130 (acl7130)
13 Interrupts are not supported.
14 The ACL-7130 card have an 8254 timer/counter not supported by this driver.
17 #include <linux/comedidev.h>
19 #include <linux/ioport.h>
22 #define ACL7130_SIZE 8
23 #define PCL730_IDIO_LO 0 /* Isolated Digital I/O low byte (ID0-ID7) */
24 #define PCL730_IDIO_HI 1 /* Isolated Digital I/O high byte (ID8-ID15) */
25 #define PCL730_DIO_LO 2 /* TTL Digital I/O low byte (D0-D7) */
26 #define PCL730_DIO_HI 3 /* TTL Digital I/O high byte (D8-D15) */
28 static int pcl730_attach(comedi_device *dev,comedi_devconfig *it);
29 static int pcl730_detach(comedi_device *dev);
32 const char *name; // board name
33 unsigned int io_range; // len of I/O space
36 static boardtype boardtypes[] =
38 { "pcl730", PCL730_SIZE, },
39 { "iso730", PCL730_SIZE, },
40 { "acl7130", ACL7130_SIZE, },
42 #define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
43 #define this_board ((boardtype *)dev->board_ptr)
45 static comedi_driver driver_pcl730 = {
46 driver_name: "pcl730",
48 attach: pcl730_attach,
49 detach: pcl730_detach,
50 board_name: &boardtypes[0].name,
51 num_names: n_boardtypes,
52 offset: sizeof(boardtype),
54 COMEDI_INITCLEANUP(driver_pcl730);
56 static int pcl730_do_insn(comedi_device *dev,comedi_subdevice *s,
57 comedi_insn *insn,lsampl_t *data)
65 s->state |= (data[0] & data[1]);
67 if( data[0] & 0x00ff )
68 outb(s->state & 0xff, dev->iobase+((unsigned long)s->private));
69 if( data[0] & 0xff00 )
70 outb((s->state >> 8), dev->iobase+((unsigned long)s->private)+1);
77 static int pcl730_di_insn(comedi_device *dev,comedi_subdevice *s,
78 comedi_insn *insn,lsampl_t *data)
83 data[1]=inb(dev->iobase+((unsigned long)s->private)) |
84 (inb(dev->iobase+((unsigned long)s->private)+1)<<8);
89 static int pcl730_attach(comedi_device *dev,comedi_devconfig *it)
95 iobase=it->options[0];
96 iorange=this_board->io_range;
97 printk("comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
98 this_board->name, iobase);
99 if( !request_region(iobase, iorange, "pcl730") ) {
100 printk("I/O port conflict\n");
103 dev->board_name=this_board->name;
107 if( alloc_subdevices(dev, 4) < 0 )
112 s->type=COMEDI_SUBD_DO;
113 s->subdev_flags=SDF_WRITABLE;
116 s->insn_bits = pcl730_do_insn;
117 s->range_table=&range_digital;
118 s->private = (void *)PCL730_IDIO_LO;
122 s->type=COMEDI_SUBD_DI;
123 s->subdev_flags=SDF_READABLE;
126 s->insn_bits = pcl730_di_insn;
127 s->range_table=&range_digital;
128 s->private = (void *)PCL730_IDIO_LO;
132 s->type=COMEDI_SUBD_DO;
133 s->subdev_flags=SDF_WRITABLE;
136 s->insn_bits = pcl730_do_insn;
137 s->range_table=&range_digital;
138 s->private = (void *)PCL730_DIO_LO;
142 s->type=COMEDI_SUBD_DI;
143 s->subdev_flags=SDF_READABLE;
146 s->insn_bits = pcl730_di_insn;
147 s->range_table=&range_digital;
148 s->private = (void *)PCL730_DIO_LO;
155 static int pcl730_detach(comedi_device *dev)
157 printk("comedi%d: pcl730: remove\n",dev->minor);
160 release_region(dev->iobase, this_board->io_range);