ke_counter.c revision da91b2692e0939b307f9047192d2b9fe07793e7a
12f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/* 22f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann comedi/drivers/ke_counter.c 32f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann Comedi driver for Kolter-Electronic PCI Counter 1 Card 42f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 52f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann COMEDI - Linux Control and Measurement Device Interface 62f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann Copyright (C) 2000 David A. Schleef <ds@schleef.org> 72f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 82f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann This program is free software; you can redistribute it and/or modify 92f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann it under the terms of the GNU General Public License as published by 102f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann the Free Software Foundation; either version 2 of the License, or 112f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann (at your option) any later version. 122f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 132f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann This program is distributed in the hope that it will be useful, 142f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann but WITHOUT ANY WARRANTY; without even the implied warranty of 152f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 162f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann GNU General Public License for more details. 172f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 182f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann You should have received a copy of the GNU General Public License 192f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann along with this program; if not, write to the Free Software 202f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 212f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 222f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann*/ 232f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/* 242f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannDriver: ke_counter 252f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannDescription: Driver for Kolter Electronic Counter Card 262f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannDevices: [Kolter Electronic] PCI Counter Card (ke_counter) 272f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannAuthor: Michael Hillmann 282f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannUpdated: Mon, 14 Apr 2008 15:42:42 +0100 292f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannStatus: tested 302f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 312f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannConfiguration Options: 322f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann [0] - PCI bus of device (optional) 332f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann [1] - PCI slot of device (optional) 342f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann If bus/slot is not specified, the first supported 352f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann PCI device found will be used. 362f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 372f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannThis driver is a simple driver to read the counter values from 382f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannKolter Electronic PCI Counter Card. 392f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann*/ 402f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 412f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann#include "../comedidev.h" 422f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 432f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann#include "comedi_pci.h" 442f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 452f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann#define CNT_DRIVER_NAME "ke_counter" 462f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann#define PCI_VENDOR_ID_KOLTER 0x1001 472f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann#define CNT_CARD_DEVICE_ID 0x0014 482f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 492f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- function prototypes ----------------------------------------------------*/ 502f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 51da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it); 52da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cnt_detach(struct comedi_device *dev); 532f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 542f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmannstatic DEFINE_PCI_DEVICE_TABLE(cnt_pci_table) = { 552f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann {PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 562f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 0}, 572f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann {0} 582f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann}; 592f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 602f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannMODULE_DEVICE_TABLE(pci, cnt_pci_table); 612f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 622f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- board specification structure ------------------------------------------*/ 632f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 649beff277bb14a844b5cb437fcdca9db7534ee44aBill Pembertonstruct cnt_board_struct { 659beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton 662f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann const char *name; 672f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int device_id; 682f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int cnt_channel_nbr; 692f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int cnt_bits; 709beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton}; 719beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton 722f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 739beff277bb14a844b5cb437fcdca9db7534ee44aBill Pembertonstatic const struct cnt_board_struct cnt_boards[] = { 742f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann { 752f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann name: CNT_DRIVER_NAME, 762f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann device_id:CNT_CARD_DEVICE_ID, 772f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann cnt_channel_nbr:3, 782f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann cnt_bits:24} 792f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann}; 802f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 819beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton#define cnt_board_nbr (sizeof(cnt_boards)/sizeof(struct cnt_board_struct)) 822f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 832f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- device private structure -----------------------------------------------*/ 842f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 852e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pembertonstruct cnt_device_private { 862e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pemberton 872f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann struct pci_dev *pcidev; 882e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pemberton}; 892e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pemberton 902f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 912e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pemberton#define devpriv ((struct cnt_device_private *)dev->private) 922f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 93139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver cnt_driver = { 942f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann driver_name:CNT_DRIVER_NAME, 952f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann module:THIS_MODULE, 962f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann attach:cnt_attach, 972f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann detach:cnt_detach, 982f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann}; 992f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1002f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannCOMEDI_PCI_INITCLEANUP(cnt_driver, cnt_pci_table); 1012f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1022f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- counter write ----------------------------------------------------------*/ 1032f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1042f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/* This should be used only for resetting the counters; maybe it is better 1052f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann to make a special command 'reset'. */ 106da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cnt_winsn(struct comedi_device *dev, 107da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1082f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann{ 1092f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int chan = CR_CHAN(insn->chanspec); 1102f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1112f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb((unsigned char)((data[0] >> 24) & 0xff), 1122f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->iobase + chan * 0x20 + 0x10); 1132f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb((unsigned char)((data[0] >> 16) & 0xff), 1142f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->iobase + chan * 0x20 + 0x0c); 1152f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb((unsigned char)((data[0] >> 8) & 0xff), 1162f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->iobase + chan * 0x20 + 0x08); 1172f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb((unsigned char)((data[0] >> 0) & 0xff), 1182f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->iobase + chan * 0x20 + 0x04); 1192f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1202f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* return the number of samples written */ 1212f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return 1; 1222f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann} 1232f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1242f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- counter read -----------------------------------------------------------*/ 1252f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 126da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cnt_rinsn(struct comedi_device *dev, 127da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1282f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann{ 1292f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann unsigned char a0, a1, a2, a3, a4; 1302f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int chan = CR_CHAN(insn->chanspec); 1312f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int result; 1322f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1332f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann a0 = inb(dev->iobase + chan * 0x20); 1342f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann a1 = inb(dev->iobase + chan * 0x20 + 0x04); 1352f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann a2 = inb(dev->iobase + chan * 0x20 + 0x08); 1362f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann a3 = inb(dev->iobase + chan * 0x20 + 0x0c); 1372f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann a4 = inb(dev->iobase + chan * 0x20 + 0x10); 1382f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1392f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann result = (a1 + (a2 * 256) + (a3 * 65536)); 1402f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (a4 > 0) 1412f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann result = result - s->maxdata; 1422f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 143790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton *data = (unsigned int) result; 1442f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1452f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* return the number of samples read */ 1462f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return 1; 1472f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann} 1482f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1492f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- attach -----------------------------------------------------------------*/ 1502f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 151da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it) 1522f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann{ 15334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *subdevice; 1542f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann struct pci_dev *pci_device; 1559beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton struct cnt_board_struct *board; 1562f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann unsigned long io_base; 1572f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int error, i; 1582f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1592f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* allocate device private structure */ 1602e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pemberton if ((error = alloc_private(dev, sizeof(struct cnt_device_private))) < 0) { 1612f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return error; 1622f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 1632f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1642f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* Probe the device to determine what device in the series it is. */ 1652f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); 1662f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann pci_device != NULL; 1672f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann pci_device = 1682f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) { 1692f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (pci_device->vendor == PCI_VENDOR_ID_KOLTER) { 1702f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann for (i = 0; i < cnt_board_nbr; i++) { 1712f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (cnt_boards[i].device_id == 1722f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann pci_device->device) { 1732f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* was a particular bus/slot requested? */ 1742f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if ((it->options[0] != 0) 1752f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann || (it->options[1] != 0)) { 1762f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* are we on the wrong bus/slot? */ 1772f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (pci_device->bus->number != 1782f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann it->options[0] 1792f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann || PCI_SLOT(pci_device-> 1802f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann devfn) != 1812f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann it->options[1]) { 1822f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann continue; 1832f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 1842f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 1852f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1862f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->board_ptr = cnt_boards + i; 1879beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton board = (struct cnt_board_struct *) dev-> 1882f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann board_ptr; 1892f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann goto found; 1902f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 1912f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 1922f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 1932f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 1942f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann printk("comedi%d: no supported board found! (req. bus/slot: %d/%d)\n", 1952f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->minor, it->options[0], it->options[1]); 1962f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return -EIO; 1972f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1982f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann found: 1992f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann printk("comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor, 2002f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann board->name, pci_device->bus->number, 2012f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann PCI_SLOT(pci_device->devfn)); 2022f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann devpriv->pcidev = pci_device; 2032f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->board_name = board->name; 2042f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2052f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* enable PCI device and request regions */ 2062f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if ((error = comedi_pci_enable(pci_device, CNT_DRIVER_NAME)) < 0) { 2072f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann printk("comedi%d: failed to enable PCI device and request regions!\n", dev->minor); 2082f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return error; 2092f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 2102f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2112f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* read register base address [PCI_BASE_ADDRESS #0] */ 2122f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann io_base = pci_resource_start(pci_device, 0); 2132f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->iobase = io_base; 2142f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2152f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* allocate the subdevice structures */ 2162f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if ((error = alloc_subdevices(dev, 1)) < 0) { 2172f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return error; 2182f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 2192f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2202f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice = dev->subdevices + 0; 2212f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->read_subdev = subdevice; 2222f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2232f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->type = COMEDI_SUBD_COUNTER; 2242f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ; 2252f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->n_chan = board->cnt_channel_nbr; 2262f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->maxdata = (1 << board->cnt_bits) - 1; 2272f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->insn_read = cnt_rinsn; 2282f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->insn_write = cnt_winsn; 2292f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2302696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* select 20MHz clock */ 2312f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb(3, dev->iobase + 248); 2322f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2332696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* reset all counters */ 2342f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb(0, dev->iobase); 2352f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb(0, dev->iobase + 0x20); 2362f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb(0, dev->iobase + 0x40); 2372f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2382f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann printk("comedi%d: " CNT_DRIVER_NAME " attached.\n", dev->minor); 2392f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return 0; 2402f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann} 2412f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2422f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- detach -----------------------------------------------------------------*/ 2432f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 244da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cnt_detach(struct comedi_device *dev) 2452f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann{ 2462f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (devpriv && devpriv->pcidev) { 2472f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (dev->iobase) { 2482f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann comedi_pci_disable(devpriv->pcidev); 2492f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 2502f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann pci_dev_put(devpriv->pcidev); 2512f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 2522f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann printk("comedi%d: " CNT_DRIVER_NAME " remove\n", dev->minor); 2532f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return 0; 2542f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann} 255