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