![]() |
RTXI 1.3
|
00001 /* 00002 00003 comedi/drivers/aio_iiro_16.c 00004 00005 Driver for Acces I/O Products PC-104 AIO-IIRO-16 Digital I/O board 00006 Copyright (C) 2006 C&C Technologies, Inc. 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 2 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program; if not, write to the Free Software 00020 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00021 */ 00022 00023 /* 00024 00025 Driver: aio_iiro_16 00026 Description: Acces I/O Products PC-104 IIRO16 Relay And Isolated Input Board 00027 Author: Zachary Ware <zach.ware@cctechnol.com> 00028 Devices: 00029 [Acces I/O] PC-104 AIO12-8 00030 Status: experimental 00031 00032 Configuration Options: 00033 [0] - I/O port base address 00034 00035 */ 00036 00037 #include <linux/comedidev.h> 00038 #include <linux/ioport.h> 00039 00040 #define AIO_IIRO_16_SIZE 0x08 00041 #define AIO_IIRO_16_RELAY_0_7 0x00 00042 #define AIO_IIRO_16_INPUT_0_7 0x01 00043 #define AIO_IIRO_16_IRQ 0x02 00044 #define AIO_IIRO_16_RELAY_8_15 0x04 00045 #define AIO_IIRO_16_INPUT_8_15 0x05 00046 00047 typedef struct aio_iiro_16_board_struct { 00048 const char *name; 00049 int do_; 00050 int di; 00051 } aio_iiro_16_board; 00052 00053 static const aio_iiro_16_board aio_iiro_16_boards[] = { 00054 { 00055 name: "aio_iiro_16", 00056 di: 16, 00057 do_: 16}, 00058 }; 00059 00060 #define thisboard ((const aio_iiro_16_board *) dev->board_ptr) 00061 00062 typedef struct { 00063 int data; 00064 struct pci_dev *pci_dev; 00065 lsampl_t ao_readback[2]; 00066 } aio_iiro_16_private; 00067 00068 #define devpriv ((aio_iiro_16_private *) dev->private) 00069 00070 static int aio_iiro_16_attach(comedi_device * dev, comedi_devconfig * it); 00071 00072 static int aio_iiro_16_detach(comedi_device * dev); 00073 00074 static comedi_driver driver_aio_iiro_16 = { 00075 driver_name:"aio_iiro_16", 00076 module:THIS_MODULE, 00077 attach:aio_iiro_16_attach, 00078 detach:aio_iiro_16_detach, 00079 board_name:&aio_iiro_16_boards[0].name, 00080 offset:sizeof(aio_iiro_16_board), 00081 num_names:sizeof(aio_iiro_16_boards) / sizeof(aio_iiro_16_board), 00082 }; 00083 00084 static int aio_iiro_16_dio_insn_bits_read(comedi_device * dev, 00085 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data); 00086 00087 static int aio_iiro_16_dio_insn_bits_write(comedi_device * dev, 00088 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data); 00089 00090 static int aio_iiro_16_attach(comedi_device * dev, comedi_devconfig * it) 00091 { 00092 int iobase; 00093 comedi_subdevice *s; 00094 00095 printk("comedi%d: aio_iiro_16: ", dev->minor); 00096 00097 dev->board_name = thisboard->name; 00098 00099 iobase = it->options[0]; 00100 00101 if (!request_region(iobase, AIO_IIRO_16_SIZE, dev->board_name)) { 00102 printk("I/O port conflict"); 00103 return -EIO; 00104 } 00105 00106 dev->iobase = iobase; 00107 00108 if (alloc_private(dev, sizeof(aio_iiro_16_private)) < 0) 00109 return -ENOMEM; 00110 00111 if (alloc_subdevices(dev, 2) < 0) 00112 return -ENOMEM; 00113 00114 s = dev->subdevices + 0; 00115 s->type = COMEDI_SUBD_DIO; 00116 s->subdev_flags = SDF_WRITABLE; 00117 s->n_chan = 16; 00118 s->maxdata = 1; 00119 s->range_table = &range_digital; 00120 s->insn_bits = aio_iiro_16_dio_insn_bits_write; 00121 00122 s = dev->subdevices + 1; 00123 s->type = COMEDI_SUBD_DIO; 00124 s->subdev_flags = SDF_READABLE; 00125 s->n_chan = 16; 00126 s->maxdata = 1; 00127 s->range_table = &range_digital; 00128 s->insn_bits = aio_iiro_16_dio_insn_bits_read; 00129 00130 printk("attached\n"); 00131 00132 return 1; 00133 } 00134 00135 static int aio_iiro_16_detach(comedi_device * dev) 00136 { 00137 printk("comedi%d: aio_iiro_16: remove\n", dev->minor); 00138 00139 if (dev->iobase) 00140 release_region(dev->iobase, AIO_IIRO_16_SIZE); 00141 00142 return 0; 00143 } 00144 00145 static int aio_iiro_16_dio_insn_bits_write(comedi_device * dev, 00146 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data) 00147 { 00148 if (insn->n != 2) 00149 return -EINVAL; 00150 00151 if (data[0]) { 00152 s->state &= ~data[0]; 00153 s->state |= data[0] & data[1]; 00154 outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7); 00155 outb((s->state >> 8) & 0xff, 00156 dev->iobase + AIO_IIRO_16_RELAY_8_15); 00157 } 00158 00159 data[1] = s->state; 00160 00161 return 2; 00162 } 00163 00164 static int aio_iiro_16_dio_insn_bits_read(comedi_device * dev, 00165 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data) 00166 { 00167 if (insn->n != 2) 00168 return -EINVAL; 00169 00170 data[1] = 0; 00171 data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7); 00172 data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8; 00173 00174 return 2; 00175 } 00176 00177 COMEDI_INITCLEANUP(driver_aio_iiro_16);