/* comedi/drivers/contec_pci_dio.c COMEDI - Linux Control and Measurement Device Interface Copyright (C) 2000 David A. Schleef This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Driver: contec_pci_dio.o Description: Driver for Contec PIO1616L digital io board Devices: [Contec] PIO1616L (contec_pci_dio) Author: Stefano Rivoir Updated: Mon, 18 Mar 2002 15:34:01 -0800 Status: works Configuration Options: none */ #include #include typedef enum contec_model { PIO1616L =0, } contec_model; typedef struct contec_board { char *name; int model; int in_ports; int out_ports; int in_offs; int out_offs; int out_boffs; } contec_board; static contec_board contec_boards[] = { { "PIO1616L", PIO1616L, 16, 16, 0, 2, 10 }, }; #define PCI_DEVICE_ID_PIO1616L 0x8172 static struct pci_device_id contec_pci_table[] __devinitdata = { { PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PIO1616L }, { 0 } }; MODULE_DEVICE_TABLE(pci, contec_pci_table); #define thisboard ((contec_board *)dev->board_ptr) typedef struct{ int data; struct pci_dev *pci_dev; } contec_private; #define devpriv ((contec_private *)dev->private) static int contec_attach(comedi_device *dev,comedi_devconfig *it); static int contec_detach(comedi_device *dev); static comedi_driver driver_contec={ driver_name: "dummy", module: THIS_MODULE, attach: contec_attach, detach: contec_detach, }; /* Classic digital IO */ static int contec_di_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data); static int contec_do_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data); #if 0 static int contec_cmdtest(comedi_device *dev,comedi_subdevice *s, comedi_cmd *cmd); static int contec_ns_to_timer(unsigned int *ns,int round); #endif static int contec_attach(comedi_device *dev,comedi_devconfig *it) { struct pci_dev *pcidev; comedi_subdevice *s; printk("comedi%d: contec: ",dev->minor); dev->board_name = thisboard->name; if(alloc_private(dev,sizeof(contec_private))<0) return -ENOMEM; dev->n_subdevices=2; if(alloc_subdevices(dev)<0) return -ENOMEM; pci_for_each_dev ( pcidev ) { if ( pcidev->vendor == PCI_VENDOR_ID_CONTEC && pcidev->device == PCI_DEVICE_ID_PIO1616L ) { dev->iobase = pci_resource_start ( pcidev, 0 ); printk ( " base addr %x ", dev->iobase ); dev->board_ptr = contec_boards + 0; s=dev->subdevices+0; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = contec_di_insn_bits; s=dev->subdevices+1; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = contec_do_insn_bits; } } printk("attached\n"); return 1; } static int contec_detach(comedi_device *dev) { printk("comedi%d: contec: remove\n",dev->minor); return 0; } #if 0 static int contec_cmdtest(comedi_device *dev,comedi_subdevice *s, comedi_cmd *cmd) { printk ( "contec_cmdtest called\n" ); return 0; } static int contec_ns_to_timer(unsigned int *ns,int round) { return *ns; } #endif static int contec_do_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) { printk ( "contec_do_insn_bits called\n" ); printk ( " data: %d %d\n", data[0], data[1] ); if(insn->n!=2)return -EINVAL; if(data[0]){ s->state &= ~data[0]; s->state |= data[0]&data[1]; printk ( " out: %d on %x\n", s->state, dev->iobase + thisboard->out_offs ); outw(s->state, dev->iobase + thisboard->out_offs ); } return 2; } static int contec_di_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) { printk ( "contec_di_insn_bits called\n" ); printk ( " data: %d %d\n", data[0], data[1] ); if(insn->n!=2)return -EINVAL; data[1] = inw(dev->iobase + thisboard->in_offs ); return 2; } COMEDI_INITCLEANUP(driver_contec);