1028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 2028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka comedi/drivers/cb_pcidio.c 3028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka A Comedi driver for PCI-DIO24H & PCI-DIO48H of ComputerBoards (currently MeasurementComputing) 4028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 5028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka COMEDI - Linux Control and Measurement Device Interface 6028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka Copyright (C) 2000 David A. Schleef <ds@schleef.org> 7028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 8028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka This program is free software; you can redistribute it and/or modify 9028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka it under the terms of the GNU General Public License as published by 10028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka the Free Software Foundation; either version 2 of the License, or 11028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka (at your option) any later version. 12028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 13028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka This program is distributed in the hope that it will be useful, 14028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka but WITHOUT ANY WARRANTY; without even the implied warranty of 15028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka GNU General Public License for more details. 17028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 18028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka You should have received a copy of the GNU General Public License 19028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka along with this program; if not, write to the Free Software 20028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 22028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka*/ 23028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 24028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya MatsuzakaDriver: cb_pcidio 25028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya MatsuzakaDescription: ComputerBoards' DIO boards with PCI interface 26028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya MatsuzakaDevices: [Measurement Computing] PCI-DIO24 (cb_pcidio), PCI-DIO24H, PCI-DIO48H 27028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya MatsuzakaAuthor: Yoshiya Matsuzaka 28028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya MatsuzakaUpdated: Mon, 29 Oct 2007 15:40:47 +0000 29028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya MatsuzakaStatus: experimental 30028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 31028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya MatsuzakaThis driver has been modified from skel.c of comedi-0.7.70. 32028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 33028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya MatsuzakaConfiguration Options: 34028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka [0] - PCI bus of device (optional) 35028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka [1] - PCI slot of device (optional) 36028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka If bus/slot is not specified, the first available PCI device will 37028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka be used. 38028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 39028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya MatsuzakaPassing a zero for an option is the same as leaving it unspecified. 40028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka*/ 41028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 42028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/*------------------------------ HEADER FILES ---------------------------------*/ 43028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka#include "../comedidev.h" 44028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka#include "comedi_pci.h" 45028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka#include "8255.h" 46028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 47028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/*-------------------------- MACROS and DATATYPES -----------------------------*/ 48028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka#define PCI_VENDOR_ID_CB 0x1307 49028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 50028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 51028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * Board descriptions for two imaginary boards. Describing the 52028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * boards in this way is optional, and completely driver-dependent. 53028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * Some drivers use arrays such as this, other do not. 54028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 55c98d3debeb1101858f7bd720116d00e15ae9124dBill Pembertonstruct pcidio_board { 56aa65d22ae6412f474e5ba23fc363137b6c53eef9Ian Abbott const char *name; /* name of the board */ 57aa65d22ae6412f474e5ba23fc363137b6c53eef9Ian Abbott int dev_id; 582696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton int n_8255; /* number of 8255 chips on board */ 59028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 602696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* indices of base address regions */ 61028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka int pcicontroler_badrindex; 62028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka int dioregs_badrindex; 63c98d3debeb1101858f7bd720116d00e15ae9124dBill Pemberton}; 64028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 65c98d3debeb1101858f7bd720116d00e15ae9124dBill Pembertonstatic const struct pcidio_board pcidio_boards[] = { 66028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka { 670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dio24", 68aa65d22ae6412f474e5ba23fc363137b6c53eef9Ian Abbott .dev_id = 0x0028, 690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 1, 700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .pcicontroler_badrindex = 1, 710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dioregs_badrindex = 2, 720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 73028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka { 740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dio24h", 75aa65d22ae6412f474e5ba23fc363137b6c53eef9Ian Abbott .dev_id = 0x0014, 760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 1, 770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .pcicontroler_badrindex = 1, 780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dioregs_badrindex = 2, 790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 80028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka { 810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dio48h", 82aa65d22ae6412f474e5ba23fc363137b6c53eef9Ian Abbott .dev_id = 0x000b, 830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 2, 840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .pcicontroler_badrindex = 0, 850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dioregs_badrindex = 1, 860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 87028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka}; 88028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 89028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* This is used by modprobe to translate PCI IDs to drivers. Should 90028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * only be used for PCI and ISA-PnP devices */ 91028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded 92028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * upstream. */ 93028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzakastatic DEFINE_PCI_DEVICE_TABLE(pcidio_pci_table) = { 940924f2f06b97a08decf97ec081a965caa5758a2eJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0028) }, 950924f2f06b97a08decf97ec081a965caa5758a2eJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0014) }, 960924f2f06b97a08decf97ec081a965caa5758a2eJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000b) }, 970924f2f06b97a08decf97ec081a965caa5758a2eJavier Martinez Canillas { 0 } 98028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka}; 99028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 100028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya MatsuzakaMODULE_DEVICE_TABLE(pci, pcidio_pci_table); 101028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 102028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 103028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * Useful for shorthand access to the particular board structure 104028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 105c98d3debeb1101858f7bd720116d00e15ae9124dBill Pemberton#define thisboard ((const struct pcidio_board *)dev->board_ptr) 106028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 107028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* this structure is for data unique to this hardware driver. If 108028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka several hardware drivers keep similar information in this structure, 10971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton feel free to suggest moving the variable to the struct comedi_device struct. */ 110fe7858af4f04d6ea5d18a513433846c63c70d0ecBill Pembertonstruct pcidio_private { 111bbc9a9916bc1cd997f3bf303e7930d5f3c804d37André Goddard Rosa int data; /* currently unused */ 112028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 113028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka /* would be useful for a PCI device */ 114028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka struct pci_dev *pci_dev; 115028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 116bbc9a9916bc1cd997f3bf303e7930d5f3c804d37André Goddard Rosa /* used for DO readback, currently unused */ 117790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int do_readback[4]; /* up to 4 unsigned int suffice to hold 96 bits for PCI-DIO96 */ 118028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 1192696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton unsigned long dio_reg_base; /* address of port A of the first 8255 chip on board */ 120fe7858af4f04d6ea5d18a513433846c63c70d0ecBill Pemberton}; 121028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 122028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 123028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * most drivers define the following macro to make it easy to 124028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * access the private structure. 125028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 126fe7858af4f04d6ea5d18a513433846c63c70d0ecBill Pemberton#define devpriv ((struct pcidio_private *)dev->private) 127028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 128028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 129139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pemberton * The struct comedi_driver structure tells the Comedi core module 130028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * which functions to call to configure/deconfigure (attach/detach) 131028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * the board, and also about the kernel module that contains 132028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * the device code. 133028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 1340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pcidio_attach(struct comedi_device *dev, 1350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 136da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcidio_detach(struct comedi_device *dev); 137139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_cb_pcidio = { 13868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "cb_pcidio", 13968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 14068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = pcidio_attach, 14168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = pcidio_detach, 1422696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 143028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* It is not necessary to implement the following members if you are 144028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * writing a driver for a ISA PnP or PCI card */ 1452696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 146028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka /* Most drivers will support multiple types of boards by 147028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * having an array of board structures. These were defined 148028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * in pcidio_boards[] above. Note that the element 'name' 149028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * was first in the structure -- Comedi uses this fact to 150028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * extract the name of the board without knowing any details 151028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * about the structure except for its length. 152028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * When a device is attached (by comedi_config), the name 153028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * of the device is given to Comedi, and Comedi tries to 154028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * match it by going through the list of board names. If 155028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * there is a match, the address of the pointer is put 156028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * into dev->board_ptr and driver->attach() is called. 157028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * 158028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * Note that these are not necessary if you can determine 159028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * the type of board in software. ISA PnP, PCI, and PCMCIA 160028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * devices are such boards. 161028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 1622696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 1632696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* The following fields should NOT be initialized if you are dealing 1642696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton * with PCI devices 1652696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton * 16668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton * .board_name = pcidio_boards, 16768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton * .offset = sizeof(struct pcidio_board), 16868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton * .num_names = sizeof(pcidio_boards) / sizeof(structpcidio_board), 1692696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton */ 1702696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 171028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka}; 172028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 173028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/*------------------------------- FUNCTIONS -----------------------------------*/ 174028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 175028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 176028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * Attach is called by the Comedi core to configure the driver 177028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * for a particular board. If you specified a board_name array 178028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * in the driver structure, dev->board_ptr contains that 179028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * address. 180028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 181da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) 182028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka{ 183028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka struct pci_dev *pcidev = NULL; 184028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka int index; 185028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka int i; 186028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 187028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 188028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * Allocate the private structure area. alloc_private() is a 189028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * convenient macro defined in comedidev.h. 190028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 191fe7858af4f04d6ea5d18a513433846c63c70d0ecBill Pemberton if (alloc_private(dev, sizeof(struct pcidio_private)) < 0) 192028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka return -ENOMEM; 193028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 194028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * If you can probe the device to determine what device in a series 195028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * it is, this is the place to do it. Otherwise, dev->board_ptr 196028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * should already be initialized. 197028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 198028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 199028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * Probe the device to determine what device in the series it is. 200028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 201028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 20220fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy for_each_pci_dev(pcidev) { 2032696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* is it not a computer boards card? */ 204028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka if (pcidev->vendor != PCI_VENDOR_ID_CB) 205028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka continue; 2062696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* loop through cards supported by this driver */ 2070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral for (index = 0; index < ARRAY_SIZE(pcidio_boards); index++) { 208aa65d22ae6412f474e5ba23fc363137b6c53eef9Ian Abbott if (pcidio_boards[index].dev_id != pcidev->device) 209028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka continue; 210028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 2112696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* was a particular bus/slot requested? */ 212028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka if (it->options[0] || it->options[1]) { 2132696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* are we on the wrong bus/slot? */ 214028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka if (pcidev->bus->number != it->options[0] || 2150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pcidev->devfn) != it->options[1]) { 216028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka continue; 217028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka } 218028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka } 219028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka dev->board_ptr = pcidio_boards + index; 220028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka goto found; 221028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka } 222028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka } 223028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 224610b8ed9594944d1142d4591599ed6a071b9316fRavishankar karkala Mallikarjunayya dev_err(dev->hw_dev, "No supported ComputerBoards/MeasurementComputing card found on requested position\n"); 225028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka return -EIO; 226028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 2270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralfound: 228028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 229028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 230028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * Initialize dev->board_name. Note that we can use the "thisboard" 231028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * macro now, since we just initialized it in the last line. 232028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 233028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka dev->board_name = thisboard->name; 234028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 235028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka devpriv->pci_dev = pcidev; 236610b8ed9594944d1142d4591599ed6a071b9316fRavishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n", thisboard->name, 237610b8ed9594944d1142d4591599ed6a071b9316fRavishankar karkala Mallikarjunayya devpriv->pci_dev->bus->number, 238610b8ed9594944d1142d4591599ed6a071b9316fRavishankar karkala Mallikarjunayya PCI_SLOT(devpriv->pci_dev->devfn)); 239610b8ed9594944d1142d4591599ed6a071b9316fRavishankar karkala Mallikarjunayya if (comedi_pci_enable(pcidev, thisboard->name)) 240028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka return -EIO; 241610b8ed9594944d1142d4591599ed6a071b9316fRavishankar karkala Mallikarjunayya 242028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka devpriv->dio_reg_base 2430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral = 2440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, 2450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pcidio_boards[index].dioregs_badrindex); 246028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 247028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 248028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * Allocate the subdevice structures. alloc_subdevice() is a 249028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * convenient macro defined in comedidev.h. 250028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 251028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka if (alloc_subdevices(dev, thisboard->n_8255) < 0) 252028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka return -ENOMEM; 253028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 254028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka for (i = 0; i < thisboard->n_8255; i++) { 255028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka subdev_8255_init(dev, dev->subdevices + i, 2560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral NULL, devpriv->dio_reg_base + i * 4); 257610b8ed9594944d1142d4591599ed6a071b9316fRavishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "subdev %d: base = 0x%lx\n", i, 258610b8ed9594944d1142d4591599ed6a071b9316fRavishankar karkala Mallikarjunayya devpriv->dio_reg_base + i * 4); 259028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka } 260028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 261028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka return 1; 262028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka} 263028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 264028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 265028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * _detach is called to deconfigure a device. It should deallocate 266028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * resources. 267028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * This function is also called when _attach() fails, so it should be 268028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * careful not to release resources that were not necessarily 269028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * allocated by _attach(). dev->private and dev->subdevices are 270028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * deallocated automatically by the core. 271028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 272da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcidio_detach(struct comedi_device *dev) 273028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka{ 274028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka if (devpriv) { 275028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka if (devpriv->pci_dev) { 276e3a21d0ac2ee4f6c1be5314e76939867a2d0b470Andrea Gelmini if (devpriv->dio_reg_base) 277028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka comedi_pci_disable(devpriv->pci_dev); 278028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka pci_dev_put(devpriv->pci_dev); 279028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka } 280028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka } 281028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka if (dev->subdevices) { 282028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka int i; 283e3a21d0ac2ee4f6c1be5314e76939867a2d0b470Andrea Gelmini for (i = 0; i < thisboard->n_8255; i++) 284028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka subdev_8255_cleanup(dev, dev->subdevices + i); 285028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka } 286028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka return 0; 287028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka} 288028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka 289028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka/* 290028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * A convenient macro that defines init_module() and cleanup_module(), 291028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka * as necessary. 292028d48644164d1b303eaba6a8d96136ef15feb69Yoshiya Matsuzaka */ 293727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit driver_cb_pcidio_pci_probe(struct pci_dev *dev, 294727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas const struct pci_device_id *ent) 295727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 296727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return comedi_pci_auto_config(dev, driver_cb_pcidio.driver_name); 297727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 298727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 299727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit driver_cb_pcidio_pci_remove(struct pci_dev *dev) 300727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 301727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_pci_auto_unconfig(dev); 302727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 303727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 304727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver driver_cb_pcidio_pci_driver = { 305727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .id_table = pcidio_pci_table, 306727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .probe = &driver_cb_pcidio_pci_probe, 307727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .remove = __devexit_p(&driver_cb_pcidio_pci_remove) 308727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}; 309727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 310727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init driver_cb_pcidio_init_module(void) 311727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 312727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas int retval; 313727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 314727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas retval = comedi_driver_register(&driver_cb_pcidio); 315727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas if (retval < 0) 316727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return retval; 317727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 318727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas driver_cb_pcidio_pci_driver.name = (char *)driver_cb_pcidio.driver_name; 319727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return pci_register_driver(&driver_cb_pcidio_pci_driver); 320727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 321727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 322727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit driver_cb_pcidio_cleanup_module(void) 323727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 324727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci_unregister_driver(&driver_cb_pcidio_pci_driver); 325727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_driver_unregister(&driver_cb_pcidio); 326727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 327727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 328727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(driver_cb_pcidio_init_module); 329727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(driver_cb_pcidio_cleanup_module); 33090f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 33190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 33290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 33390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 334