ni_pcidio.c revision 13a9e03c0c209b59f07b72c5388845a5f55eda2a
1/*
2    comedi/drivers/ni_pcidio.c
3    driver for National Instruments PCI-DIO-96/PCI-6508
4		National Instruments PCI-DIO-32HS
5		National Instruments PCI-6503
6
7    COMEDI - Linux Control and Measurement Device Interface
8    Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24*/
25/*
26Driver: ni_pcidio
27Description: National Instruments PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503
28Author: ds
29Status: works
30Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533,
31  PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X,
32  PXI-6503, PCI-6533, PCI-6534
33Updated: Sun, 21 Apr 2002 21:03:38 -0700
34
35The DIO-96 appears as four 8255 subdevices.  See the 8255
36driver notes for details.
37
38The DIO32HS board appears as one subdevice, with 32 channels.
39Each channel is individually I/O configurable.  The channel order
40is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0.  The driver only
41supports simple digital I/O; no handshaking is supported.
42
43DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
44
45This driver could be easily modified to support AT-MIO32HS and
46AT-MIO96.
47
48The PCI-6534 requires a firmware upload after power-up to work, the
49firmware data and instructions for loading it with comedi_config
50it are contained in the
51comedi_nonfree_firmware tarball available from http://www.comedi.org
52*/
53
54/*
55   This driver is for both the NI PCI-DIO-32HS and the PCI-DIO-96,
56   which have very different architectures.  But, since the '96 is
57   so simple, it is included here.
58
59   Manuals (available from ftp://ftp.natinst.com/support/manuals)
60
61	320938c.pdf	PCI-DIO-96/PXI-6508/PCI-6503 User Manual
62	321464b.pdf	AT/PCI-DIO-32HS User Manual
63	341329A.pdf	PCI-6533 Register-Level Programmer Manual
64	341330A.pdf	DAQ-DIO Technical Reference Manual
65
66 */
67
68#define USE_DMA
69/* #define DEBUG 1 */
70/* #define DEBUG_FLAGS */
71
72#include <linux/interrupt.h>
73#include <linux/sched.h>
74#include "../comedidev.h"
75
76#include "mite.h"
77#include "8255.h"
78
79#undef DPRINTK
80#ifdef DEBUG
81#define DPRINTK(format, args...)	printk(format, ## args)
82#else
83#define DPRINTK(format, args...)
84#endif
85
86#define PCI_DIO_SIZE 4096
87#define PCI_MITE_SIZE 4096
88
89/* defines for the PCI-DIO-96 */
90
91#define NIDIO_8255_BASE(x)	((x)*4)
92#define NIDIO_A 0
93#define NIDIO_B 4
94#define NIDIO_C 8
95#define NIDIO_D 12
96
97/* defines for the PCI-DIO-32HS */
98
99#define Window_Address			4	/* W */
100#define Interrupt_And_Window_Status	4	/* R */
101#define IntStatus1				(1<<0)
102#define IntStatus2				(1<<1)
103#define WindowAddressStatus_mask		0x7c
104
105#define Master_DMA_And_Interrupt_Control 5	/* W */
106#define InterruptLine(x)			((x)&3)
107#define OpenInt				(1<<2)
108#define Group_Status			5	/* R */
109#define DataLeft				(1<<0)
110#define Req					(1<<2)
111#define StopTrig				(1<<3)
112
113#define Group_1_Flags			6	/* R */
114#define Group_2_Flags			7	/* R */
115#define TransferReady				(1<<0)
116#define CountExpired				(1<<1)
117#define Waited				(1<<5)
118#define PrimaryTC				(1<<6)
119#define SecondaryTC				(1<<7)
120  /* #define SerialRose */
121  /* #define ReqRose */
122  /* #define Paused */
123
124#define Group_1_First_Clear		6	/* W */
125#define Group_2_First_Clear		7	/* W */
126#define ClearWaited				(1<<3)
127#define ClearPrimaryTC			(1<<4)
128#define ClearSecondaryTC			(1<<5)
129#define DMAReset				(1<<6)
130#define FIFOReset				(1<<7)
131#define ClearAll				0xf8
132
133#define Group_1_FIFO			8	/* W */
134#define Group_2_FIFO			12	/* W */
135
136#define Transfer_Count			20
137#define Chip_ID_D			24
138#define Chip_ID_I			25
139#define Chip_ID_O			26
140#define Chip_Version			27
141#define Port_IO(x)			(28+(x))
142#define Port_Pin_Directions(x)		(32+(x))
143#define Port_Pin_Mask(x)		(36+(x))
144#define Port_Pin_Polarities(x)		(40+(x))
145
146#define Master_Clock_Routing		45
147#define RTSIClocking(x)			(((x)&3)<<4)
148
149#define Group_1_Second_Clear		46	/* W */
150#define Group_2_Second_Clear		47	/* W */
151#define ClearExpired				(1<<0)
152
153#define Port_Pattern(x)			(48+(x))
154
155#define Data_Path			64
156#define FIFOEnableA		(1<<0)
157#define FIFOEnableB		(1<<1)
158#define FIFOEnableC		(1<<2)
159#define FIFOEnableD		(1<<3)
160#define Funneling(x)		(((x)&3)<<4)
161#define GroupDirection	(1<<7)
162
163#define Protocol_Register_1		65
164#define OpMode				Protocol_Register_1
165#define RunMode(x)		((x)&7)
166#define Numbered		(1<<3)
167
168#define Protocol_Register_2		66
169#define ClockReg			Protocol_Register_2
170#define ClockLine(x)		(((x)&3)<<5)
171#define InvertStopTrig	(1<<7)
172#define DataLatching(x)       (((x)&3)<<5)
173
174#define Protocol_Register_3		67
175#define Sequence			Protocol_Register_3
176
177#define Protocol_Register_14		68	/* 16 bit */
178#define ClockSpeed			Protocol_Register_14
179
180#define Protocol_Register_4		70
181#define ReqReg				Protocol_Register_4
182#define ReqConditioning(x)	(((x)&7)<<3)
183
184#define Protocol_Register_5		71
185#define BlockMode			Protocol_Register_5
186
187#define FIFO_Control			72
188#define ReadyLevel(x)		((x)&7)
189
190#define Protocol_Register_6		73
191#define LinePolarities			Protocol_Register_6
192#define InvertAck		(1<<0)
193#define InvertReq		(1<<1)
194#define InvertClock		(1<<2)
195#define InvertSerial		(1<<3)
196#define OpenAck		(1<<4)
197#define OpenClock		(1<<5)
198
199#define Protocol_Register_7		74
200#define AckSer				Protocol_Register_7
201#define AckLine(x)		(((x)&3)<<2)
202#define ExchangePins		(1<<7)
203
204#define Interrupt_Control		75
205  /* bits same as flags */
206
207#define DMA_Line_Control_Group1		76
208#define DMA_Line_Control_Group2		108
209/* channel zero is none */
210static inline unsigned primary_DMAChannel_bits(unsigned channel)
211{
212	return channel & 0x3;
213}
214
215static inline unsigned secondary_DMAChannel_bits(unsigned channel)
216{
217	return (channel << 2) & 0xc;
218}
219
220#define Transfer_Size_Control		77
221#define TransferWidth(x)	((x)&3)
222#define TransferLength(x)	(((x)&3)<<3)
223#define RequireRLevel		(1<<5)
224
225#define Protocol_Register_15		79
226#define DAQOptions			Protocol_Register_15
227#define StartSource(x)			((x)&0x3)
228#define InvertStart				(1<<2)
229#define StopSource(x)				(((x)&0x3)<<3)
230#define ReqStart				(1<<6)
231#define PreStart				(1<<7)
232
233#define Pattern_Detection		81
234#define DetectionMethod			(1<<0)
235#define InvertMatch				(1<<1)
236#define IE_Pattern_Detection			(1<<2)
237
238#define Protocol_Register_9		82
239#define ReqDelay			Protocol_Register_9
240
241#define Protocol_Register_10		83
242#define ReqNotDelay			Protocol_Register_10
243
244#define Protocol_Register_11		84
245#define AckDelay			Protocol_Register_11
246
247#define Protocol_Register_12		85
248#define AckNotDelay			Protocol_Register_12
249
250#define Protocol_Register_13		86
251#define Data1Delay			Protocol_Register_13
252
253#define Protocol_Register_8		88	/* 32 bit */
254#define StartDelay			Protocol_Register_8
255
256enum pci_6534_firmware_registers {	/* 16 bit */
257	Firmware_Control_Register = 0x100,
258	Firmware_Status_Register = 0x104,
259	Firmware_Data_Register = 0x108,
260	Firmware_Mask_Register = 0x10c,
261	Firmware_Debug_Register = 0x110,
262};
263/* main fpga registers (32 bit)*/
264enum pci_6534_fpga_registers {
265	FPGA_Control1_Register = 0x200,
266	FPGA_Control2_Register = 0x204,
267	FPGA_Irq_Mask_Register = 0x208,
268	FPGA_Status_Register = 0x20c,
269	FPGA_Signature_Register = 0x210,
270	FPGA_SCALS_Counter_Register = 0x280,	/*write-clear */
271	FPGA_SCAMS_Counter_Register = 0x284,	/*write-clear */
272	FPGA_SCBLS_Counter_Register = 0x288,	/*write-clear */
273	FPGA_SCBMS_Counter_Register = 0x28c,	/*write-clear */
274	FPGA_Temp_Control_Register = 0x2a0,
275	FPGA_DAR_Register = 0x2a8,
276	FPGA_ELC_Read_Register = 0x2b8,
277	FPGA_ELC_Write_Register = 0x2bc,
278};
279enum FPGA_Control_Bits {
280	FPGA_Enable_Bit = 0x8000,
281};
282
283#define TIMER_BASE 50		/* nanoseconds */
284
285#ifdef USE_DMA
286#define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC)
287#else
288#define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC)
289#endif
290
291static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it);
292static int nidio_detach(struct comedi_device *dev);
293static int ni_pcidio_cancel(struct comedi_device *dev,
294			    struct comedi_subdevice *s);
295
296static struct comedi_driver driver_pcidio = {
297	.driver_name = "ni_pcidio",
298	.module = THIS_MODULE,
299	.attach = nidio_attach,
300	.detach = nidio_detach,
301};
302
303struct nidio_board {
304
305	int dev_id;
306	const char *name;
307	int n_8255;
308	unsigned int is_diodaq:1;
309	unsigned int uses_firmware:1;
310};
311
312static const struct nidio_board nidio_boards[] = {
313	{
314	 .dev_id = 0x1150,
315	 .name = "pci-dio-32hs",
316	 .n_8255 = 0,
317	 .is_diodaq = 1,
318	 },
319	{
320	 .dev_id = 0x1320,
321	 .name = "pxi-6533",
322	 .n_8255 = 0,
323	 .is_diodaq = 1,
324	 },
325	{
326	 .dev_id = 0x12b0,
327	 .name = "pci-6534",
328	 .n_8255 = 0,
329	 .is_diodaq = 1,
330	 .uses_firmware = 1,
331	 },
332	{
333	 .dev_id = 0x0160,
334	 .name = "pci-dio-96",
335	 .n_8255 = 4,
336	 .is_diodaq = 0,
337	 },
338	{
339	 .dev_id = 0x1630,
340	 .name = "pci-dio-96b",
341	 .n_8255 = 4,
342	 .is_diodaq = 0,
343	 },
344	{
345	 .dev_id = 0x13c0,
346	 .name = "pxi-6508",
347	 .n_8255 = 4,
348	 .is_diodaq = 0,
349	 },
350	{
351	 .dev_id = 0x0400,
352	 .name = "pci-6503",
353	 .n_8255 = 1,
354	 .is_diodaq = 0,
355	 },
356	{
357	 .dev_id = 0x1250,
358	 .name = "pci-6503b",
359	 .n_8255 = 1,
360	 .is_diodaq = 0,
361	 },
362	{
363	 .dev_id = 0x17d0,
364	 .name = "pci-6503x",
365	 .n_8255 = 1,
366	 .is_diodaq = 0,
367	 },
368	{
369	 .dev_id = 0x1800,
370	 .name = "pxi-6503",
371	 .n_8255 = 1,
372	 .is_diodaq = 0,
373	 },
374};
375
376#define n_nidio_boards ARRAY_SIZE(nidio_boards)
377#define this_board ((const struct nidio_board *)dev->board_ptr)
378
379static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = {
380	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1150)},
381	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1320)},
382	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x12b0)},
383	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0160)},
384	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1630)},
385	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x13c0)},
386	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0400)},
387	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1250)},
388	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x17d0)},
389	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1800)},
390	{0}
391};
392
393MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
394
395struct nidio96_private {
396	struct mite_struct *mite;
397	int boardtype;
398	int dio;
399	unsigned short OpModeBits;
400	struct mite_channel *di_mite_chan;
401	struct mite_dma_descriptor_ring *di_mite_ring;
402	spinlock_t mite_channel_lock;
403};
404#define devpriv ((struct nidio96_private *)dev->private)
405
406static int ni_pcidio_cmdtest(struct comedi_device *dev,
407			     struct comedi_subdevice *s,
408			     struct comedi_cmd *cmd);
409static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
410static int ni_pcidio_inttrig(struct comedi_device *dev,
411			     struct comedi_subdevice *s, unsigned int trignum);
412static int nidio_find_device(struct comedi_device *dev, int bus, int slot);
413static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
414static int setup_mite_dma(struct comedi_device *dev,
415			  struct comedi_subdevice *s);
416
417#ifdef DEBUG_FLAGS
418static void ni_pcidio_print_flags(unsigned int flags);
419static void ni_pcidio_print_status(unsigned int status);
420#else
421#define ni_pcidio_print_flags(x)
422#define ni_pcidio_print_status(x)
423#endif
424
425static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
426{
427	unsigned long flags;
428
429	spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
430	BUG_ON(devpriv->di_mite_chan);
431	devpriv->di_mite_chan =
432	    mite_request_channel_in_range(devpriv->mite,
433					  devpriv->di_mite_ring, 1, 2);
434	if (devpriv->di_mite_chan == NULL) {
435		spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
436		comedi_error(dev, "failed to reserve mite dma channel.");
437		return -EBUSY;
438	}
439	writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
440	       secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
441	       devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
442	mmiowb();
443	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
444	return 0;
445}
446
447static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
448{
449	unsigned long flags;
450
451	spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
452	if (devpriv->di_mite_chan) {
453		mite_dma_disarm(devpriv->di_mite_chan);
454		mite_dma_reset(devpriv->di_mite_chan);
455		mite_release_channel(devpriv->di_mite_chan);
456		devpriv->di_mite_chan = NULL;
457		writeb(primary_DMAChannel_bits(0) |
458		       secondary_DMAChannel_bits(0),
459		       devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
460		mmiowb();
461	}
462	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
463}
464
465static int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase)
466{
467	if (dir) {
468		writeb(data, (void *)(iobase + port));
469		return 0;
470	} else {
471		return readb((void *)(iobase + port));
472	}
473}
474
475void ni_pcidio_event(struct comedi_device *dev, struct comedi_subdevice *s)
476{
477	if (s->
478	    async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
479			     COMEDI_CB_OVERFLOW)) {
480		ni_pcidio_cancel(dev, s);
481	}
482	comedi_event(dev, s);
483}
484
485static irqreturn_t nidio_interrupt(int irq, void *d)
486{
487	struct comedi_device *dev = d;
488	struct comedi_subdevice *s = dev->subdevices;
489	struct comedi_async *async = s->async;
490	struct mite_struct *mite = devpriv->mite;
491
492	/* int i, j; */
493	long int AuxData = 0;
494	short data1 = 0;
495	short data2 = 0;
496	int flags;
497	int status;
498	int work = 0;
499	unsigned int m_status = 0;
500	unsigned long irq_flags;
501
502	/* interrupcions parasites */
503	if (dev->attached == 0) {
504		/* assume it's from another card */
505		return IRQ_NONE;
506	}
507
508	status = readb(devpriv->mite->daq_io_addr +
509		       Interrupt_And_Window_Status);
510	flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
511
512	DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
513		status, flags);
514	ni_pcidio_print_flags(flags);
515	ni_pcidio_print_status(status);
516
517	/* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */
518	/* printk("buf[4096]=%08x\n",
519	       *(unsigned int *)(async->prealloc_buf+4096)); */
520
521	spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
522	if (devpriv->di_mite_chan)
523		m_status = mite_get_status(devpriv->di_mite_chan);
524#ifdef MITE_DEBUG
525	mite_print_chsr(m_status);
526#endif
527	/* printk("mite_bytes_transferred: %d\n",
528	       mite_bytes_transferred(mite,DI_DMA_CHAN)); */
529
530	/* mite_dump_regs(mite); */
531	if (m_status & CHSR_INT) {
532		if (m_status & CHSR_LINKC) {
533			writel(CHOR_CLRLC,
534			       mite->mite_io_addr +
535			       MITE_CHOR(devpriv->di_mite_chan->channel));
536			mite_sync_input_dma(devpriv->di_mite_chan, s->async);
537			/* XXX need to byteswap */
538		}
539		if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
540				 CHSR_DRQ1 | CHSR_MRDY)) {
541			DPRINTK("unknown mite interrupt, disabling IRQ\n");
542			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
543			disable_irq(dev->irq);
544		}
545	}
546	spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);
547
548	while (status & DataLeft) {
549		work++;
550		if (work > 20) {
551			DPRINTK("too much work in interrupt\n");
552			writeb(0x00,
553			       devpriv->mite->daq_io_addr +
554			       Master_DMA_And_Interrupt_Control);
555			break;
556		}
557
558		flags &= IntEn;
559
560		if (flags & TransferReady) {
561			/* DPRINTK("TransferReady\n"); */
562			while (flags & TransferReady) {
563				work++;
564				if (work > 100) {
565					DPRINTK("too much work in interrupt\n");
566					writeb(0x00,
567					       devpriv->mite->daq_io_addr +
568					       Master_DMA_And_Interrupt_Control
569					      );
570					goto out;
571				}
572				AuxData =
573				    readl(devpriv->mite->daq_io_addr +
574					  Group_1_FIFO);
575				data1 = AuxData & 0xffff;
576				data2 = (AuxData & 0xffff0000) >> 16;
577				comedi_buf_put(async, data1);
578				comedi_buf_put(async, data2);
579				/* DPRINTK("read:%d, %d\n",data1,data2); */
580				flags = readb(devpriv->mite->daq_io_addr +
581					      Group_1_Flags);
582			}
583			/* DPRINTK("buf_int_count: %d\n",
584				async->buf_int_count); */
585			/* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",
586				IntEn,flags,status); */
587			/* ni_pcidio_print_flags(flags); */
588			/* ni_pcidio_print_status(status); */
589			async->events |= COMEDI_CB_BLOCK;
590		}
591
592		if (flags & CountExpired) {
593			DPRINTK("CountExpired\n");
594			writeb(ClearExpired,
595			       devpriv->mite->daq_io_addr +
596			       Group_1_Second_Clear);
597			async->events |= COMEDI_CB_EOA;
598
599			writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
600			break;
601		} else if (flags & Waited) {
602			DPRINTK("Waited\n");
603			writeb(ClearWaited,
604			       devpriv->mite->daq_io_addr +
605			       Group_1_First_Clear);
606			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
607			break;
608		} else if (flags & PrimaryTC) {
609			DPRINTK("PrimaryTC\n");
610			writeb(ClearPrimaryTC,
611			       devpriv->mite->daq_io_addr +
612			       Group_1_First_Clear);
613			async->events |= COMEDI_CB_EOA;
614		} else if (flags & SecondaryTC) {
615			DPRINTK("SecondaryTC\n");
616			writeb(ClearSecondaryTC,
617			       devpriv->mite->daq_io_addr +
618			       Group_1_First_Clear);
619			async->events |= COMEDI_CB_EOA;
620		}
621#if 0
622		else {
623			printk("ni_pcidio: unknown interrupt\n");
624			async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
625			writeb(0x00,
626			       devpriv->mite->daq_io_addr +
627			       Master_DMA_And_Interrupt_Control);
628		}
629#endif
630		flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
631		status = readb(devpriv->mite->daq_io_addr +
632			       Interrupt_And_Window_Status);
633		/* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,"
634			"status=0x%02x\n", IntEn, flags, status); */
635		/* ni_pcidio_print_flags(flags); */
636		/* ni_pcidio_print_status(status); */
637	}
638
639out:
640	ni_pcidio_event(dev, s);
641#if 0
642	if (!tag) {
643		writeb(0x03,
644		       devpriv->mite->daq_io_addr +
645		       Master_DMA_And_Interrupt_Control);
646	}
647#endif
648	return IRQ_HANDLED;
649}
650
651#ifdef DEBUG_FLAGS
652static const char *const flags_strings[] = {
653	"TransferReady", "CountExpired", "2", "3",
654	"4", "Waited", "PrimaryTC", "SecondaryTC",
655};
656
657static void ni_pcidio_print_flags(unsigned int flags)
658{
659	int i;
660
661	printk(KERN_INFO "group_1_flags:");
662	for (i = 7; i >= 0; i--) {
663		if (flags & (1 << i))
664			printk(" %s", flags_strings[i]);
665	}
666	printk("\n");
667}
668
669static char *status_strings[] = {
670	"DataLeft1", "Reserved1", "Req1", "StopTrig1",
671	"DataLeft2", "Reserved2", "Req2", "StopTrig2",
672};
673
674static void ni_pcidio_print_status(unsigned int flags)
675{
676	int i;
677
678	printk(KERN_INFO "group_status:");
679	for (i = 7; i >= 0; i--) {
680		if (flags & (1 << i))
681			printk(" %s", status_strings[i]);
682	}
683	printk("\n");
684}
685#endif
686
687#ifdef unused
688static void debug_int(struct comedi_device *dev)
689{
690	int a, b;
691	static int n_int;
692	struct timeval tv;
693
694	do_gettimeofday(&tv);
695	a = readb(devpriv->mite->daq_io_addr + Group_Status);
696	b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
697
698	if (n_int < 10) {
699		DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b,
700			(int)tv.tv_usec);
701	}
702
703	while (b & 1) {
704		writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO);
705		b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
706	}
707
708	b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
709
710	if (n_int < 10) {
711		DPRINTK("new status 0x%02x\n", b);
712		n_int++;
713	}
714}
715#endif
716
717static int ni_pcidio_insn_config(struct comedi_device *dev,
718				 struct comedi_subdevice *s,
719				 struct comedi_insn *insn, unsigned int *data)
720{
721	if (insn->n != 1)
722		return -EINVAL;
723	switch (data[0]) {
724	case INSN_CONFIG_DIO_OUTPUT:
725		s->io_bits |= 1 << CR_CHAN(insn->chanspec);
726		break;
727	case INSN_CONFIG_DIO_INPUT:
728		s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
729		break;
730	case INSN_CONFIG_DIO_QUERY:
731		data[1] =
732		    (s->
733		     io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
734		    COMEDI_INPUT;
735		return insn->n;
736		break;
737	default:
738		return -EINVAL;
739	}
740	writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
741
742	return 1;
743}
744
745static int ni_pcidio_insn_bits(struct comedi_device *dev,
746			       struct comedi_subdevice *s,
747			       struct comedi_insn *insn, unsigned int *data)
748{
749	if (insn->n != 2)
750		return -EINVAL;
751	if (data[0]) {
752		s->state &= ~data[0];
753		s->state |= (data[0] & data[1]);
754		writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
755	}
756	data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
757
758	return 2;
759}
760
761static int ni_pcidio_cmdtest(struct comedi_device *dev,
762			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
763{
764	int err = 0;
765	int tmp;
766
767	/* step 1: make sure trigger sources are trivially valid */
768
769	tmp = cmd->start_src;
770	cmd->start_src &= TRIG_NOW | TRIG_INT;
771	if (!cmd->start_src || tmp != cmd->start_src)
772		err++;
773
774	tmp = cmd->scan_begin_src;
775	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
776	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
777		err++;
778
779	tmp = cmd->convert_src;
780	cmd->convert_src &= TRIG_NOW;
781	if (!cmd->convert_src || tmp != cmd->convert_src)
782		err++;
783
784	tmp = cmd->scan_end_src;
785	cmd->scan_end_src &= TRIG_COUNT;
786	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
787		err++;
788
789	tmp = cmd->stop_src;
790	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
791	if (!cmd->stop_src || tmp != cmd->stop_src)
792		err++;
793
794	if (err)
795		return 1;
796
797	/* step 2: make sure trigger sources are unique and mutually
798	compatible */
799
800	/* note that mutual compatibility is not an issue here */
801	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
802		err++;
803	if (cmd->scan_begin_src != TRIG_TIMER &&
804	    cmd->scan_begin_src != TRIG_EXT)
805		err++;
806
807	if (err)
808		return 2;
809
810	/* step 3: make sure arguments are trivially compatible */
811
812	if (cmd->start_arg != 0) {
813		/* same for both TRIG_INT and TRIG_NOW */
814		cmd->start_arg = 0;
815		err++;
816	}
817#define MAX_SPEED	(TIMER_BASE)	/* in nanoseconds */
818
819	if (cmd->scan_begin_src == TRIG_TIMER) {
820		if (cmd->scan_begin_arg < MAX_SPEED) {
821			cmd->scan_begin_arg = MAX_SPEED;
822			err++;
823		}
824		/* no minimum speed */
825	} else {
826		/* TRIG_EXT */
827		/* should be level/edge, hi/lo specification here */
828		if (cmd->scan_begin_arg != 0) {
829			cmd->scan_begin_arg = 0;
830			err++;
831		}
832	}
833	if (cmd->convert_arg != 0) {
834		cmd->convert_arg = 0;
835		err++;
836	}
837
838	if (cmd->scan_end_arg != cmd->chanlist_len) {
839		cmd->scan_end_arg = cmd->chanlist_len;
840		err++;
841	}
842	if (cmd->stop_src == TRIG_COUNT) {
843		/* no limit */
844	} else {
845		/* TRIG_NONE */
846		if (cmd->stop_arg != 0) {
847			cmd->stop_arg = 0;
848			err++;
849		}
850	}
851
852	if (err)
853		return 3;
854
855	/* step 4: fix up any arguments */
856
857	if (cmd->scan_begin_src == TRIG_TIMER) {
858		tmp = cmd->scan_begin_arg;
859		ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
860				      cmd->flags & TRIG_ROUND_MASK);
861		if (tmp != cmd->scan_begin_arg)
862			err++;
863	}
864
865	if (err)
866		return 4;
867
868	return 0;
869}
870
871static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
872{
873	int divider, base;
874
875	base = TIMER_BASE;
876
877	switch (round_mode) {
878	case TRIG_ROUND_NEAREST:
879	default:
880		divider = (*nanosec + base / 2) / base;
881		break;
882	case TRIG_ROUND_DOWN:
883		divider = (*nanosec) / base;
884		break;
885	case TRIG_ROUND_UP:
886		divider = (*nanosec + base - 1) / base;
887		break;
888	}
889
890	*nanosec = base * divider;
891	return divider;
892}
893
894static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
895{
896	struct comedi_cmd *cmd = &s->async->cmd;
897
898	/* XXX configure ports for input */
899	writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
900
901	if (1) {
902		/* enable fifos A B C D */
903		writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
904
905		/* set transfer width a 32 bits */
906		writeb(TransferWidth(0) | TransferLength(0),
907		       devpriv->mite->daq_io_addr + Transfer_Size_Control);
908	} else {
909		writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
910		writeb(TransferWidth(3) | TransferLength(0),
911		       devpriv->mite->daq_io_addr + Transfer_Size_Control);
912	}
913
914	/* protocol configuration */
915	if (cmd->scan_begin_src == TRIG_TIMER) {
916		/* page 4-5, "input with internal REQs" */
917		writeb(0, devpriv->mite->daq_io_addr + OpMode);
918		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
919		writeb(1, devpriv->mite->daq_io_addr + Sequence);
920		writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
921		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
922		writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
923		writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
924		writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
925					     TRIG_ROUND_NEAREST),
926		       devpriv->mite->daq_io_addr + StartDelay);
927		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
928		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
929		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
930		writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
931		writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
932		/* manual, page 4-5: ClockSpeed comment is incorrectly listed
933		 * on DAQOptions */
934		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
935		writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
936	} else {
937		/* TRIG_EXT */
938		/* page 4-5, "input with external REQs" */
939		writeb(0, devpriv->mite->daq_io_addr + OpMode);
940		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
941		writeb(0, devpriv->mite->daq_io_addr + Sequence);
942		writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
943		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
944		writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
945		writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
946		writel(1, devpriv->mite->daq_io_addr + StartDelay);
947		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
948		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
949		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
950		writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
951		writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
952		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
953		writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
954	}
955
956	if (cmd->stop_src == TRIG_COUNT) {
957		writel(cmd->stop_arg,
958		       devpriv->mite->daq_io_addr + Transfer_Count);
959	} else {
960		/* XXX */
961	}
962
963#ifdef USE_DMA
964	writeb(ClearPrimaryTC | ClearSecondaryTC,
965	       devpriv->mite->daq_io_addr + Group_1_First_Clear);
966
967	{
968		int retval = setup_mite_dma(dev, s);
969		if (retval)
970			return retval;
971	}
972#else
973	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
974#endif
975	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
976
977	/* clear and enable interrupts */
978	writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
979	/* writeb(ClearExpired,
980	       devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
981
982	writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
983	writeb(0x03,
984	       devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
985
986	if (cmd->stop_src == TRIG_NONE) {
987		devpriv->OpModeBits = DataLatching(0) | RunMode(7);
988	} else {		/* TRIG_TIMER */
989		devpriv->OpModeBits = Numbered | RunMode(7);
990	}
991	if (cmd->start_src == TRIG_NOW) {
992		/* start */
993		writeb(devpriv->OpModeBits,
994		       devpriv->mite->daq_io_addr + OpMode);
995		s->async->inttrig = NULL;
996	} else {
997		/* TRIG_INT */
998		s->async->inttrig = ni_pcidio_inttrig;
999	}
1000
1001	DPRINTK("ni_pcidio: command started\n");
1002	return 0;
1003}
1004
1005static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
1006{
1007	int retval;
1008
1009	retval = ni_pcidio_request_di_mite_channel(dev);
1010	if (retval)
1011		return retval;
1012
1013	devpriv->di_mite_chan->dir = COMEDI_INPUT;
1014
1015	mite_prep_dma(devpriv->di_mite_chan, 32, 32);
1016
1017	mite_dma_arm(devpriv->di_mite_chan);
1018	return 0;
1019}
1020
1021static int ni_pcidio_inttrig(struct comedi_device *dev,
1022			     struct comedi_subdevice *s, unsigned int trignum)
1023{
1024	if (trignum != 0)
1025		return -EINVAL;
1026
1027	writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
1028	s->async->inttrig = NULL;
1029
1030	return 1;
1031}
1032
1033static int ni_pcidio_cancel(struct comedi_device *dev,
1034			    struct comedi_subdevice *s)
1035{
1036	writeb(0x00,
1037	       devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
1038	ni_pcidio_release_di_mite_channel(dev);
1039
1040	return 0;
1041}
1042
1043static int ni_pcidio_change(struct comedi_device *dev,
1044			    struct comedi_subdevice *s, unsigned long new_size)
1045{
1046	int ret;
1047
1048	ret = mite_buf_change(devpriv->di_mite_ring, s->async);
1049	if (ret < 0)
1050		return ret;
1051
1052	memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
1053
1054	return 0;
1055}
1056
1057static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
1058			      u8 *data, int data_len)
1059{
1060	static const int timeout = 1000;
1061	int i, j;
1062	writew(0x80 | fpga_index,
1063	       devpriv->mite->daq_io_addr + Firmware_Control_Register);
1064	writew(0xc0 | fpga_index,
1065	       devpriv->mite->daq_io_addr + Firmware_Control_Register);
1066	for (i = 0;
1067	     (readw(devpriv->mite->daq_io_addr +
1068		    Firmware_Status_Register) & 0x2) == 0 && i < timeout; ++i) {
1069		udelay(1);
1070	}
1071	if (i == timeout) {
1072		printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, "
1073		       "waiting for status 0x2\n", fpga_index);
1074		return -EIO;
1075	}
1076	writew(0x80 | fpga_index,
1077	       devpriv->mite->daq_io_addr + Firmware_Control_Register);
1078	for (i = 0;
1079	     readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
1080	     0x3 && i < timeout; ++i) {
1081		udelay(1);
1082	}
1083	if (i == timeout) {
1084		printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, "
1085		       "waiting for status 0x3\n", fpga_index);
1086		return -EIO;
1087	}
1088	for (j = 0; j + 1 < data_len;) {
1089		unsigned int value = data[j++];
1090		value |= data[j++] << 8;
1091		writew(value,
1092		       devpriv->mite->daq_io_addr + Firmware_Data_Register);
1093		for (i = 0;
1094		     (readw(devpriv->mite->daq_io_addr +
1095			    Firmware_Status_Register) & 0x2) == 0
1096		     && i < timeout; ++i) {
1097			udelay(1);
1098		}
1099		if (i == timeout) {
1100			printk("ni_pcidio: failed to load word into fpga %i\n",
1101			       fpga_index);
1102			return -EIO;
1103		}
1104		if (need_resched())
1105			schedule();
1106	}
1107	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1108	return 0;
1109}
1110
1111static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index)
1112{
1113	return pci_6534_load_fpga(dev, fpga_index, NULL, 0);
1114}
1115
1116static int pci_6534_reset_fpgas(struct comedi_device *dev)
1117{
1118	int ret;
1119	int i;
1120	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1121	for (i = 0; i < 3; ++i) {
1122		ret = pci_6534_reset_fpga(dev, i);
1123		if (ret < 0)
1124			break;
1125	}
1126	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
1127	return ret;
1128}
1129
1130static void pci_6534_init_main_fpga(struct comedi_device *dev)
1131{
1132	writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
1133	writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
1134	writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
1135	writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
1136	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
1137	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
1138}
1139
1140static int pci_6534_upload_firmware(struct comedi_device *dev, int options[])
1141{
1142	int ret;
1143	void *main_fpga_data, *scarab_a_data, *scarab_b_data;
1144	int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len;
1145
1146	if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0)
1147		return 0;
1148	ret = pci_6534_reset_fpgas(dev);
1149	if (ret < 0)
1150		return ret;
1151	main_fpga_data = comedi_aux_data(options, 0);
1152	main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH];
1153	ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len);
1154	if (ret < 0)
1155		return ret;
1156	pci_6534_init_main_fpga(dev);
1157	scarab_a_data = comedi_aux_data(options, 1);
1158	scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH];
1159	ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len);
1160	if (ret < 0)
1161		return ret;
1162	scarab_b_data = comedi_aux_data(options, 2);
1163	scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH];
1164	ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len);
1165	if (ret < 0)
1166		return ret;
1167	return 0;
1168}
1169
1170static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1171{
1172	struct comedi_subdevice *s;
1173	int i;
1174	int ret;
1175	int n_subdevices;
1176	unsigned int irq;
1177
1178	printk(KERN_INFO "comedi%d: nidio:", dev->minor);
1179
1180	ret = alloc_private(dev, sizeof(struct nidio96_private));
1181	if (ret < 0)
1182		return ret;
1183	spin_lock_init(&devpriv->mite_channel_lock);
1184
1185	ret = nidio_find_device(dev, it->options[0], it->options[1]);
1186	if (ret < 0)
1187		return ret;
1188
1189	ret = mite_setup(devpriv->mite);
1190	if (ret < 0) {
1191		printk(KERN_WARNING "error setting up mite\n");
1192		return ret;
1193	}
1194	comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
1195	devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
1196	if (devpriv->di_mite_ring == NULL)
1197		return -ENOMEM;
1198
1199	dev->board_name = this_board->name;
1200	irq = mite_irq(devpriv->mite);
1201	printk(KERN_INFO " %s", dev->board_name);
1202	if (this_board->uses_firmware) {
1203		ret = pci_6534_upload_firmware(dev, it->options);
1204		if (ret < 0)
1205			return ret;
1206	}
1207	if (!this_board->is_diodaq)
1208		n_subdevices = this_board->n_8255;
1209	else
1210		n_subdevices = 1;
1211
1212	ret = alloc_subdevices(dev, n_subdevices);
1213	if (ret < 0)
1214		return ret;
1215
1216	if (!this_board->is_diodaq) {
1217		for (i = 0; i < this_board->n_8255; i++) {
1218			subdev_8255_init(dev, dev->subdevices + i,
1219					 nidio96_8255_cb,
1220					 (unsigned long)(devpriv->mite->
1221							 daq_io_addr +
1222							 NIDIO_8255_BASE(i)));
1223		}
1224	} else {
1225
1226		printk(KERN_INFO " rev=%d",
1227		       readb(devpriv->mite->daq_io_addr + Chip_Version));
1228
1229		s = dev->subdevices + 0;
1230
1231		dev->read_subdev = s;
1232		s->type = COMEDI_SUBD_DIO;
1233		s->subdev_flags =
1234		    SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
1235		    SDF_CMD_READ;
1236		s->n_chan = 32;
1237		s->range_table = &range_digital;
1238		s->maxdata = 1;
1239		s->insn_config = &ni_pcidio_insn_config;
1240		s->insn_bits = &ni_pcidio_insn_bits;
1241		s->do_cmd = &ni_pcidio_cmd;
1242		s->do_cmdtest = &ni_pcidio_cmdtest;
1243		s->cancel = &ni_pcidio_cancel;
1244		s->len_chanlist = 32;	/* XXX */
1245		s->buf_change = &ni_pcidio_change;
1246		s->async_dma_dir = DMA_BIDIRECTIONAL;
1247
1248		writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
1249		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
1250		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0));
1251
1252		/* disable interrupts on board */
1253		writeb(0x00,
1254		       devpriv->mite->daq_io_addr +
1255		       Master_DMA_And_Interrupt_Control);
1256
1257		ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
1258				  "ni_pcidio", dev);
1259		if (ret < 0)
1260			printk(KERN_WARNING " irq not available");
1261
1262		dev->irq = irq;
1263	}
1264
1265	printk("\n");
1266
1267	return 0;
1268}
1269
1270static int nidio_detach(struct comedi_device *dev)
1271{
1272	int i;
1273
1274	if (this_board && !this_board->is_diodaq) {
1275		for (i = 0; i < this_board->n_8255; i++)
1276			subdev_8255_cleanup(dev, dev->subdevices + i);
1277	}
1278
1279	if (dev->irq)
1280		free_irq(dev->irq, dev);
1281
1282	if (devpriv) {
1283		if (devpriv->di_mite_ring) {
1284			mite_free_ring(devpriv->di_mite_ring);
1285			devpriv->di_mite_ring = NULL;
1286		}
1287		if (devpriv->mite)
1288			mite_unsetup(devpriv->mite);
1289	}
1290	return 0;
1291}
1292
1293static int nidio_find_device(struct comedi_device *dev, int bus, int slot)
1294{
1295	struct mite_struct *mite;
1296	int i;
1297
1298	for (mite = mite_devices; mite; mite = mite->next) {
1299		if (mite->used)
1300			continue;
1301		if (bus || slot) {
1302			if (bus != mite->pcidev->bus->number ||
1303			    slot != PCI_SLOT(mite->pcidev->devfn))
1304				continue;
1305		}
1306		for (i = 0; i < n_nidio_boards; i++) {
1307			if (mite_device_id(mite) == nidio_boards[i].dev_id) {
1308				dev->board_ptr = nidio_boards + i;
1309				devpriv->mite = mite;
1310
1311				return 0;
1312			}
1313		}
1314	}
1315	printk(KERN_WARNING "no device found\n");
1316	mite_list_devices();
1317	return -EIO;
1318}
1319
1320static int __devinit driver_pcidio_pci_probe(struct pci_dev *dev,
1321					     const struct pci_device_id *ent)
1322{
1323	return comedi_pci_auto_config(dev, driver_pcidio.driver_name);
1324}
1325
1326static void __devexit driver_pcidio_pci_remove(struct pci_dev *dev)
1327{
1328	comedi_pci_auto_unconfig(dev);
1329}
1330
1331static struct pci_driver driver_pcidio_pci_driver = {
1332	.id_table = ni_pcidio_pci_table,
1333	.probe = &driver_pcidio_pci_probe,
1334	.remove = __devexit_p(&driver_pcidio_pci_remove)
1335};
1336
1337static int __init driver_pcidio_init_module(void)
1338{
1339	int retval;
1340
1341	retval = comedi_driver_register(&driver_pcidio);
1342	if (retval < 0)
1343		return retval;
1344
1345	driver_pcidio_pci_driver.name = (char *)driver_pcidio.driver_name;
1346	return pci_register_driver(&driver_pcidio_pci_driver);
1347}
1348
1349static void __exit driver_pcidio_cleanup_module(void)
1350{
1351	pci_unregister_driver(&driver_pcidio_pci_driver);
1352	comedi_driver_unregister(&driver_pcidio);
1353}
1354
1355module_init(driver_pcidio_init_module);
1356module_exit(driver_pcidio_cleanup_module);
1357
1358MODULE_AUTHOR("Comedi http://www.comedi.org");
1359MODULE_DESCRIPTION("Comedi low-level driver");
1360MODULE_LICENSE("GPL");
1361