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) = { 5549d6f67245c11a18d0454b2101fa224133f59323Peter Huewe { PCI_DEVICE(PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID) }, 5649d6f67245c11a18d0454b2101fa224133f59323Peter Huewe {0} 572f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann}; 582f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 592f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael HillmannMODULE_DEVICE_TABLE(pci, cnt_pci_table); 602f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 612f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- board specification structure ------------------------------------------*/ 622f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 639beff277bb14a844b5cb437fcdca9db7534ee44aBill Pembertonstruct cnt_board_struct { 649beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton 652f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann const char *name; 662f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int device_id; 672f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int cnt_channel_nbr; 682f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int cnt_bits; 699beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton}; 709beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton 719beff277bb14a844b5cb437fcdca9db7534ee44aBill Pembertonstatic const struct cnt_board_struct cnt_boards[] = { 722f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann { 730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = CNT_DRIVER_NAME, 740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = CNT_CARD_DEVICE_ID, 750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .cnt_channel_nbr = 3, 760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .cnt_bits = 24} 772f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann}; 782f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 799beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton#define cnt_board_nbr (sizeof(cnt_boards)/sizeof(struct cnt_board_struct)) 802f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 812f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- device private structure -----------------------------------------------*/ 822f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 832e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pembertonstruct cnt_device_private { 842e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pemberton 852f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann struct pci_dev *pcidev; 862e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pemberton}; 872e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pemberton 882e2269f90f2bb4e9438849f0690daba5cba29fc5Bill Pemberton#define devpriv ((struct cnt_device_private *)dev->private) 892f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 90139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver cnt_driver = { 9168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = CNT_DRIVER_NAME, 9268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 9368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = cnt_attach, 9468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = cnt_detach, 952f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann}; 962f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 97727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit cnt_driver_pci_probe(struct pci_dev *dev, 98727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas const struct pci_device_id *ent) 99727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 100727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return comedi_pci_auto_config(dev, cnt_driver.driver_name); 101727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 102727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 103727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit cnt_driver_pci_remove(struct pci_dev *dev) 104727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 105727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_pci_auto_unconfig(dev); 106727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 107727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 108727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver cnt_driver_pci_driver = { 109727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .id_table = cnt_pci_table, 110727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .probe = &cnt_driver_pci_probe, 111727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .remove = __devexit_p(&cnt_driver_pci_remove) 112727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}; 113727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 114727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init cnt_driver_init_module(void) 115727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 116727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas int retval; 117727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 118727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas retval = comedi_driver_register(&cnt_driver); 119727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas if (retval < 0) 120727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return retval; 121727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 122727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas cnt_driver_pci_driver.name = (char *)cnt_driver.driver_name; 123727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return pci_register_driver(&cnt_driver_pci_driver); 124727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 125727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 126727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit cnt_driver_cleanup_module(void) 127727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 128727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci_unregister_driver(&cnt_driver_pci_driver); 129727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_driver_unregister(&cnt_driver); 130727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 131727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 132727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(cnt_driver_init_module); 133727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(cnt_driver_cleanup_module); 1342f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1352f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- counter write ----------------------------------------------------------*/ 1362f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1372f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/* This should be used only for resetting the counters; maybe it is better 1382f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann to make a special command 'reset'. */ 139da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cnt_winsn(struct comedi_device *dev, 1400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 1410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 1422f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann{ 1432f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int chan = CR_CHAN(insn->chanspec); 1442f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1452f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb((unsigned char)((data[0] >> 24) & 0xff), 1460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->iobase + chan * 0x20 + 0x10); 1472f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb((unsigned char)((data[0] >> 16) & 0xff), 1480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->iobase + chan * 0x20 + 0x0c); 1492f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb((unsigned char)((data[0] >> 8) & 0xff), 1500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->iobase + chan * 0x20 + 0x08); 1512f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb((unsigned char)((data[0] >> 0) & 0xff), 1520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->iobase + chan * 0x20 + 0x04); 1532f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1542f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* return the number of samples written */ 1552f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return 1; 1562f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann} 1572f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1582f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- counter read -----------------------------------------------------------*/ 1592f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 160da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cnt_rinsn(struct comedi_device *dev, 1610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 1620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 1632f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann{ 1642f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann unsigned char a0, a1, a2, a3, a4; 1652f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int chan = CR_CHAN(insn->chanspec); 1662f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int result; 1672f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1682f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann a0 = inb(dev->iobase + chan * 0x20); 1692f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann a1 = inb(dev->iobase + chan * 0x20 + 0x04); 1702f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann a2 = inb(dev->iobase + chan * 0x20 + 0x08); 1712f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann a3 = inb(dev->iobase + chan * 0x20 + 0x0c); 1722f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann a4 = inb(dev->iobase + chan * 0x20 + 0x10); 1732f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1742f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann result = (a1 + (a2 * 256) + (a3 * 65536)); 1752f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (a4 > 0) 1762f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann result = result - s->maxdata; 1772f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral *data = (unsigned int)result; 1792f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1802f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* return the number of samples read */ 1812f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return 1; 1822f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann} 1832f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1842f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- attach -----------------------------------------------------------------*/ 1852f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 186da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it) 1872f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann{ 18834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *subdevice; 18920fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy struct pci_dev *pci_device = NULL; 1909beff277bb14a844b5cb437fcdca9db7534ee44aBill Pemberton struct cnt_board_struct *board; 1912f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann unsigned long io_base; 1922f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann int error, i; 1932f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1942f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* allocate device private structure */ 195c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton error = alloc_private(dev, sizeof(struct cnt_device_private)); 196c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (error < 0) 1972f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return error; 1982f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 1992f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* Probe the device to determine what device in the series it is. */ 20020fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy for_each_pci_dev(pci_device) { 2012f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (pci_device->vendor == PCI_VENDOR_ID_KOLTER) { 2022f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann for (i = 0; i < cnt_board_nbr; i++) { 2032f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (cnt_boards[i].device_id == 2040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device->device) { 2052f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* was a particular bus/slot requested? */ 2062f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if ((it->options[0] != 0) 2070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || (it->options[1] != 0)) { 2082f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* are we on the wrong bus/slot? */ 2092f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (pci_device->bus->number != 2100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral it->options[0] 2110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || 2120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pci_device->devfn) 2130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral != it->options[1]) { 2142f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann continue; 2152f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 2162f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 2172f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2182f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->board_ptr = cnt_boards + i; 2190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral board = 2200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (struct cnt_board_struct *) 2210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->board_ptr; 2222f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann goto found; 2232f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 2242f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 2252f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 2262f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 22726ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel printk(KERN_WARNING 22826ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel "comedi%d: no supported board found! (req. bus/slot: %d/%d)\n", 2290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, it->options[0], it->options[1]); 2302f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return -EIO; 2312f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralfound: 23326ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel printk(KERN_INFO 23426ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel "comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor, 2350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral board->name, pci_device->bus->number, 2360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pci_device->devfn)); 2372f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann devpriv->pcidev = pci_device; 2382f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->board_name = board->name; 2392f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2402f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* enable PCI device and request regions */ 241c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton error = comedi_pci_enable(pci_device, CNT_DRIVER_NAME); 242c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (error < 0) { 24326ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel printk(KERN_WARNING "comedi%d: " 24426ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel "failed to enable PCI device and request regions!\n", 24526ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel dev->minor); 2462f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return error; 2472f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 2482f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2492f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* read register base address [PCI_BASE_ADDRESS #0] */ 2502f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann io_base = pci_resource_start(pci_device, 0); 2512f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->iobase = io_base; 2522f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2532f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann /* allocate the subdevice structures */ 254c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton error = alloc_subdevices(dev, 1); 255c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (error < 0) 2562f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return error; 2572f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2582f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice = dev->subdevices + 0; 2592f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann dev->read_subdev = subdevice; 2602f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2612f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->type = COMEDI_SUBD_COUNTER; 2622f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ; 2632f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->n_chan = board->cnt_channel_nbr; 2642f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->maxdata = (1 << board->cnt_bits) - 1; 2652f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->insn_read = cnt_rinsn; 2662f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann subdevice->insn_write = cnt_winsn; 2672f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2682696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* select 20MHz clock */ 2692f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb(3, dev->iobase + 248); 2702f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2712696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* reset all counters */ 2722f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb(0, dev->iobase); 2732f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb(0, dev->iobase + 0x20); 2742f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann outb(0, dev->iobase + 0x40); 2752f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 27626ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel printk(KERN_INFO "comedi%d: " CNT_DRIVER_NAME " attached.\n", 27726ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel dev->minor); 2782f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return 0; 2792f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann} 2802f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 2812f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*-- detach -----------------------------------------------------------------*/ 2822f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann 283da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cnt_detach(struct comedi_device *dev) 2842f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann{ 2852f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann if (devpriv && devpriv->pcidev) { 28626ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel if (dev->iobase) 2872f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann comedi_pci_disable(devpriv->pcidev); 2882f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann pci_dev_put(devpriv->pcidev); 2892f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann } 29026ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel printk(KERN_INFO "comedi%d: " CNT_DRIVER_NAME " remove\n", 29126ac87851aa65f6bc58c2d1aa9162951a1dcd999Dirk Hohndel dev->minor); 2922f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann return 0; 2932f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann} 29490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 29590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 29690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 29790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 298