4 Michal Dobes <dobes@tesnet.cz>
6 hardware driver for Advantech cards:
7 card: PCL-724, PCL-722, PCL-731
8 driver: pcl724, pcl722, pcl731
10 card: ACL-7122, ACL-7124, PET-48DIO
11 driver: acl7122, acl7124, pet48dio
13 Options for PCL-724, PCL-731, ACL-7124 and PET-48DIO:
16 Options for PCL-722 and ACL-7122:
18 [1] - IRQ (0=disable IRQ) IRQ isn't supported at this time!
20 0, 144: 144 DIO configuration
21 1, 96: 96 DIO configuration
25 Description: Advantech PCL-724, PCL-722, PCL-731 ADLink ACL-7122, ACL-7124,
27 Author: Michal Dobes <dobes@tesnet.cz>
28 Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731),
29 [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio)
32 This is driver for digital I/O boards PCL-722/724/731 with 144/24/48 DIO
33 and for digital I/O boards ACL-7122/7124/PET-48DIO with 144/24/48 DIO.
34 It need 8255.o for operations and only immediate mode is supported.
35 See the source for configuration details.
38 * check_driver overrides:
42 #include <linux/comedidev.h>
44 #include <linux/ioport.h>
45 #include <linux/delay.h>
49 #define PCL722_SIZE 32
50 #define PCL722_96_SIZE 16
57 // #define PCL724_IRQ 1 /* no IRQ support now */
59 static int pcl724_attach(comedi_device *dev,comedi_devconfig *it);
60 static int pcl724_detach(comedi_device *dev);
63 const char *name; // board name
64 int dio; // num of DIO
65 int numofports; // num of 8255 subdevices
66 unsigned int IRQbits; // allowed interrupts
67 unsigned int io_range; // len of IO space
72 static const boardtype boardtypes[] =
74 {"pcl724", 24, 1, 0x00fc, PCL724_SIZE, 0, 0, },
75 {"pcl722", 144, 6, 0x00fc, PCL722_SIZE, 1, 0, },
76 {"pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0, },
77 {"acl7122", 144, 6, 0x9ee8, PCL722_SIZE, 1, 0, },
78 {"acl7124", 24, 1, 0x00fc, PCL724_SIZE, 0, 0, },
79 {"pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1, },
82 #define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
83 #define this_board ((const boardtype *)dev->board_ptr)
85 static comedi_driver driver_pcl724={
86 driver_name: "pcl724",
88 attach: pcl724_attach,
89 detach: pcl724_detach,
90 board_name: &boardtypes[0].name,
91 num_names: n_boardtypes,
92 offset: sizeof(boardtype),
94 COMEDI_INITCLEANUP(driver_pcl724);
97 static int subdev_8255_cb(int dir,int port,int data,unsigned long arg)
99 unsigned long iobase=arg;
102 outb(data,iobase+port);
105 return inb(iobase+port);
109 static int subdev_8255mapped_cb(int dir,int port,int data,unsigned long iobase)
111 int movport=SIZE_8255*(iobase>>12);
116 outb(port+movport,iobase);
120 outb(port+movport,iobase);
121 return inb(iobase+1);
125 static int pcl724_attach(comedi_device *dev,comedi_devconfig *it)
127 unsigned long iobase;
128 unsigned int iorange;
129 int ret,i,n_subdevices;
134 iobase=it->options[0];
135 iorange=this_board->io_range;
136 if ((this_board->can_have96)&&((it->options[1]==1)||(it->options[1]==96)))
137 iorange=PCL722_96_SIZE; // PCL-724 in 96 DIO configuration
138 printk("comedi%d: pcl724: board=%s, 0x%03lx ",dev->minor,
139 this_board->name,iobase);
140 if(!request_region(iobase, iorange, "pcl724")){
141 printk("I/O port conflict\n");
147 dev->board_name = this_board->name;
151 if (this_board->IRQbits!=0) { /* board support IRQ */
153 if (irq) {/* we want to use IRQ */
154 if (((1<<irq)&this_board->IRQbits)==0) {
155 rt_printk(", IRQ %u is out of allowed range, DISABLING IT",irq);
158 if (comedi_request_irq(irq, interrupt_pcl724, 0, "pcl724", dev)) {
159 rt_printk(", unable to allocate IRQ %u, DISABLING IT", irq);
160 irq=0; /* Can't use IRQ */
162 rt_printk(", irq=%u", irq);
173 n_subdevices=this_board->numofports;
174 if ((this_board->can_have96)&&((it->options[1]==1)||(it->options[1]==96)))
175 n_subdevices=4; // PCL-724 in 96 DIO configuration
177 if((ret=alloc_subdevices(dev, n_subdevices))<0)
180 for(i=0;i<dev->n_subdevices;i++){
181 if (this_board->is_pet48) {
182 subdev_8255_init(dev,dev->subdevices+i,
183 subdev_8255mapped_cb,(unsigned long)(dev->iobase+i*0x1000));
185 subdev_8255_init(dev,dev->subdevices+i,
186 subdev_8255_cb,(unsigned long)(dev->iobase+SIZE_8255*i));
193 static int pcl724_detach(comedi_device *dev)
197 // printk("comedi%d: pcl724: remove\n",dev->minor);
199 for(i=0;i<dev->n_subdevices;i++){
200 subdev_8255_cleanup(dev,dev->subdevices+i);
205 comedi_free_irq(dev->irq,dev);
209 release_region(dev->iobase,this_board->io_range);