1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Comedi driver for National Instruments PCI-DIO-32HS
4 *
5 * COMEDI - Linux Control and Measurement Device Interface
6 * Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
7 */
8
9 /*
10 * Driver: ni_pcidio
11 * Description: National Instruments PCI-DIO32HS, PCI-6533
12 * Author: ds
13 * Status: works
14 * Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio)
15 * [National Instruments] PXI-6533, PCI-6533 (pxi-6533)
16 * [National Instruments] PCI-6534 (pci-6534)
17 * Updated: Mon, 09 Jan 2012 14:27:23 +0000
18 *
19 * The DIO32HS board appears as one subdevice, with 32 channels. Each
20 * channel is individually I/O configurable. The channel order is 0=A0,
21 * 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0. The driver only supports simple
22 * digital I/O; no handshaking is supported.
23 *
24 * DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
25 *
26 * The PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting
27 * scan_begin_arg to 0 or CR_EDGE triggers on the leading edge. Setting
28 * scan_begin_arg to CR_INVERT or (CR_EDGE | CR_INVERT) triggers on the
29 * trailing edge.
30 *
31 * This driver could be easily modified to support AT-MIO32HS and AT-MIO96.
32 *
33 * The PCI-6534 requires a firmware upload after power-up to work, the
34 * firmware data and instructions for loading it with comedi_config
35 * it are contained in the comedi_nonfree_firmware tarball available from
36 * http://www.comedi.org
37 */
38
39 #define USE_DMA
40
41 #include <linux/module.h>
42 #include <linux/delay.h>
43 #include <linux/interrupt.h>
44 #include <linux/sched.h>
45
46 #include "../comedi_pci.h"
47
48 #include "mite.h"
49
50 /* defines for the PCI-DIO-32HS */
51
52 #define Window_Address 4 /* W */
53 #define Interrupt_And_Window_Status 4 /* R */
54 #define IntStatus1 BIT(0)
55 #define IntStatus2 BIT(1)
56 #define WindowAddressStatus_mask 0x7c
57
58 #define Master_DMA_And_Interrupt_Control 5 /* W */
59 #define InterruptLine(x) ((x) & 3)
60 #define OpenInt BIT(2)
61 #define Group_Status 5 /* R */
62 #define DataLeft BIT(0)
63 #define Req BIT(2)
64 #define StopTrig BIT(3)
65
66 #define Group_1_Flags 6 /* R */
67 #define Group_2_Flags 7 /* R */
68 #define TransferReady BIT(0)
69 #define CountExpired BIT(1)
70 #define Waited BIT(5)
71 #define PrimaryTC BIT(6)
72 #define SecondaryTC BIT(7)
73 /* #define SerialRose */
74 /* #define ReqRose */
75 /* #define Paused */
76
77 #define Group_1_First_Clear 6 /* W */
78 #define Group_2_First_Clear 7 /* W */
79 #define ClearWaited BIT(3)
80 #define ClearPrimaryTC BIT(4)
81 #define ClearSecondaryTC BIT(5)
82 #define DMAReset BIT(6)
83 #define FIFOReset BIT(7)
84 #define ClearAll 0xf8
85
86 #define Group_1_FIFO 8 /* W */
87 #define Group_2_FIFO 12 /* W */
88
89 #define Transfer_Count 20
90 #define Chip_ID_D 24
91 #define Chip_ID_I 25
92 #define Chip_ID_O 26
93 #define Chip_Version 27
94 #define Port_IO(x) (28 + (x))
95 #define Port_Pin_Directions(x) (32 + (x))
96 #define Port_Pin_Mask(x) (36 + (x))
97 #define Port_Pin_Polarities(x) (40 + (x))
98
99 #define Master_Clock_Routing 45
100 #define RTSIClocking(x) (((x) & 3) << 4)
101
102 #define Group_1_Second_Clear 46 /* W */
103 #define Group_2_Second_Clear 47 /* W */
104 #define ClearExpired BIT(0)
105
106 #define Port_Pattern(x) (48 + (x))
107
108 #define Data_Path 64
109 #define FIFOEnableA BIT(0)
110 #define FIFOEnableB BIT(1)
111 #define FIFOEnableC BIT(2)
112 #define FIFOEnableD BIT(3)
113 #define Funneling(x) (((x) & 3) << 4)
114 #define GroupDirection BIT(7)
115
116 #define Protocol_Register_1 65
117 #define OpMode Protocol_Register_1
118 #define RunMode(x) ((x) & 7)
119 #define Numbered BIT(3)
120
121 #define Protocol_Register_2 66
122 #define ClockReg Protocol_Register_2
123 #define ClockLine(x) (((x) & 3) << 5)
124 #define InvertStopTrig BIT(7)
125 #define DataLatching(x) (((x) & 3) << 5)
126
127 #define Protocol_Register_3 67
128 #define Sequence Protocol_Register_3
129
130 #define Protocol_Register_14 68 /* 16 bit */
131 #define ClockSpeed Protocol_Register_14
132
133 #define Protocol_Register_4 70
134 #define ReqReg Protocol_Register_4
135 #define ReqConditioning(x) (((x) & 7) << 3)
136
137 #define Protocol_Register_5 71
138 #define BlockMode Protocol_Register_5
139
140 #define FIFO_Control 72
141 #define ReadyLevel(x) ((x) & 7)
142
143 #define Protocol_Register_6 73
144 #define LinePolarities Protocol_Register_6
145 #define InvertAck BIT(0)
146 #define InvertReq BIT(1)
147 #define InvertClock BIT(2)
148 #define InvertSerial BIT(3)
149 #define OpenAck BIT(4)
150 #define OpenClock BIT(5)
151
152 #define Protocol_Register_7 74
153 #define AckSer Protocol_Register_7
154 #define AckLine(x) (((x) & 3) << 2)
155 #define ExchangePins BIT(7)
156
157 #define Interrupt_Control 75
158 /* bits same as flags */
159
160 #define DMA_Line_Control_Group1 76
161 #define DMA_Line_Control_Group2 108
162 /* channel zero is none */
primary_DMAChannel_bits(unsigned int channel)163 static inline unsigned int primary_DMAChannel_bits(unsigned int channel)
164 {
165 return channel & 0x3;
166 }
167
secondary_DMAChannel_bits(unsigned int channel)168 static inline unsigned int secondary_DMAChannel_bits(unsigned int channel)
169 {
170 return (channel << 2) & 0xc;
171 }
172
173 #define Transfer_Size_Control 77
174 #define TransferWidth(x) ((x) & 3)
175 #define TransferLength(x) (((x) & 3) << 3)
176 #define RequireRLevel BIT(5)
177
178 #define Protocol_Register_15 79
179 #define DAQOptions Protocol_Register_15
180 #define StartSource(x) ((x) & 0x3)
181 #define InvertStart BIT(2)
182 #define StopSource(x) (((x) & 0x3) << 3)
183 #define ReqStart BIT(6)
184 #define PreStart BIT(7)
185
186 #define Pattern_Detection 81
187 #define DetectionMethod BIT(0)
188 #define InvertMatch BIT(1)
189 #define IE_Pattern_Detection BIT(2)
190
191 #define Protocol_Register_9 82
192 #define ReqDelay Protocol_Register_9
193
194 #define Protocol_Register_10 83
195 #define ReqNotDelay Protocol_Register_10
196
197 #define Protocol_Register_11 84
198 #define AckDelay Protocol_Register_11
199
200 #define Protocol_Register_12 85
201 #define AckNotDelay Protocol_Register_12
202
203 #define Protocol_Register_13 86
204 #define Data1Delay Protocol_Register_13
205
206 #define Protocol_Register_8 88 /* 32 bit */
207 #define StartDelay Protocol_Register_8
208
209 /* Firmware files for PCI-6524 */
210 #define FW_PCI_6534_MAIN "ni6534a.bin"
211 #define FW_PCI_6534_SCARAB_DI "niscrb01.bin"
212 #define FW_PCI_6534_SCARAB_DO "niscrb02.bin"
213 MODULE_FIRMWARE(FW_PCI_6534_MAIN);
214 MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DI);
215 MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DO);
216
217 enum pci_6534_firmware_registers { /* 16 bit */
218 Firmware_Control_Register = 0x100,
219 Firmware_Status_Register = 0x104,
220 Firmware_Data_Register = 0x108,
221 Firmware_Mask_Register = 0x10c,
222 Firmware_Debug_Register = 0x110,
223 };
224
225 /* main fpga registers (32 bit)*/
226 enum pci_6534_fpga_registers {
227 FPGA_Control1_Register = 0x200,
228 FPGA_Control2_Register = 0x204,
229 FPGA_Irq_Mask_Register = 0x208,
230 FPGA_Status_Register = 0x20c,
231 FPGA_Signature_Register = 0x210,
232 FPGA_SCALS_Counter_Register = 0x280, /*write-clear */
233 FPGA_SCAMS_Counter_Register = 0x284, /*write-clear */
234 FPGA_SCBLS_Counter_Register = 0x288, /*write-clear */
235 FPGA_SCBMS_Counter_Register = 0x28c, /*write-clear */
236 FPGA_Temp_Control_Register = 0x2a0,
237 FPGA_DAR_Register = 0x2a8,
238 FPGA_ELC_Read_Register = 0x2b8,
239 FPGA_ELC_Write_Register = 0x2bc,
240 };
241
242 enum FPGA_Control_Bits {
243 FPGA_Enable_Bit = 0x8000,
244 };
245
246 #define TIMER_BASE 50 /* nanoseconds */
247
248 #ifdef USE_DMA
249 #define IntEn (CountExpired | Waited | PrimaryTC | SecondaryTC)
250 #else
251 #define IntEn (TransferReady | CountExpired | Waited | PrimaryTC | SecondaryTC)
252 #endif
253
254 enum nidio_boardid {
255 BOARD_PCIDIO_32HS,
256 BOARD_PXI6533,
257 BOARD_PCI6534,
258 };
259
260 struct nidio_board {
261 const char *name;
262 unsigned int uses_firmware:1;
263 };
264
265 static const struct nidio_board nidio_boards[] = {
266 [BOARD_PCIDIO_32HS] = {
267 .name = "pci-dio-32hs",
268 },
269 [BOARD_PXI6533] = {
270 .name = "pxi-6533",
271 },
272 [BOARD_PCI6534] = {
273 .name = "pci-6534",
274 .uses_firmware = 1,
275 },
276 };
277
278 struct nidio96_private {
279 struct mite *mite;
280 int boardtype;
281 int dio;
282 unsigned short OpModeBits;
283 struct mite_channel *di_mite_chan;
284 struct mite_ring *di_mite_ring;
285 spinlock_t mite_channel_lock;
286 };
287
ni_pcidio_request_di_mite_channel(struct comedi_device * dev)288 static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
289 {
290 struct nidio96_private *devpriv = dev->private;
291 unsigned long flags;
292
293 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
294 BUG_ON(devpriv->di_mite_chan);
295 devpriv->di_mite_chan =
296 mite_request_channel_in_range(devpriv->mite,
297 devpriv->di_mite_ring, 1, 2);
298 if (!devpriv->di_mite_chan) {
299 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
300 dev_err(dev->class_dev, "failed to reserve mite dma channel\n");
301 return -EBUSY;
302 }
303 devpriv->di_mite_chan->dir = COMEDI_INPUT;
304 writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
305 secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
306 dev->mmio + DMA_Line_Control_Group1);
307 mmiowb();
308 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
309 return 0;
310 }
311
ni_pcidio_release_di_mite_channel(struct comedi_device * dev)312 static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
313 {
314 struct nidio96_private *devpriv = dev->private;
315 unsigned long flags;
316
317 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
318 if (devpriv->di_mite_chan) {
319 mite_release_channel(devpriv->di_mite_chan);
320 devpriv->di_mite_chan = NULL;
321 writeb(primary_DMAChannel_bits(0) |
322 secondary_DMAChannel_bits(0),
323 dev->mmio + DMA_Line_Control_Group1);
324 mmiowb();
325 }
326 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
327 }
328
setup_mite_dma(struct comedi_device * dev,struct comedi_subdevice * s)329 static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
330 {
331 struct nidio96_private *devpriv = dev->private;
332 int retval;
333 unsigned long flags;
334
335 retval = ni_pcidio_request_di_mite_channel(dev);
336 if (retval)
337 return retval;
338
339 /* write alloc the entire buffer */
340 comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
341
342 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
343 if (devpriv->di_mite_chan) {
344 mite_prep_dma(devpriv->di_mite_chan, 32, 32);
345 mite_dma_arm(devpriv->di_mite_chan);
346 } else {
347 retval = -EIO;
348 }
349 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
350
351 return retval;
352 }
353
ni_pcidio_poll(struct comedi_device * dev,struct comedi_subdevice * s)354 static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
355 {
356 struct nidio96_private *devpriv = dev->private;
357 unsigned long irq_flags;
358 int count;
359
360 spin_lock_irqsave(&dev->spinlock, irq_flags);
361 spin_lock(&devpriv->mite_channel_lock);
362 if (devpriv->di_mite_chan)
363 mite_sync_dma(devpriv->di_mite_chan, s);
364 spin_unlock(&devpriv->mite_channel_lock);
365 count = comedi_buf_n_bytes_ready(s);
366 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
367 return count;
368 }
369
nidio_interrupt(int irq,void * d)370 static irqreturn_t nidio_interrupt(int irq, void *d)
371 {
372 struct comedi_device *dev = d;
373 struct nidio96_private *devpriv = dev->private;
374 struct comedi_subdevice *s = dev->read_subdev;
375 struct comedi_async *async = s->async;
376 unsigned int auxdata;
377 int flags;
378 int status;
379 int work = 0;
380
381 /* interrupcions parasites */
382 if (!dev->attached) {
383 /* assume it's from another card */
384 return IRQ_NONE;
385 }
386
387 /* Lock to avoid race with comedi_poll */
388 spin_lock(&dev->spinlock);
389
390 status = readb(dev->mmio + Interrupt_And_Window_Status);
391 flags = readb(dev->mmio + Group_1_Flags);
392
393 spin_lock(&devpriv->mite_channel_lock);
394 if (devpriv->di_mite_chan) {
395 mite_ack_linkc(devpriv->di_mite_chan, s, false);
396 /* XXX need to byteswap sync'ed dma */
397 }
398 spin_unlock(&devpriv->mite_channel_lock);
399
400 while (status & DataLeft) {
401 work++;
402 if (work > 20) {
403 dev_dbg(dev->class_dev, "too much work in interrupt\n");
404 writeb(0x00,
405 dev->mmio + Master_DMA_And_Interrupt_Control);
406 break;
407 }
408
409 flags &= IntEn;
410
411 if (flags & TransferReady) {
412 while (flags & TransferReady) {
413 work++;
414 if (work > 100) {
415 dev_dbg(dev->class_dev,
416 "too much work in interrupt\n");
417 writeb(0x00, dev->mmio +
418 Master_DMA_And_Interrupt_Control
419 );
420 goto out;
421 }
422 auxdata = readl(dev->mmio + Group_1_FIFO);
423 comedi_buf_write_samples(s, &auxdata, 1);
424 flags = readb(dev->mmio + Group_1_Flags);
425 }
426 }
427
428 if (flags & CountExpired) {
429 writeb(ClearExpired, dev->mmio + Group_1_Second_Clear);
430 async->events |= COMEDI_CB_EOA;
431
432 writeb(0x00, dev->mmio + OpMode);
433 break;
434 } else if (flags & Waited) {
435 writeb(ClearWaited, dev->mmio + Group_1_First_Clear);
436 async->events |= COMEDI_CB_ERROR;
437 break;
438 } else if (flags & PrimaryTC) {
439 writeb(ClearPrimaryTC,
440 dev->mmio + Group_1_First_Clear);
441 async->events |= COMEDI_CB_EOA;
442 } else if (flags & SecondaryTC) {
443 writeb(ClearSecondaryTC,
444 dev->mmio + Group_1_First_Clear);
445 async->events |= COMEDI_CB_EOA;
446 }
447
448 flags = readb(dev->mmio + Group_1_Flags);
449 status = readb(dev->mmio + Interrupt_And_Window_Status);
450 }
451
452 out:
453 comedi_handle_events(dev, s);
454 #if 0
455 if (!tag)
456 writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control);
457 #endif
458
459 spin_unlock(&dev->spinlock);
460 return IRQ_HANDLED;
461 }
462
ni_pcidio_insn_config(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)463 static int ni_pcidio_insn_config(struct comedi_device *dev,
464 struct comedi_subdevice *s,
465 struct comedi_insn *insn,
466 unsigned int *data)
467 {
468 int ret;
469
470 ret = comedi_dio_insn_config(dev, s, insn, data, 0);
471 if (ret)
472 return ret;
473
474 writel(s->io_bits, dev->mmio + Port_Pin_Directions(0));
475
476 return insn->n;
477 }
478
ni_pcidio_insn_bits(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)479 static int ni_pcidio_insn_bits(struct comedi_device *dev,
480 struct comedi_subdevice *s,
481 struct comedi_insn *insn,
482 unsigned int *data)
483 {
484 if (comedi_dio_update_state(s, data))
485 writel(s->state, dev->mmio + Port_IO(0));
486
487 data[1] = readl(dev->mmio + Port_IO(0));
488
489 return insn->n;
490 }
491
ni_pcidio_ns_to_timer(int * nanosec,unsigned int flags)492 static int ni_pcidio_ns_to_timer(int *nanosec, unsigned int flags)
493 {
494 int divider, base;
495
496 base = TIMER_BASE;
497
498 switch (flags & CMDF_ROUND_MASK) {
499 case CMDF_ROUND_NEAREST:
500 default:
501 divider = DIV_ROUND_CLOSEST(*nanosec, base);
502 break;
503 case CMDF_ROUND_DOWN:
504 divider = (*nanosec) / base;
505 break;
506 case CMDF_ROUND_UP:
507 divider = DIV_ROUND_UP(*nanosec, base);
508 break;
509 }
510
511 *nanosec = base * divider;
512 return divider;
513 }
514
ni_pcidio_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)515 static int ni_pcidio_cmdtest(struct comedi_device *dev,
516 struct comedi_subdevice *s, struct comedi_cmd *cmd)
517 {
518 int err = 0;
519 unsigned int arg;
520
521 /* Step 1 : check if triggers are trivially valid */
522
523 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
524 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
525 TRIG_TIMER | TRIG_EXT);
526 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
527 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
528 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
529
530 if (err)
531 return 1;
532
533 /* Step 2a : make sure trigger sources are unique */
534
535 err |= comedi_check_trigger_is_unique(cmd->start_src);
536 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
537 err |= comedi_check_trigger_is_unique(cmd->stop_src);
538
539 /* Step 2b : and mutually compatible */
540
541 if (err)
542 return 2;
543
544 /* Step 3: check if arguments are trivially valid */
545
546 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
547
548 #define MAX_SPEED (TIMER_BASE) /* in nanoseconds */
549
550 if (cmd->scan_begin_src == TRIG_TIMER) {
551 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
552 MAX_SPEED);
553 /* no minimum speed */
554 } else {
555 /* TRIG_EXT */
556 /* should be level/edge, hi/lo specification here */
557 if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) {
558 cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT);
559 err |= -EINVAL;
560 }
561 }
562
563 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
564 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
565 cmd->chanlist_len);
566
567 if (cmd->stop_src == TRIG_COUNT)
568 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
569 else /* TRIG_NONE */
570 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
571
572 if (err)
573 return 3;
574
575 /* step 4: fix up any arguments */
576
577 if (cmd->scan_begin_src == TRIG_TIMER) {
578 arg = cmd->scan_begin_arg;
579 ni_pcidio_ns_to_timer(&arg, cmd->flags);
580 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
581 }
582
583 if (err)
584 return 4;
585
586 return 0;
587 }
588
ni_pcidio_inttrig(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trig_num)589 static int ni_pcidio_inttrig(struct comedi_device *dev,
590 struct comedi_subdevice *s,
591 unsigned int trig_num)
592 {
593 struct nidio96_private *devpriv = dev->private;
594 struct comedi_cmd *cmd = &s->async->cmd;
595
596 if (trig_num != cmd->start_arg)
597 return -EINVAL;
598
599 writeb(devpriv->OpModeBits, dev->mmio + OpMode);
600 s->async->inttrig = NULL;
601
602 return 1;
603 }
604
ni_pcidio_cmd(struct comedi_device * dev,struct comedi_subdevice * s)605 static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
606 {
607 struct nidio96_private *devpriv = dev->private;
608 struct comedi_cmd *cmd = &s->async->cmd;
609
610 /* XXX configure ports for input */
611 writel(0x0000, dev->mmio + Port_Pin_Directions(0));
612
613 if (1) {
614 /* enable fifos A B C D */
615 writeb(0x0f, dev->mmio + Data_Path);
616
617 /* set transfer width a 32 bits */
618 writeb(TransferWidth(0) | TransferLength(0),
619 dev->mmio + Transfer_Size_Control);
620 } else {
621 writeb(0x03, dev->mmio + Data_Path);
622 writeb(TransferWidth(3) | TransferLength(0),
623 dev->mmio + Transfer_Size_Control);
624 }
625
626 /* protocol configuration */
627 if (cmd->scan_begin_src == TRIG_TIMER) {
628 /* page 4-5, "input with internal REQs" */
629 writeb(0, dev->mmio + OpMode);
630 writeb(0x00, dev->mmio + ClockReg);
631 writeb(1, dev->mmio + Sequence);
632 writeb(0x04, dev->mmio + ReqReg);
633 writeb(4, dev->mmio + BlockMode);
634 writeb(3, dev->mmio + LinePolarities);
635 writeb(0xc0, dev->mmio + AckSer);
636 writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
637 CMDF_ROUND_NEAREST),
638 dev->mmio + StartDelay);
639 writeb(1, dev->mmio + ReqDelay);
640 writeb(1, dev->mmio + ReqNotDelay);
641 writeb(1, dev->mmio + AckDelay);
642 writeb(0x0b, dev->mmio + AckNotDelay);
643 writeb(0x01, dev->mmio + Data1Delay);
644 /*
645 * manual, page 4-5:
646 * ClockSpeed comment is incorrectly listed on DAQOptions
647 */
648 writew(0, dev->mmio + ClockSpeed);
649 writeb(0, dev->mmio + DAQOptions);
650 } else {
651 /* TRIG_EXT */
652 /* page 4-5, "input with external REQs" */
653 writeb(0, dev->mmio + OpMode);
654 writeb(0x00, dev->mmio + ClockReg);
655 writeb(0, dev->mmio + Sequence);
656 writeb(0x00, dev->mmio + ReqReg);
657 writeb(4, dev->mmio + BlockMode);
658 if (!(cmd->scan_begin_arg & CR_INVERT)) /* Leading Edge */
659 writeb(0, dev->mmio + LinePolarities);
660 else /* Trailing Edge */
661 writeb(2, dev->mmio + LinePolarities);
662 writeb(0x00, dev->mmio + AckSer);
663 writel(1, dev->mmio + StartDelay);
664 writeb(1, dev->mmio + ReqDelay);
665 writeb(1, dev->mmio + ReqNotDelay);
666 writeb(1, dev->mmio + AckDelay);
667 writeb(0x0C, dev->mmio + AckNotDelay);
668 writeb(0x10, dev->mmio + Data1Delay);
669 writew(0, dev->mmio + ClockSpeed);
670 writeb(0x60, dev->mmio + DAQOptions);
671 }
672
673 if (cmd->stop_src == TRIG_COUNT) {
674 writel(cmd->stop_arg,
675 dev->mmio + Transfer_Count);
676 } else {
677 /* XXX */
678 }
679
680 #ifdef USE_DMA
681 writeb(ClearPrimaryTC | ClearSecondaryTC,
682 dev->mmio + Group_1_First_Clear);
683
684 {
685 int retval = setup_mite_dma(dev, s);
686
687 if (retval)
688 return retval;
689 }
690 #else
691 writeb(0x00, dev->mmio + DMA_Line_Control_Group1);
692 #endif
693 writeb(0x00, dev->mmio + DMA_Line_Control_Group2);
694
695 /* clear and enable interrupts */
696 writeb(0xff, dev->mmio + Group_1_First_Clear);
697 /* writeb(ClearExpired, dev->mmio+Group_1_Second_Clear); */
698
699 writeb(IntEn, dev->mmio + Interrupt_Control);
700 writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control);
701
702 if (cmd->stop_src == TRIG_NONE) {
703 devpriv->OpModeBits = DataLatching(0) | RunMode(7);
704 } else { /* TRIG_TIMER */
705 devpriv->OpModeBits = Numbered | RunMode(7);
706 }
707 if (cmd->start_src == TRIG_NOW) {
708 /* start */
709 writeb(devpriv->OpModeBits, dev->mmio + OpMode);
710 s->async->inttrig = NULL;
711 } else {
712 /* TRIG_INT */
713 s->async->inttrig = ni_pcidio_inttrig;
714 }
715
716 return 0;
717 }
718
ni_pcidio_cancel(struct comedi_device * dev,struct comedi_subdevice * s)719 static int ni_pcidio_cancel(struct comedi_device *dev,
720 struct comedi_subdevice *s)
721 {
722 writeb(0x00, dev->mmio + Master_DMA_And_Interrupt_Control);
723 ni_pcidio_release_di_mite_channel(dev);
724
725 return 0;
726 }
727
ni_pcidio_change(struct comedi_device * dev,struct comedi_subdevice * s)728 static int ni_pcidio_change(struct comedi_device *dev,
729 struct comedi_subdevice *s)
730 {
731 struct nidio96_private *devpriv = dev->private;
732 int ret;
733
734 ret = mite_buf_change(devpriv->di_mite_ring, s);
735 if (ret < 0)
736 return ret;
737
738 memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
739
740 return 0;
741 }
742
pci_6534_load_fpga(struct comedi_device * dev,const u8 * data,size_t data_len,unsigned long context)743 static int pci_6534_load_fpga(struct comedi_device *dev,
744 const u8 *data, size_t data_len,
745 unsigned long context)
746 {
747 static const int timeout = 1000;
748 int fpga_index = context;
749 int i;
750 size_t j;
751
752 writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register);
753 writew(0xc0 | fpga_index, dev->mmio + Firmware_Control_Register);
754 for (i = 0;
755 (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0 &&
756 i < timeout; ++i) {
757 udelay(1);
758 }
759 if (i == timeout) {
760 dev_warn(dev->class_dev,
761 "ni_pcidio: failed to load fpga %i, waiting for status 0x2\n",
762 fpga_index);
763 return -EIO;
764 }
765 writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register);
766 for (i = 0;
767 readw(dev->mmio + Firmware_Status_Register) != 0x3 &&
768 i < timeout; ++i) {
769 udelay(1);
770 }
771 if (i == timeout) {
772 dev_warn(dev->class_dev,
773 "ni_pcidio: failed to load fpga %i, waiting for status 0x3\n",
774 fpga_index);
775 return -EIO;
776 }
777 for (j = 0; j + 1 < data_len;) {
778 unsigned int value = data[j++];
779
780 value |= data[j++] << 8;
781 writew(value, dev->mmio + Firmware_Data_Register);
782 for (i = 0;
783 (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0
784 && i < timeout; ++i) {
785 udelay(1);
786 }
787 if (i == timeout) {
788 dev_warn(dev->class_dev,
789 "ni_pcidio: failed to load word into fpga %i\n",
790 fpga_index);
791 return -EIO;
792 }
793 if (need_resched())
794 schedule();
795 }
796 writew(0x0, dev->mmio + Firmware_Control_Register);
797 return 0;
798 }
799
pci_6534_reset_fpga(struct comedi_device * dev,int fpga_index)800 static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index)
801 {
802 return pci_6534_load_fpga(dev, NULL, 0, fpga_index);
803 }
804
pci_6534_reset_fpgas(struct comedi_device * dev)805 static int pci_6534_reset_fpgas(struct comedi_device *dev)
806 {
807 int ret;
808 int i;
809
810 writew(0x0, dev->mmio + Firmware_Control_Register);
811 for (i = 0; i < 3; ++i) {
812 ret = pci_6534_reset_fpga(dev, i);
813 if (ret < 0)
814 break;
815 }
816 writew(0x0, dev->mmio + Firmware_Mask_Register);
817 return ret;
818 }
819
pci_6534_init_main_fpga(struct comedi_device * dev)820 static void pci_6534_init_main_fpga(struct comedi_device *dev)
821 {
822 writel(0, dev->mmio + FPGA_Control1_Register);
823 writel(0, dev->mmio + FPGA_Control2_Register);
824 writel(0, dev->mmio + FPGA_SCALS_Counter_Register);
825 writel(0, dev->mmio + FPGA_SCAMS_Counter_Register);
826 writel(0, dev->mmio + FPGA_SCBLS_Counter_Register);
827 writel(0, dev->mmio + FPGA_SCBMS_Counter_Register);
828 }
829
pci_6534_upload_firmware(struct comedi_device * dev)830 static int pci_6534_upload_firmware(struct comedi_device *dev)
831 {
832 struct nidio96_private *devpriv = dev->private;
833 static const char *const fw_file[3] = {
834 FW_PCI_6534_SCARAB_DI, /* loaded into scarab A for DI */
835 FW_PCI_6534_SCARAB_DO, /* loaded into scarab B for DO */
836 FW_PCI_6534_MAIN, /* loaded into main FPGA */
837 };
838 int ret;
839 int n;
840
841 ret = pci_6534_reset_fpgas(dev);
842 if (ret < 0)
843 return ret;
844 /* load main FPGA first, then the two scarabs */
845 for (n = 2; n >= 0; n--) {
846 ret = comedi_load_firmware(dev, &devpriv->mite->pcidev->dev,
847 fw_file[n],
848 pci_6534_load_fpga, n);
849 if (ret == 0 && n == 2)
850 pci_6534_init_main_fpga(dev);
851 if (ret < 0)
852 break;
853 }
854 return ret;
855 }
856
nidio_reset_board(struct comedi_device * dev)857 static void nidio_reset_board(struct comedi_device *dev)
858 {
859 writel(0, dev->mmio + Port_IO(0));
860 writel(0, dev->mmio + Port_Pin_Directions(0));
861 writel(0, dev->mmio + Port_Pin_Mask(0));
862
863 /* disable interrupts on board */
864 writeb(0, dev->mmio + Master_DMA_And_Interrupt_Control);
865 }
866
nidio_auto_attach(struct comedi_device * dev,unsigned long context)867 static int nidio_auto_attach(struct comedi_device *dev,
868 unsigned long context)
869 {
870 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
871 const struct nidio_board *board = NULL;
872 struct nidio96_private *devpriv;
873 struct comedi_subdevice *s;
874 int ret;
875 unsigned int irq;
876
877 if (context < ARRAY_SIZE(nidio_boards))
878 board = &nidio_boards[context];
879 if (!board)
880 return -ENODEV;
881 dev->board_ptr = board;
882 dev->board_name = board->name;
883
884 ret = comedi_pci_enable(dev);
885 if (ret)
886 return ret;
887
888 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
889 if (!devpriv)
890 return -ENOMEM;
891
892 spin_lock_init(&devpriv->mite_channel_lock);
893
894 devpriv->mite = mite_attach(dev, false); /* use win0 */
895 if (!devpriv->mite)
896 return -ENOMEM;
897
898 devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
899 if (!devpriv->di_mite_ring)
900 return -ENOMEM;
901
902 if (board->uses_firmware) {
903 ret = pci_6534_upload_firmware(dev);
904 if (ret < 0)
905 return ret;
906 }
907
908 nidio_reset_board(dev);
909
910 ret = comedi_alloc_subdevices(dev, 1);
911 if (ret)
912 return ret;
913
914 dev_info(dev->class_dev, "%s rev=%d\n", dev->board_name,
915 readb(dev->mmio + Chip_Version));
916
917 s = &dev->subdevices[0];
918
919 dev->read_subdev = s;
920 s->type = COMEDI_SUBD_DIO;
921 s->subdev_flags =
922 SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
923 SDF_CMD_READ;
924 s->n_chan = 32;
925 s->range_table = &range_digital;
926 s->maxdata = 1;
927 s->insn_config = &ni_pcidio_insn_config;
928 s->insn_bits = &ni_pcidio_insn_bits;
929 s->do_cmd = &ni_pcidio_cmd;
930 s->do_cmdtest = &ni_pcidio_cmdtest;
931 s->cancel = &ni_pcidio_cancel;
932 s->len_chanlist = 32; /* XXX */
933 s->buf_change = &ni_pcidio_change;
934 s->async_dma_dir = DMA_BIDIRECTIONAL;
935 s->poll = &ni_pcidio_poll;
936
937 irq = pcidev->irq;
938 if (irq) {
939 ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
940 dev->board_name, dev);
941 if (ret == 0)
942 dev->irq = irq;
943 }
944
945 return 0;
946 }
947
nidio_detach(struct comedi_device * dev)948 static void nidio_detach(struct comedi_device *dev)
949 {
950 struct nidio96_private *devpriv = dev->private;
951
952 if (dev->irq)
953 free_irq(dev->irq, dev);
954 if (devpriv) {
955 if (devpriv->di_mite_ring) {
956 mite_free_ring(devpriv->di_mite_ring);
957 devpriv->di_mite_ring = NULL;
958 }
959 mite_detach(devpriv->mite);
960 }
961 if (dev->mmio)
962 iounmap(dev->mmio);
963 comedi_pci_disable(dev);
964 }
965
966 static struct comedi_driver ni_pcidio_driver = {
967 .driver_name = "ni_pcidio",
968 .module = THIS_MODULE,
969 .auto_attach = nidio_auto_attach,
970 .detach = nidio_detach,
971 };
972
ni_pcidio_pci_probe(struct pci_dev * dev,const struct pci_device_id * id)973 static int ni_pcidio_pci_probe(struct pci_dev *dev,
974 const struct pci_device_id *id)
975 {
976 return comedi_pci_auto_config(dev, &ni_pcidio_driver, id->driver_data);
977 }
978
979 static const struct pci_device_id ni_pcidio_pci_table[] = {
980 { PCI_VDEVICE(NI, 0x1150), BOARD_PCIDIO_32HS },
981 { PCI_VDEVICE(NI, 0x12b0), BOARD_PCI6534 },
982 { PCI_VDEVICE(NI, 0x1320), BOARD_PXI6533 },
983 { 0 }
984 };
985 MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
986
987 static struct pci_driver ni_pcidio_pci_driver = {
988 .name = "ni_pcidio",
989 .id_table = ni_pcidio_pci_table,
990 .probe = ni_pcidio_pci_probe,
991 .remove = comedi_pci_auto_unconfig,
992 };
993 module_comedi_pci_driver(ni_pcidio_driver, ni_pcidio_pci_driver);
994
995 MODULE_AUTHOR("Comedi http://www.comedi.org");
996 MODULE_DESCRIPTION("Comedi low-level driver");
997 MODULE_LICENSE("GPL");
998