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