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
7 COMEDI - Linux Control and Measurement Device Interface
8 Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
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.
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.
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.
27 Description: National Instruments PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503
30 Devices: [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-6534, PCI-6533
33 Updated: Sun, 21 Apr 2002 21:03:38 -0700
35 The DIO-96 appears as four 8255 subdevices. See the 8255
36 driver notes for details.
38 The DIO32HS board appears as one subdevice, with 32 channels.
39 Each channel is individually I/O configurable. The channel order
40 is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0. The driver only
41 supports simple digital I/O; no handshaking is supported.
43 DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
45 This driver could be easily modified to support AT-MIO32HS and
50 This driver is for both the NI PCI-DIO-32HS and the PCI-DIO-96,
51 which have very different architectures. But, since the '96 is
52 so simple, it is included here.
54 Manuals (available from ftp://ftp.natinst.com/support/manuals)
56 320938c.pdf PCI-DIO-96/PXI-6508/PCI-6503 User Manual
57 321464b.pdf AT/PCI-DIO-32HS User Manual
58 341329A.pdf PCI-6533 Register-Level Programmer Manual
59 341330A.pdf DAQ-DIO Technical Reference Manual
67 #include <linux/kernel.h>
68 #include <linux/module.h>
69 #include <linux/comedidev.h>
70 #include <linux/errno.h>
71 #include <linux/ioport.h>
72 #include <linux/slab.h>
73 #include <linux/delay.h>
74 #include <linux/irq.h>
75 #include <linux/init.h>
84 #define DPRINTK(format, args...) printk(format, ## args)
86 #define DPRINTK(format, args...)
89 #define PCI_VENDOR_ID_NATINST 0x1093
91 #define PCI_DIO_SIZE 4096
92 #define PCI_MITE_SIZE 4096
94 /* defines for the PCI-DIO-96 */
96 #define NIDIO_8255_BASE(x) ((x)*4)
102 /* defines for the PCI-DIO-32HS */
104 #define Window_Address 4 /* W */
105 #define Interrupt_And_Window_Status 4 /* R */
106 #define IntStatus1 (1<<0)
107 #define IntStatus2 (1<<1)
108 #define WindowAddressStatus_mask 0x7c
110 #define Master_DMA_And_Interrupt_Control 5 /* W */
111 #define InterruptLine(x) ((x)&3)
112 #define OpenInt (1<<2)
113 #define Group_Status 5 /* R */
114 #define DataLeft (1<<0)
116 #define StopTrig (1<<3)
118 #define Group_1_Flags 6 /* R */
119 #define Group_2_Flags 7 /* R */
120 #define TransferReady (1<<0)
121 #define CountExpired (1<<1)
122 #define Waited (1<<5)
123 #define PrimaryTC (1<<6)
124 #define SecondaryTC (1<<7)
129 #define Group_1_First_Clear 6 /* W */
130 #define Group_2_First_Clear 7 /* W */
131 #define ClearWaited (1<<3)
132 #define ClearPrimaryTC (1<<4)
133 #define ClearSecondaryTC (1<<5)
134 #define DMAReset (1<<6)
135 #define FIFOReset (1<<7)
136 #define ClearAll 0xf8
138 #define Group_1_FIFO 8 /* W */
139 #define Group_2_FIFO 12 /* W */
141 #define Transfer_Count 20
145 #define Chip_Version 27
146 #define Port_IO(x) (28+(x))
147 #define Port_Pin_Directions(x) (32+(x))
148 #define Port_Pin_Mask(x) (36+(x))
149 #define Port_Pin_Polarities(x) (40+(x))
151 #define Master_Clock_Routing 45
152 #define RTSIClocking(x) (((x)&3)<<4)
154 #define Group_1_Second_Clear 46 /* W */
155 #define Group_2_Second_Clear 47 /* W */
156 #define ClearExpired (1<<0)
158 #define Port_Pattern(x) (48+(x))
161 #define FIFOEnableA (1<<0)
162 #define FIFOEnableB (1<<1)
163 #define FIFOEnableC (1<<2)
164 #define FIFOEnableD (1<<3)
165 #define Funneling(x) (((x)&3)<<4)
166 #define GroupDirection (1<<7)
168 #define Protocol_Register_1 65
169 #define OpMode Protocol_Register_1
170 #define RunMode(x) ((x)&7)
171 #define Numbered (1<<3)
173 #define Protocol_Register_2 66
174 #define ClockReg Protocol_Register_2
175 #define ClockLine(x) (((x)&3)<<5)
176 #define InvertStopTrig (1<<7)
178 #define Protocol_Register_3 67
179 #define Sequence Protocol_Register_3
181 #define Protocol_Register_14 68 /* 16 bit */
182 #define ClockSpeed Protocol_Register_14
184 #define Protocol_Register_4 70
185 #define ReqReg Protocol_Register_4
186 #define ReqConditioning(x) (((x)&7)<<3)
188 #define Protocol_Register_5 71
189 #define BlockMode Protocol_Register_5
191 #define FIFO_Control 72
192 #define ReadyLevel(x) ((x)&7)
194 #define Protocol_Register_6 73
195 #define LinePolarities Protocol_Register_6
196 #define InvertAck (1<<0)
197 #define InvertReq (1<<1)
198 #define InvertClock (1<<2)
199 #define InvertSerial (1<<3)
200 #define OpenAck (1<<4)
201 #define OpenClock (1<<5)
203 #define Protocol_Register_7 74
204 #define AckSer Protocol_Register_7
205 #define AckLine(x) (((x)&3)<<2)
206 #define ExchangePins (1<<7)
208 #define Interrupt_Control 75
209 /* bits same as flags */
211 #define DMA_Line_Control 76
212 #define DMAChannel(x) ((x)&0xf)
214 #define Transfer_Size_Control 77
215 #define TransferWidth(x) ((x)&3)
216 #define TransferLength(x) (((x)&3)<<3)
217 #define RequireRLevel (1<<5)
219 #define Protocol_Register_15 79
220 #define DAQOptions Protocol_Register_15
221 #define StartSource(x) ((x)&0x3)
222 #define InvertStart (1<<2)
223 #define StopSource(x) (((x)&0x3)<<3)
224 #define ReqStart (1<<6)
225 #define PreStart (1<<7)
227 #define Pattern_Detection 81
228 #define DetectionMethod (1<<0)
229 #define InvertMatch (1<<1)
230 #define IE_Pattern_Detection (1<<2)
232 #define Protocol_Register_9 82
233 #define ReqDelay Protocol_Register_9
235 #define Protocol_Register_10 83
236 #define ReqNotDelay Protocol_Register_10
238 #define Protocol_Register_11 84
239 #define AckDelay Protocol_Register_11
241 #define Protocol_Register_12 85
242 #define AckNotDelay Protocol_Register_12
244 #define Protocol_Register_13 86
245 #define Data1Delay Protocol_Register_13
247 #define Protocol_Register_8 88 /* 32 bit */
248 #define StartDelay Protocol_Register_8
251 #define TIMER_BASE 50 /* nanoseconds */
254 #define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC)
256 #define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC)
259 static int nidio_attach(comedi_device *dev,comedi_devconfig *it);
260 static int nidio_detach(comedi_device *dev);
261 static comedi_driver driver_pcidio={
262 driver_name: "ni_pcidio",
264 attach: nidio_attach,
265 detach: nidio_detach,
267 COMEDI_INITCLEANUP(driver_pcidio);
275 static nidio_board nidio_boards[]={
278 name: "pci-dio-32hs",
337 #define n_nidio_boards (sizeof(nidio_boards)/sizeof(nidio_boards[0]))
338 #define this_board ((nidio_board *)dev->board_ptr)
340 static struct pci_device_id ni_pcidio_pci_table[] __devinitdata = {
341 { PCI_VENDOR_ID_NATINST, 0x1150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
342 { PCI_VENDOR_ID_NATINST, 0x1320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
343 { PCI_VENDOR_ID_NATINST, 0x0160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
344 { PCI_VENDOR_ID_NATINST, 0x1630, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
345 { PCI_VENDOR_ID_NATINST, 0x13c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
346 { PCI_VENDOR_ID_NATINST, 0x0400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
347 { PCI_VENDOR_ID_NATINST, 0x1250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
348 { PCI_VENDOR_ID_NATINST, 0x17d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
349 { PCI_VENDOR_ID_NATINST, 0x1800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
352 MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
355 struct mite_struct *mite;
359 #define devpriv ((nidio96_private *)dev->private)
361 static int ni_pcidio_cmdtest(comedi_device *dev,comedi_subdevice *s,
363 static int ni_pcidio_cmd(comedi_device *dev,comedi_subdevice *s);
364 static int ni_pcidio_inttrig(comedi_device *dev, comedi_subdevice *s,
365 unsigned int trignum);
366 static int nidio_find_device(comedi_device *dev,int bus,int slot);
367 static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
368 static void setup_mite_dma(comedi_device *dev,comedi_subdevice *s);
371 static void ni_pcidio_print_flags(unsigned int flags);
372 static void ni_pcidio_print_status(unsigned int status);
374 #define ni_pcidio_print_flags(x)
375 #define ni_pcidio_print_status(x)
378 static int nidio96_8255_cb(int dir,int port,int data,unsigned long iobase)
381 writeb(data,iobase+port);
384 return readb(iobase+port);
388 static void nidio_interrupt(int irq, void *d, struct pt_regs *regs)
390 comedi_device *dev=d;
391 comedi_subdevice *s = dev->subdevices;
392 comedi_async *async = s->async;
393 struct mite_struct *mite = devpriv->mite;
395 long int AuxData = 0;
401 unsigned int m_status;
403 status = readb(dev->iobase+Interrupt_And_Window_Status);
404 flags = readb(dev->iobase+Group_1_Flags);
405 m_status = readl(mite->mite_io_addr + MITE_CHSR + CHAN_OFFSET(1));
407 //interrupcions parasites
408 if(dev->attached == 0){
409 comedi_error(dev,"premature interrupt");
410 async->events |= COMEDI_CB_ERROR|COMEDI_CB_EOA;
413 DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x,m_status=0x%08x\n",
414 status,flags,m_status);
415 ni_pcidio_print_flags(flags);
416 ni_pcidio_print_status(status);
418 mite_print_chsr(m_status);
420 //printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,1));
421 //mite_dump_regs(mite);
423 //printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf);
424 //printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096));
426 if(m_status & CHSR_INT){
427 if(m_status & CHSR_LINKC){
430 writel(CHOR_CLRLC, mite->mite_io_addr + MITE_CHOR + CHAN_OFFSET(1));
431 count = le32_to_cpu(mite->ring[mite->current_link].count);
433 /* XXX need to byteswap */
435 async->buf_write_count += count;
436 async->buf_write_ptr += count;
437 if(async->buf_write_ptr >= async->data_len){
438 async->buf_write_ptr -= async->data_len;
440 mite->current_link++;
441 if(mite->current_link >= mite->n_links){
442 mite->current_link=0;
445 if(m_status & CHSR_DONE){
446 writel(CHOR_CLRDONE, mite->mite_io_addr + MITE_CHOR +
449 if(m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY | CHSR_DRQ1)){
450 DPRINTK("unknown mite interrupt, disabling IRQ\n");
451 writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR +
453 disable_irq(dev->irq);
455 async->events |= COMEDI_CB_BLOCK;
458 while(status&DataLeft){
461 DPRINTK("too much work in interrupt\n");
462 writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control);
468 if(flags & TransferReady){
469 //DPRINTK("TransferReady\n");
470 while(flags & TransferReady){
473 DPRINTK("too much work in interrupt\n");
474 writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control);
477 AuxData = readl(dev->iobase+Group_1_FIFO);
478 data1 = AuxData & 0xffff;
479 data2 = (AuxData & 0xffff0000) >> 16;
480 comedi_buf_put(async,data1);
481 comedi_buf_put(async,data2);
482 //DPRINTK("read:%d, %d\n",data1,data2);
483 flags = readb(dev->iobase+Group_1_Flags);
485 //DPRINTK("buf_int_count: %d\n",async->buf_int_count);
486 //DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status);
487 //ni_pcidio_print_flags(flags);
488 //ni_pcidio_print_status(status);
489 async->events |= COMEDI_CB_BLOCK;
492 if(flags & CountExpired){
493 DPRINTK("CountExpired\n");
494 writeb(ClearExpired,dev->iobase+Group_1_Second_Clear);
495 async->events |= COMEDI_CB_EOA;
497 writeb(0x00,dev->iobase+OpMode);
498 writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control);
500 mite_dma_disarm(mite);
501 writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR +
505 }else if(flags & Waited){
507 writeb(ClearWaited,dev->iobase+Group_1_First_Clear);
508 writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control);
509 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
511 mite_dma_disarm(mite);
512 writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR +
516 }else if(flags & PrimaryTC){
517 DPRINTK("PrimaryTC\n");
518 writeb(ClearPrimaryTC,dev->iobase+Group_1_First_Clear);
519 async->events |= COMEDI_CB_EOA;
520 writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control);
521 }else if(flags & SecondaryTC){
522 DPRINTK("SecondaryTC\n");
523 writeb(ClearSecondaryTC,dev->iobase+Group_1_First_Clear);
524 async->events |= COMEDI_CB_EOA;
525 writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control);
529 printk("ni_pcidio: unknown interrupt\n");
530 async->events |= COMEDI_CB_ERROR|COMEDI_CB_EOA;
531 writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control);
534 flags = readb(dev->iobase+Group_1_Flags);
535 status = readb(dev->iobase+Interrupt_And_Window_Status);
536 //DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n",
537 // IntEn,flags,status);
538 //ni_pcidio_print_flags(flags);
539 //ni_pcidio_print_status(status);
543 comedi_event(dev,s,async->events);
547 writeb(0x03,dev->iobase+Master_DMA_And_Interrupt_Control);
554 static char *flags_strings[] = {
555 "TransferReady", "CountExpired", "2", "3",
556 "4", "Waited", "PrimaryTC", "SecondaryTC",
558 static void ni_pcidio_print_flags(unsigned int flags)
562 printk("group_1_flags:");
565 printk(" %s",flags_strings[i]);
570 static char *status_strings[] = {
571 "DataLeft1", "Reserved1", "Req1", "StopTrig1",
572 "DataLeft2", "Reserved2", "Req2", "StopTrig2",
574 static void ni_pcidio_print_status(unsigned int flags)
578 printk("group_status:");
581 printk(" %s",status_strings[i]);
589 static void debug_int(comedi_device *dev)
592 static int n_int = 0;
595 do_gettimeofday(&tv);
596 a=readb(dev->iobase+Group_Status);
597 b=readb(dev->iobase+Group_1_Flags);
600 DPRINTK("status 0x%02x flags 0x%02x time %06d\n",a,b,(int)tv.tv_usec);
604 writew(0xff,dev->iobase+Group_1_FIFO);
605 b=readb(dev->iobase+Group_1_Flags);
608 b=readb(dev->iobase+Group_1_Flags);
611 DPRINTK("new status 0x%02x\n",b);
618 static int ni_pcidio_insn_config(comedi_device *dev,comedi_subdevice *s,
619 comedi_insn *insn,lsampl_t *data)
621 if(insn->n!=1)return -EINVAL;
624 s->io_bits |= 1<<CR_CHAN(insn->chanspec);
627 s->io_bits &= ~(1<<CR_CHAN(insn->chanspec));
632 writel(s->io_bits,dev->iobase+Port_Pin_Directions(0));
637 static int ni_pcidio_insn_bits(comedi_device *dev,comedi_subdevice *s,
638 comedi_insn *insn,lsampl_t *data)
640 if(insn->n!=2)return -EINVAL;
642 s->state &= ~data[0];
643 s->state |= (data[0]&data[1]);
644 writel(s->state,dev->iobase+Port_IO(0));
646 data[1] = readl(dev->iobase+Port_IO(0));
651 static int ni_pcidio_cmdtest(comedi_device *dev,comedi_subdevice *s,
657 /* step 1: make sure trigger sources are trivially valid */
660 cmd->start_src &= TRIG_NOW|TRIG_INT;
661 if(!cmd->start_src || tmp!=cmd->start_src)err++;
663 tmp=cmd->scan_begin_src;
664 cmd->scan_begin_src &= TRIG_TIMER|TRIG_EXT;
665 if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
667 tmp=cmd->convert_src;
668 cmd->convert_src &= TRIG_NOW;
669 if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
671 tmp=cmd->scan_end_src;
672 cmd->scan_end_src &= TRIG_COUNT;
673 if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
676 cmd->stop_src &= TRIG_COUNT;
677 if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
681 /* step 2: make sure trigger sources are unique and mutually compatible */
683 /* note that mutual compatiblity is not an issue here */
684 if(cmd->start_src!=TRIG_NOW &&
685 cmd->start_src!=TRIG_INT)err++;
686 if(cmd->scan_begin_src!=TRIG_TIMER &&
687 cmd->scan_begin_src!=TRIG_EXT)err++;
691 /* step 3: make sure arguments are trivially compatible */
693 if(cmd->start_arg!=0){
694 /* same for both TRIG_INT and TRIG_NOW */
699 #define MAX_SPEED (TIMER_BASE) /* in nanoseconds */
701 if(cmd->scan_begin_src==TRIG_TIMER){
702 if(cmd->scan_begin_arg<MAX_SPEED){
703 cmd->scan_begin_arg=MAX_SPEED;
706 /* no minumum speed */
709 /* should be level/edge, hi/lo specification here */
710 if(cmd->scan_begin_arg!=0){
711 cmd->scan_begin_arg=0;
715 if(cmd->convert_arg!=0){
716 cmd->convert_arg = 0;
720 if(cmd->scan_end_arg!=cmd->chanlist_len){
721 cmd->scan_end_arg=cmd->chanlist_len;
724 if(cmd->stop_src==TRIG_COUNT){
728 if(cmd->stop_arg!=0){
736 /* step 4: fix up any arguments */
738 if(cmd->scan_begin_src == TRIG_TIMER){
739 tmp = cmd->scan_begin_arg;
740 ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
741 cmd->flags&TRIG_ROUND_MASK);
742 if(tmp!=cmd->scan_begin_arg)err++;
751 static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
758 case TRIG_ROUND_NEAREST:
760 divider = (*nanosec + base/2)/base;
762 case TRIG_ROUND_DOWN:
763 divider = (*nanosec)/base;
766 divider = (*nanosec + base - 1)/base;
770 *nanosec = base * divider;
775 static int ni_pcidio_cmd(comedi_device *dev,comedi_subdevice *s)
777 comedi_cmd *cmd = &s->async->cmd;
779 /* XXX configure ports for input*/
780 writel(0x0000,dev->iobase+Port_Pin_Directions(0));
783 /* enable fifos A B C D */
784 writeb(0x0f,dev->iobase+Data_Path);
786 /* set transfer width a 32 bits*/
787 writeb(TransferWidth(0) | TransferLength(0),
788 dev->iobase+Transfer_Size_Control);
790 writeb(0x03,dev->iobase+Data_Path);
791 writeb(TransferWidth(3) | TransferLength(0),
792 dev->iobase+Transfer_Size_Control);
795 /* protocol configuration */
796 if(cmd->scan_begin_src == TRIG_TIMER){
797 /* page 4-5, "input with internal REQs" */
798 writeb( 0 ,dev->iobase+OpMode);
799 writeb(0x00,dev->iobase+ClockReg);
800 writeb( 1 ,dev->iobase+Sequence);
801 writeb(0x04,dev->iobase+ReqReg);
802 writeb( 4 ,dev->iobase+BlockMode);
803 writeb( 3 ,dev->iobase+LinePolarities);
804 writeb(0xc0,dev->iobase+AckSer);
805 writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
806 TRIG_ROUND_NEAREST),dev->iobase+StartDelay);
807 writeb( 1 ,dev->iobase+ReqDelay);
808 writeb( 1 ,dev->iobase+ReqNotDelay);
809 writeb( 1 ,dev->iobase+AckDelay);
810 writeb(0x0b,dev->iobase+AckNotDelay);
811 writeb(0x01,dev->iobase+Data1Delay);
812 /* manual, page 4-5: ClockSpeed comment is incorrectly listed
814 writew(0 ,dev->iobase+ClockSpeed);
815 writeb(0 ,dev->iobase+DAQOptions);
818 /* page 4-5, "input with external REQs" */
819 writeb( 0 ,dev->iobase+OpMode);
820 writeb(0x00,dev->iobase+ClockReg);
821 writeb( 0 ,dev->iobase+Sequence);
822 writeb(0x00,dev->iobase+ReqReg);
823 writeb( 4 ,dev->iobase+BlockMode);
824 writeb( 0 ,dev->iobase+LinePolarities);
825 writeb(0x00,dev->iobase+AckSer);
826 writel( 1 ,dev->iobase+StartDelay);
827 writeb( 1 ,dev->iobase+ReqDelay);
828 writeb( 1 ,dev->iobase+ReqNotDelay);
829 writeb( 1 ,dev->iobase+AckDelay);
830 writeb(0x0C,dev->iobase+AckNotDelay);
831 writeb(0x10,dev->iobase+Data1Delay);
832 writew( 0 ,dev->iobase+ClockSpeed);
833 writeb(0x60,dev->iobase+DAQOptions);
836 if(cmd->stop_src == TRIG_COUNT){
837 writel(cmd->stop_arg,dev->iobase+Transfer_Count);
843 writeb(0x05,dev->iobase+DMA_Line_Control);
844 writeb(0x30,dev->iobase+Group_1_First_Clear);
846 setup_mite_dma(dev,s);
848 writeb(0x00,dev->iobase+DMA_Line_Control);
851 /* clear and enable interrupts */
852 writeb(0xff,dev->iobase+Group_1_First_Clear);
853 //writeb(ClearExpired,dev->iobase+Group_1_Second_Clear);
855 writeb(IntEn,dev->iobase+Interrupt_Control);
856 writeb(0x03,dev->iobase+Master_DMA_And_Interrupt_Control);
858 if(cmd->start_src == TRIG_NOW){
860 writeb(Numbered | RunMode(7),dev->iobase+OpMode);
861 s->async->inttrig = NULL;
864 s->async->inttrig = ni_pcidio_inttrig;
867 DPRINTK("ni_pcidio: command started\n");
872 static void setup_mite_dma(comedi_device *dev,comedi_subdevice *s)
874 struct mite_struct *mite = devpriv->mite;
876 mite->current_link = 0;
878 mite->dir = COMEDI_INPUT;
887 static int ni_pcidio_inttrig(comedi_device *dev, comedi_subdevice *s,
888 unsigned int trignum)
890 if(trignum!=0)return -EINVAL;
892 writeb(Numbered | RunMode(7),dev->iobase+OpMode);
893 s->async->inttrig = NULL;
899 static int ni_pcidio_cancel(comedi_device *dev, comedi_subdevice *s)
901 writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control);
907 static int ni_pcidio_alloc(comedi_device *dev, comedi_subdevice *s,
908 unsigned long new_size)
912 ret = mite_buf_alloc(devpriv->mite, s->async, new_size);
915 memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
921 static int nidio_attach(comedi_device *dev,comedi_devconfig *it)
927 printk("comedi%d: nidio:",dev->minor);
929 if((ret=alloc_private(dev,sizeof(nidio96_private)))<0)
932 ret=nidio_find_device(dev,it->options[0],it->options[1]);
935 ret = mite_setup(devpriv->mite);
938 printk("error setting up mite\n");
941 dev->iobase = mite_iobase(devpriv->mite);
943 dev->board_name=this_board->name;
944 dev->irq=mite_irq(devpriv->mite);
945 printk(" %s",dev->board_name);
947 if(!this_board->is_diodaq){
948 dev->n_subdevices=this_board->n_8255;
952 if((ret=alloc_subdevices(dev))<0)
955 if(!this_board->is_diodaq){
956 for(i=0;i<this_board->n_8255;i++){
957 subdev_8255_init(dev,dev->subdevices+i,
958 nidio96_8255_cb,(unsigned long)(dev->iobase+NIDIO_8255_BASE(i)));
962 printk(" rev=%d",readb(dev->iobase+Chip_Version));
966 dev->read_subdev = s;
967 s->type=COMEDI_SUBD_DIO;
968 s->subdev_flags=SDF_READABLE|SDF_WRITABLE|SDF_RT;
970 s->range_table=&range_digital;
972 s->insn_config = ni_pcidio_insn_config;
973 s->insn_bits = ni_pcidio_insn_bits;
974 s->do_cmd = ni_pcidio_cmd;
975 s->do_cmdtest = ni_pcidio_cmdtest;
976 s->cancel = ni_pcidio_cancel;
977 s->len_chanlist=32; /* XXX */
978 s->buf_alloc = ni_pcidio_alloc;
980 writel(0,dev->iobase+Port_IO(0));
981 writel(0,dev->iobase+Port_Pin_Directions(0));
982 writel(0,dev->iobase+Port_Pin_Mask(0));
984 /* disable interrupts on board */
985 writeb(0x00,dev->iobase+Master_DMA_And_Interrupt_Control);
987 ret=comedi_request_irq(dev->irq,nidio_interrupt,SA_SHIRQ,"ni_pcidio",dev);
990 printk(" irq not available");
994 devpriv->mite->chan = 1;
1001 static int nidio_detach(comedi_device *dev)
1005 if(this_board && !this_board->is_diodaq){
1006 for(i=0;i<this_board->n_8255;i++){
1007 subdev_8255_cleanup(dev,dev->subdevices+i);
1012 comedi_free_irq(dev->irq,dev);
1014 if(devpriv && devpriv->mite)
1015 mite_unsetup(devpriv->mite);
1021 static int nidio_find_device(comedi_device *dev,int bus,int slot)
1023 struct mite_struct *mite;
1026 for(mite=mite_devices;mite;mite=mite->next){
1027 if(mite->used)continue;
1029 if(bus!=(mite->pcidev->bus->number<<8) ||
1030 slot!=PCI_SLOT(mite->pcidev->devfn))
1033 for(i=0;i<n_nidio_boards;i++){
1034 if(mite_device_id(mite)==nidio_boards[i].dev_id){
1035 dev->board_ptr=nidio_boards+i;
1042 printk("no device found\n");
1043 mite_list_devices();