![]() |
RTXI 1.3
|
00001 /* 00002 comedi/drivers/contec_pci_dio.c 00003 00004 COMEDI - Linux Control and Measurement Device Interface 00005 Copyright (C) 2000 David A. Schleef <ds@schleef.org> 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 00021 */ 00022 /* 00023 Driver: contec_pci_dio 00024 Description: Contec PIO1616L digital I/O board 00025 Devices: [Contec] PIO1616L (contec_pci_dio) 00026 Author: Stefano Rivoir <s.rivoir@gts.it> 00027 Updated: Wed, 27 Jun 2007 13:00:06 +0100 00028 Status: works 00029 00030 Configuration Options: 00031 [0] - PCI bus of device (optional) 00032 [1] - PCI slot of device (optional) 00033 If bus/slot is not specified, the first supported 00034 PCI device found will be used. 00035 */ 00036 00037 #include <linux/comedidev.h> 00038 00039 #include "comedi_pci.h" 00040 00041 typedef enum contec_model { 00042 PIO1616L = 0, 00043 } contec_model; 00044 00045 typedef struct contec_board { 00046 const char *name; 00047 int model; 00048 int in_ports; 00049 int out_ports; 00050 int in_offs; 00051 int out_offs; 00052 int out_boffs; 00053 } contec_board; 00054 static const contec_board contec_boards[] = { 00055 {"PIO1616L", PIO1616L, 16, 16, 0, 2, 10}, 00056 }; 00057 00058 #define PCI_DEVICE_ID_PIO1616L 0x8172 00059 static DEFINE_PCI_DEVICE_TABLE(contec_pci_table) = { 00060 {PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L, PCI_ANY_ID, PCI_ANY_ID, 00061 0, 0, PIO1616L}, 00062 {0} 00063 }; 00064 00065 MODULE_DEVICE_TABLE(pci, contec_pci_table); 00066 00067 #define thisboard ((const contec_board *)dev->board_ptr) 00068 00069 typedef struct { 00070 int data; 00071 00072 struct pci_dev *pci_dev; 00073 00074 } contec_private; 00075 00076 #define devpriv ((contec_private *)dev->private) 00077 00078 static int contec_attach(comedi_device * dev, comedi_devconfig * it); 00079 static int contec_detach(comedi_device * dev); 00080 static comedi_driver driver_contec = { 00081 driver_name:"contec_pci_dio", 00082 module:THIS_MODULE, 00083 attach:contec_attach, 00084 detach:contec_detach, 00085 }; 00086 00087 /* Classic digital IO */ 00088 static int contec_di_insn_bits(comedi_device * dev, comedi_subdevice * s, 00089 comedi_insn * insn, lsampl_t * data); 00090 static int contec_do_insn_bits(comedi_device * dev, comedi_subdevice * s, 00091 comedi_insn * insn, lsampl_t * data); 00092 00093 #if 0 00094 static int contec_cmdtest(comedi_device * dev, comedi_subdevice * s, 00095 comedi_cmd * cmd); 00096 00097 static int contec_ns_to_timer(unsigned int *ns, int round); 00098 #endif 00099 00100 static int contec_attach(comedi_device * dev, comedi_devconfig * it) 00101 { 00102 struct pci_dev *pcidev; 00103 comedi_subdevice *s; 00104 00105 printk("comedi%d: contec: ", dev->minor); 00106 00107 dev->board_name = thisboard->name; 00108 00109 if (alloc_private(dev, sizeof(contec_private)) < 0) 00110 return -ENOMEM; 00111 00112 if (alloc_subdevices(dev, 2) < 0) 00113 return -ENOMEM; 00114 00115 for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); 00116 pcidev != NULL; 00117 pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { 00118 00119 if (pcidev->vendor == PCI_VENDOR_ID_CONTEC && 00120 pcidev->device == PCI_DEVICE_ID_PIO1616L) { 00121 if (it->options[0] || it->options[1]) { 00122 /* Check bus and slot. */ 00123 if (it->options[0] != pcidev->bus->number || 00124 it->options[1] != 00125 PCI_SLOT(pcidev->devfn)) { 00126 continue; 00127 } 00128 } 00129 devpriv->pci_dev = pcidev; 00130 if (comedi_pci_enable(pcidev, "contec_pci_dio")) { 00131 printk("error enabling PCI device and request regions!\n"); 00132 return -EIO; 00133 } 00134 dev->iobase = pci_resource_start(pcidev, 0); 00135 printk(" base addr %lx ", dev->iobase); 00136 00137 dev->board_ptr = contec_boards + 0; 00138 00139 s = dev->subdevices + 0; 00140 00141 s->type = COMEDI_SUBD_DI; 00142 s->subdev_flags = SDF_READABLE; 00143 s->n_chan = 16; 00144 s->maxdata = 1; 00145 s->range_table = &range_digital; 00146 s->insn_bits = contec_di_insn_bits; 00147 00148 s = dev->subdevices + 1; 00149 s->type = COMEDI_SUBD_DO; 00150 s->subdev_flags = SDF_WRITABLE; 00151 s->n_chan = 16; 00152 s->maxdata = 1; 00153 s->range_table = &range_digital; 00154 s->insn_bits = contec_do_insn_bits; 00155 00156 printk("attached\n"); 00157 00158 return 1; 00159 } 00160 } 00161 00162 printk("card not present!\n"); 00163 00164 return -EIO; 00165 } 00166 00167 static int contec_detach(comedi_device * dev) 00168 { 00169 printk("comedi%d: contec: remove\n", dev->minor); 00170 00171 if (devpriv && devpriv->pci_dev) { 00172 if (dev->iobase) { 00173 comedi_pci_disable(devpriv->pci_dev); 00174 } 00175 pci_dev_put(devpriv->pci_dev); 00176 } 00177 00178 return 0; 00179 } 00180 00181 #if 0 00182 static int contec_cmdtest(comedi_device * dev, comedi_subdevice * s, 00183 comedi_cmd * cmd) 00184 { 00185 printk("contec_cmdtest called\n"); 00186 return 0; 00187 } 00188 00189 static int contec_ns_to_timer(unsigned int *ns, int round) 00190 { 00191 return *ns; 00192 } 00193 #endif 00194 00195 static int contec_do_insn_bits(comedi_device * dev, comedi_subdevice * s, 00196 comedi_insn * insn, lsampl_t * data) 00197 { 00198 00199 printk("contec_do_insn_bits called\n"); 00200 printk(" data: %d %d\n", data[0], data[1]); 00201 00202 if (insn->n != 2) 00203 return -EINVAL; 00204 00205 if (data[0]) { 00206 s->state &= ~data[0]; 00207 s->state |= data[0] & data[1]; 00208 rt_printk(" out: %d on %lx\n", s->state, 00209 dev->iobase + thisboard->out_offs); 00210 outw(s->state, dev->iobase + thisboard->out_offs); 00211 } 00212 return 2; 00213 } 00214 00215 static int contec_di_insn_bits(comedi_device * dev, comedi_subdevice * s, 00216 comedi_insn * insn, lsampl_t * data) 00217 { 00218 00219 rt_printk("contec_di_insn_bits called\n"); 00220 rt_printk(" data: %d %d\n", data[0], data[1]); 00221 00222 if (insn->n != 2) 00223 return -EINVAL; 00224 00225 data[1] = inw(dev->iobase + thisboard->in_offs); 00226 00227 return 2; 00228 } 00229 00230 COMEDI_PCI_INITCLEANUP(driver_contec, contec_pci_table);