1/* 2 comedi/drivers/contec_pci_dio.c 3 4 COMEDI - Linux Control and Measurement Device Interface 5 Copyright (C) 2000 David A. Schleef <ds@schleef.org> 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16*/ 17/* 18Driver: contec_pci_dio 19Description: Contec PIO1616L digital I/O board 20Devices: [Contec] PIO1616L (contec_pci_dio) 21Author: Stefano Rivoir <s.rivoir@gts.it> 22Updated: Wed, 27 Jun 2007 13:00:06 +0100 23Status: works 24 25Configuration Options: not applicable, uses comedi PCI auto config 26*/ 27 28#include <linux/module.h> 29#include <linux/pci.h> 30 31#include "../comedidev.h" 32 33/* 34 * Register map 35 */ 36#define PIO1616L_DI_REG 0x00 37#define PIO1616L_DO_REG 0x02 38 39static int contec_do_insn_bits(struct comedi_device *dev, 40 struct comedi_subdevice *s, 41 struct comedi_insn *insn, 42 unsigned int *data) 43{ 44 if (comedi_dio_update_state(s, data)) 45 outw(s->state, dev->iobase + PIO1616L_DO_REG); 46 47 data[1] = s->state; 48 49 return insn->n; 50} 51 52static int contec_di_insn_bits(struct comedi_device *dev, 53 struct comedi_subdevice *s, 54 struct comedi_insn *insn, unsigned int *data) 55{ 56 data[1] = inw(dev->iobase + PIO1616L_DI_REG); 57 58 return insn->n; 59} 60 61static int contec_auto_attach(struct comedi_device *dev, 62 unsigned long context_unused) 63{ 64 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 65 struct comedi_subdevice *s; 66 int ret; 67 68 ret = comedi_pci_enable(dev); 69 if (ret) 70 return ret; 71 dev->iobase = pci_resource_start(pcidev, 0); 72 73 ret = comedi_alloc_subdevices(dev, 2); 74 if (ret) 75 return ret; 76 77 s = &dev->subdevices[0]; 78 s->type = COMEDI_SUBD_DI; 79 s->subdev_flags = SDF_READABLE; 80 s->n_chan = 16; 81 s->maxdata = 1; 82 s->range_table = &range_digital; 83 s->insn_bits = contec_di_insn_bits; 84 85 s = &dev->subdevices[1]; 86 s->type = COMEDI_SUBD_DO; 87 s->subdev_flags = SDF_WRITABLE; 88 s->n_chan = 16; 89 s->maxdata = 1; 90 s->range_table = &range_digital; 91 s->insn_bits = contec_do_insn_bits; 92 93 return 0; 94} 95 96static struct comedi_driver contec_pci_dio_driver = { 97 .driver_name = "contec_pci_dio", 98 .module = THIS_MODULE, 99 .auto_attach = contec_auto_attach, 100 .detach = comedi_pci_detach, 101}; 102 103static int contec_pci_dio_pci_probe(struct pci_dev *dev, 104 const struct pci_device_id *id) 105{ 106 return comedi_pci_auto_config(dev, &contec_pci_dio_driver, 107 id->driver_data); 108} 109 110static const struct pci_device_id contec_pci_dio_pci_table[] = { 111 { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, 0x8172) }, 112 { 0 } 113}; 114MODULE_DEVICE_TABLE(pci, contec_pci_dio_pci_table); 115 116static struct pci_driver contec_pci_dio_pci_driver = { 117 .name = "contec_pci_dio", 118 .id_table = contec_pci_dio_pci_table, 119 .probe = contec_pci_dio_pci_probe, 120 .remove = comedi_pci_auto_unconfig, 121}; 122module_comedi_pci_driver(contec_pci_dio_driver, contec_pci_dio_pci_driver); 123 124MODULE_AUTHOR("Comedi http://www.comedi.org"); 125MODULE_DESCRIPTION("Comedi low-level driver"); 126MODULE_LICENSE("GPL"); 127