1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104#include <linux/interrupt.h>
105#include <linux/delay.h>
106
107#include "../comedidev.h"
108#include "comedi_pci.h"
109
110#define DRV_NAME "rtd520"
111
112
113
114
115
116
117
118
119
120#define DMA_CHAIN_COUNT 2
121
122
123
124
125#define TRANS_TARGET_PERIOD 10000000
126
127
128
129#define RTD_MAX_CHANLIST 128
130
131
132#ifdef FAST_SPIN
133#define WAIT_QUIETLY
134#define RTD_ADC_TIMEOUT 66000
135#define RTD_DAC_TIMEOUT 66000
136#define RTD_DMA_TIMEOUT 33000
137#else
138
139#define WAIT_QUIETLY udelay (1)
140#define RTD_ADC_TIMEOUT 2000
141#define RTD_DAC_TIMEOUT 2000
142#define RTD_DMA_TIMEOUT 1000
143#endif
144
145
146
147
148
149
150#define PCI_VENDOR_ID_RTD 0x1435
151
152
153
154
155#define LCFG_PCIINDEX 0
156
157#define LAS0_PCIINDEX 2
158#define LAS1_PCIINDEX 3
159#define LCFG_PCISIZE 0x100
160#define LAS0_PCISIZE 0x200
161#define LAS1_PCISIZE 0x10
162
163#define RTD_CLOCK_RATE 8000000
164#define RTD_CLOCK_BASE 125
165
166
167#define RTD_MAX_SPEED 1625
168
169#define RTD_MAX_SPEED_1 875
170
171#define RTD_MIN_SPEED 2097151875
172
173#define RTD_MIN_SPEED_1 5000000
174
175#include "rtd520.h"
176#include "plx9080.h"
177
178
179#define DMA_MODE_BITS (\
180 PLX_LOCAL_BUS_16_WIDE_BITS \
181 | PLX_DMA_EN_READYIN_BIT \
182 | PLX_DMA_LOCAL_BURST_EN_BIT \
183 | PLX_EN_CHAIN_BIT \
184 | PLX_DMA_INTR_PCI_BIT \
185 | PLX_LOCAL_ADDR_CONST_BIT \
186 | PLX_DEMAND_MODE_BIT)
187
188#define DMA_TRANSFER_BITS (\
189 PLX_DESC_IN_PCI_BIT \
190 | PLX_INTR_TERM_COUNT \
191 | PLX_XFER_LOCAL_TO_PCI)
192
193
194
195
196
197
198
199
200static const struct comedi_lrange rtd_ai_7520_range = { 18, {
201
202 BIP_RANGE(5.0),
203 BIP_RANGE(5.0 / 2),
204 BIP_RANGE(5.0 / 4),
205 BIP_RANGE(5.0 / 8),
206 BIP_RANGE(5.0 /
207 16),
208 BIP_RANGE(5.0 /
209 32),
210
211 BIP_RANGE(10.0),
212 BIP_RANGE(10.0 /
213 2),
214 BIP_RANGE(10.0 /
215 4),
216 BIP_RANGE(10.0 /
217 8),
218 BIP_RANGE(10.0 /
219 16),
220 BIP_RANGE(10.0 /
221 32),
222
223 UNI_RANGE(10.0),
224 UNI_RANGE(10.0 /
225 2),
226 UNI_RANGE(10.0 /
227 4),
228 UNI_RANGE(10.0 /
229 8),
230 UNI_RANGE(10.0 /
231 16),
232 UNI_RANGE(10.0 /
233 32),
234
235 }
236};
237
238
239static const struct comedi_lrange rtd_ai_4520_range = { 24, {
240
241 BIP_RANGE(5.0),
242 BIP_RANGE(5.0 / 2),
243 BIP_RANGE(5.0 / 4),
244 BIP_RANGE(5.0 / 8),
245 BIP_RANGE(5.0 /
246 16),
247 BIP_RANGE(5.0 /
248 32),
249 BIP_RANGE(5.0 /
250 64),
251 BIP_RANGE(5.0 /
252 128),
253
254 BIP_RANGE(10.0),
255 BIP_RANGE(10.0 /
256 2),
257 BIP_RANGE(10.0 /
258 4),
259 BIP_RANGE(10.0 /
260 8),
261 BIP_RANGE(10.0 /
262 16),
263 BIP_RANGE(10.0 /
264 32),
265 BIP_RANGE(10.0 /
266 64),
267 BIP_RANGE(10.0 /
268 128),
269
270 UNI_RANGE(10.0),
271 UNI_RANGE(10.0 /
272 2),
273 UNI_RANGE(10.0 /
274 4),
275 UNI_RANGE(10.0 /
276 8),
277 UNI_RANGE(10.0 /
278 16),
279 UNI_RANGE(10.0 /
280 32),
281 UNI_RANGE(10.0 /
282 64),
283 UNI_RANGE(10.0 /
284 128),
285 }
286};
287
288
289static const struct comedi_lrange rtd_ao_range = { 4, {
290 RANGE(0, 5),
291 RANGE(0, 10),
292 RANGE(-5, 5),
293 RANGE(-10, 10),
294 }
295};
296
297
298
299
300struct rtdBoard {
301 const char *name;
302 int device_id;
303 int aiChans;
304 int aiBits;
305 int aiMaxGain;
306 int range10Start;
307 int rangeUniStart;
308};
309
310static const struct rtdBoard rtd520Boards[] = {
311 {
312 .name = "DM7520",
313 .device_id = 0x7520,
314 .aiChans = 16,
315 .aiBits = 12,
316 .aiMaxGain = 32,
317 .range10Start = 6,
318 .rangeUniStart = 12,
319 },
320 {
321 .name = "PCI4520",
322 .device_id = 0x4520,
323 .aiChans = 16,
324 .aiBits = 12,
325 .aiMaxGain = 128,
326 .range10Start = 8,
327 .rangeUniStart = 16,
328 },
329};
330
331static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = {
332 {
333 PCI_VENDOR_ID_RTD, 0x7520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
334 PCI_VENDOR_ID_RTD, 0x4520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
335 0}
336};
337
338MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
339
340
341
342
343#define thisboard ((const struct rtdBoard *)dev->board_ptr)
344
345
346
347
348
349struct rtdPrivate {
350
351 void *las0;
352 void *las1;
353 void *lcfg;
354
355 unsigned long intCount;
356 long aiCount;
357 int transCount;
358 int flags;
359
360
361 struct pci_dev *pci_dev;
362 int got_regions;
363
364
365
366 unsigned char chanBipolar[RTD_MAX_CHANLIST / 8];
367
368
369 unsigned int aoValue[2];
370
371
372 u8 utcGate[4];
373
374
375
376 u16 intMask;
377 u16 intClearMask;
378 u8 utcCtrl[4];
379 u8 dioStatus;
380#ifdef USE_DMA
381
382
383 s16 dma0Offset;
384 uint16_t *dma0Buff[DMA_CHAIN_COUNT];
385 dma_addr_t dma0BuffPhysAddr[DMA_CHAIN_COUNT];
386 struct plx_dma_desc *dma0Chain;
387 dma_addr_t dma0ChainPhysAddr;
388
389 u8 dma0Control;
390 u8 dma1Control;
391#endif
392 unsigned fifoLen;
393};
394
395
396#define SEND_EOS 0x01
397#define DMA0_ACTIVE 0x02
398#define DMA1_ACTIVE 0x04
399
400
401#define CHAN_ARRAY_TEST(array, index) \
402 (((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
403#define CHAN_ARRAY_SET(array, index) \
404 (((array)[(index)/8] |= 1 << ((index) & 0x7)))
405#define CHAN_ARRAY_CLEAR(array, index) \
406 (((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
407
408
409
410
411
412#define devpriv ((struct rtdPrivate *)dev->private)
413
414
415
416
417#define RtdResetBoard(dev) \
418 writel (0, devpriv->las0+LAS0_BOARD_RESET)
419
420
421#define RtdResetCGT(dev) \
422 writel (0, devpriv->las0+LAS0_CGT_RESET)
423
424
425#define RtdClearCGT(dev) \
426 writel (0, devpriv->las0+LAS0_CGT_CLEAR)
427
428
429#define RtdEnableCGT(dev, v) \
430 writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_CGT_ENABLE)
431
432
433#define RtdWriteCGTable(dev, v) \
434 writel (v, devpriv->las0+LAS0_CGT_WRITE)
435
436
437#define RtdWriteCGLatch(dev, v) \
438 writel (v, devpriv->las0+LAS0_CGL_WRITE)
439
440
441#define RtdAdcClearFifo(dev) \
442 writel (0, devpriv->las0+LAS0_ADC_FIFO_CLEAR)
443
444
445#define RtdAdcConversionSource(dev, v) \
446 writel (v, devpriv->las0+LAS0_ADC_CONVERSION)
447
448
449#define RtdBurstStartSource(dev, v) \
450 writel (v, devpriv->las0+LAS0_BURST_START)
451
452
453#define RtdPacerStartSource(dev, v) \
454 writel (v, devpriv->las0+LAS0_PACER_START)
455
456
457#define RtdPacerStopSource(dev, v) \
458 writel (v, devpriv->las0+LAS0_PACER_STOP)
459
460
461#define RtdPacerClockSource(dev, v) \
462 writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_SELECT)
463
464
465#define RtdAdcSampleCounterSource(dev, v) \
466 writel (v, devpriv->las0+LAS0_ADC_SCNT_SRC)
467
468
469#define RtdPacerTriggerMode(dev, v) \
470 writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_REPEAT)
471
472
473#define RtdAboutStopEnable(dev, v) \
474 writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ACNT_STOP_ENABLE)
475
476
477#define RtdTriggerPolarity(dev, v) \
478 writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ETRG_POLARITY)
479
480
481#define RtdAdcStart(dev) \
482 writew (0, devpriv->las0+LAS0_ADC)
483
484
485
486#define RtdAdcFifoGet(dev) \
487 readw (devpriv->las1+LAS1_ADC_FIFO)
488
489
490#define RtdAdcFifoGet2(dev) \
491 readl (devpriv->las1+LAS1_ADC_FIFO)
492
493
494#define RtdFifoStatus(dev) \
495 readl (devpriv->las0+LAS0_ADC)
496
497
498#define RtdPacerStart(dev) \
499 readl (devpriv->las0+LAS0_PACER)
500#define RtdPacerStop(dev) \
501 writel (0, devpriv->las0+LAS0_PACER)
502
503
504#define RtdInterruptStatus(dev) \
505 readw (devpriv->las0+LAS0_IT)
506
507
508#define RtdInterruptMask(dev, v) \
509 writew ((devpriv->intMask = (v)), devpriv->las0+LAS0_IT)
510
511
512#define RtdInterruptClear(dev) \
513 readw (devpriv->las0+LAS0_CLEAR)
514
515
516#define RtdInterruptClearMask(dev, v) \
517 writew ((devpriv->intClearMask = (v)), devpriv->las0+LAS0_CLEAR)
518
519
520#define RtdInterruptOverrunStatus(dev) \
521 readl (devpriv->las0+LAS0_OVERRUN)
522
523
524#define RtdInterruptOverrunClear(dev) \
525 writel (0, devpriv->las0+LAS0_OVERRUN)
526
527
528#define RtdPacerCount(dev) \
529 readl (devpriv->las0+LAS0_PCLK)
530#define RtdPacerCounter(dev, v) \
531 writel ((v) & 0xffffff, devpriv->las0+LAS0_PCLK)
532
533
534#define RtdBurstCount(dev) \
535 readl (devpriv->las0+LAS0_BCLK)
536#define RtdBurstCounter(dev, v) \
537 writel ((v) & 0x3ff, devpriv->las0+LAS0_BCLK)
538
539
540#define RtdDelayCount(dev) \
541 readl (devpriv->las0+LAS0_DCLK)
542#define RtdDelayCounter(dev, v) \
543 writel ((v) & 0xffff, devpriv->las0+LAS0_DCLK)
544
545
546#define RtdAboutCount(dev) \
547 readl (devpriv->las0+LAS0_ACNT)
548#define RtdAboutCounter(dev, v) \
549 writel ((v) & 0xffff, devpriv->las0+LAS0_ACNT)
550
551
552#define RtdAdcSampleCount(dev) \
553 readl (devpriv->las0+LAS0_ADC_SCNT)
554#define RtdAdcSampleCounter(dev, v) \
555 writel ((v) & 0x3ff, devpriv->las0+LAS0_ADC_SCNT)
556
557
558#define RtdUtcCounterGet(dev, n) \
559 readb (devpriv->las0 \
560 + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
561
562#define RtdUtcCounterPut(dev, n, v) \
563 writeb ((v) & 0xff, devpriv->las0 \
564 + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
565
566
567#define RtdUtcCtrlPut(dev, n, v) \
568 writeb (devpriv->utcCtrl[(n) & 3] = (((n) & 3) << 6) | ((v) & 0x3f), \
569 devpriv->las0 + LAS0_UTC_CTRL)
570
571
572#define RtdUtcClockSource(dev, n, v) \
573 writew (v, devpriv->las0 \
574 + ((n <= 0) ? LAS0_UTC0_CLOCK : \
575 ((1 == n) ? LAS0_UTC1_CLOCK : LAS0_UTC2_CLOCK)))
576
577
578#define RtdUtcGateSource(dev, n, v) \
579 writew (v, devpriv->las0 \
580 + ((n <= 0) ? LAS0_UTC0_GATE : \
581 ((1 == n) ? LAS0_UTC1_GATE : LAS0_UTC2_GATE)))
582
583
584#define RtdUsrOutSource(dev, n, v) \
585 writel (v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT))
586
587
588#define RtdDio0Read(dev) \
589 (readw (devpriv->las0+LAS0_DIO0) & 0xff)
590#define RtdDio0Write(dev, v) \
591 writew ((v) & 0xff, devpriv->las0+LAS0_DIO0)
592
593#define RtdDio1Read(dev) \
594 (readw (devpriv->las0+LAS0_DIO1) & 0xff)
595#define RtdDio1Write(dev, v) \
596 writew ((v) & 0xff, devpriv->las0+LAS0_DIO1)
597
598#define RtdDioStatusRead(dev) \
599 (readw (devpriv->las0+LAS0_DIO_STATUS) & 0xff)
600#define RtdDioStatusWrite(dev, v) \
601 writew ((devpriv->dioStatus = (v)), devpriv->las0+LAS0_DIO_STATUS)
602
603#define RtdDio0CtrlRead(dev) \
604 (readw (devpriv->las0+LAS0_DIO0_CTRL) & 0xff)
605#define RtdDio0CtrlWrite(dev, v) \
606 writew ((v) & 0xff, devpriv->las0+LAS0_DIO0_CTRL)
607
608
609
610
611#define RtdDacFifoPut(dev, n, v) \
612 writew ((v), devpriv->las1 +(((n) == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO))
613
614
615#define RtdDacUpdate(dev, n) \
616 writew (0, devpriv->las0 +(((n) == 0) ? LAS0_DAC1 : LAS0_DAC2))
617
618
619#define RtdDacBothUpdate(dev) \
620 writew (0, devpriv->las0+LAS0_DAC)
621
622
623#define RtdDacRange(dev, n, v) \
624 writew ((v) & 7, devpriv->las0 \
625 +(((n) == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL))
626
627
628#define RtdDacClearFifo(dev, n) \
629 writel (0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : LAS0_DAC2_RESET))
630
631
632#define RtdDma0Source(dev, n) \
633 writel ((n) & 0xf, devpriv->las0+LAS0_DMA0_SRC)
634
635
636#define RtdDma1Source(dev, n) \
637 writel ((n) & 0xf, devpriv->las0+LAS0_DMA1_SRC)
638
639
640#define RtdDma0Reset(dev) \
641 writel (0, devpriv->las0+LAS0_DMA0_RESET)
642
643
644#define RtdDma1Reset(dev) \
645 writel (0, devpriv->las0+LAS0_DMA1_SRC)
646
647
648#define RtdPlxInterruptRead(dev) \
649 readl (devpriv->lcfg+LCFG_ITCSR)
650#define RtdPlxInterruptWrite(dev, v) \
651 writel (v, devpriv->lcfg+LCFG_ITCSR)
652
653
654#define RtdDma0Mode(dev, m) \
655 writel ((m), devpriv->lcfg+LCFG_DMAMODE0)
656
657
658#define RtdDma0PciAddr(dev, a) \
659 writel ((a), devpriv->lcfg+LCFG_DMAPADR0)
660
661
662#define RtdDma0LocalAddr(dev, a) \
663 writel ((a), devpriv->lcfg+LCFG_DMALADR0)
664
665
666#define RtdDma0Count(dev, c) \
667 writel ((c), devpriv->lcfg+LCFG_DMASIZ0)
668
669
670#define RtdDma0Next(dev, a) \
671 writel ((a), devpriv->lcfg+LCFG_DMADPR0)
672
673
674#define RtdDma1Mode(dev, m) \
675 writel ((m), devpriv->lcfg+LCFG_DMAMODE1)
676
677
678#define RtdDma1PciAddr(dev, a) \
679 writel ((a), devpriv->lcfg+LCFG_DMAADR1)
680
681
682#define RtdDma1LocalAddr(dev, a) \
683 writel ((a), devpriv->lcfg+LCFG_DMALADR1)
684
685
686#define RtdDma1Count(dev, c) \
687 writel ((c), devpriv->lcfg+LCFG_DMASIZ1)
688
689
690#define RtdDma1Next(dev, a) \
691 writel ((a), devpriv->lcfg+LCFG_DMADPR1)
692
693
694#define RtdDma0Control(dev, n) \
695 writeb (devpriv->dma0Control = (n), devpriv->lcfg+LCFG_DMACSR0)
696
697
698#define RtdDma0Status(dev) \
699 readb (devpriv->lcfg+LCFG_DMACSR0)
700
701
702#define RtdDma1Control(dev, n) \
703 writeb (devpriv->dma1Control = (n), devpriv->lcfg+LCFG_DMACSR1)
704
705
706#define RtdDma1Status(dev) \
707 readb (devpriv->lcfg+LCFG_DMACSR1)
708
709
710
711
712
713
714
715static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it);
716static int rtd_detach(struct comedi_device *dev);
717
718static struct comedi_driver rtd520Driver = {
719 .driver_name = DRV_NAME,
720 .module = THIS_MODULE,
721 .attach = rtd_attach,
722 .detach = rtd_detach,
723};
724
725static int rtd_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
726 struct comedi_insn *insn, unsigned int *data);
727static int rtd_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
728 struct comedi_insn *insn, unsigned int *data);
729static int rtd_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
730 struct comedi_insn *insn, unsigned int *data);
731static int rtd_dio_insn_bits(struct comedi_device *dev,
732 struct comedi_subdevice *s,
733 struct comedi_insn *insn, unsigned int *data);
734static int rtd_dio_insn_config(struct comedi_device *dev,
735 struct comedi_subdevice *s,
736 struct comedi_insn *insn, unsigned int *data);
737static int rtd_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
738 struct comedi_cmd *cmd);
739static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
740static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
741
742static int rtd_ns_to_timer(unsigned int *ns, int roundMode);
743static irqreturn_t rtd_interrupt(int irq, void *d);
744static int rtd520_probe_fifo_depth(struct comedi_device *dev);
745
746
747
748
749
750
751
752static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
753{
754 struct comedi_subdevice *s;
755 struct pci_dev *pcidev;
756 int ret;
757 resource_size_t physLas0;
758 resource_size_t physLas1;
759 resource_size_t physLcfg;
760#ifdef USE_DMA
761 int index;
762#endif
763
764 printk("comedi%d: rtd520 attaching.\n", dev->minor);
765
766#if defined (CONFIG_COMEDI_DEBUG) && defined (USE_DMA)
767
768 if (0 == comedi_debug)
769 comedi_debug = 1;
770#endif
771
772
773
774
775
776 if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0)
777 return -ENOMEM;
778
779
780
781
782 for (pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, NULL);
783 pcidev != NULL;
784 pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, pcidev)) {
785 int i;
786
787 if (it->options[0] || it->options[1]) {
788 if (pcidev->bus->number != it->options[0]
789 || PCI_SLOT(pcidev->devfn) != it->options[1]) {
790 continue;
791 }
792 }
793 for (i = 0; i < ARRAY_SIZE(rtd520Boards); ++i) {
794 if (pcidev->device == rtd520Boards[i].device_id) {
795 dev->board_ptr = &rtd520Boards[i];
796 break;
797 }
798 }
799 if (dev->board_ptr)
800 break;
801 }
802 if (!pcidev) {
803 if (it->options[0] && it->options[1]) {
804 printk("No RTD card at bus=%d slot=%d.\n",
805 it->options[0], it->options[1]);
806 } else {
807 printk("No RTD card found.\n");
808 }
809 return -EIO;
810 }
811 devpriv->pci_dev = pcidev;
812 dev->board_name = thisboard->name;
813
814 ret = comedi_pci_enable(pcidev, DRV_NAME);
815 if (ret < 0) {
816 printk("Failed to enable PCI device and request regions.\n");
817 return ret;
818 }
819 devpriv->got_regions = 1;
820
821
822
823
824
825 physLas0 = pci_resource_start(devpriv->pci_dev, LAS0_PCIINDEX);
826 physLas1 = pci_resource_start(devpriv->pci_dev, LAS1_PCIINDEX);
827 physLcfg = pci_resource_start(devpriv->pci_dev, LCFG_PCIINDEX);
828
829
830 devpriv->las0 = ioremap_nocache(physLas0, LAS0_PCISIZE);
831 devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE);
832 devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE);
833
834 if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) {
835 return -ENOMEM;
836 }
837
838 DPRINTK("%s: LAS0=%llx, LAS1=%llx, CFG=%llx.\n", dev->board_name,
839 (unsigned long long)physLas0, (unsigned long long)physLas1,
840 (unsigned long long)physLcfg);
841 {
842 unsigned char pci_latency;
843 u16 revision;
844
845
846 pci_read_config_word(devpriv->pci_dev, PCI_REVISION_ID,
847 &revision);
848 DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision);
849
850 pci_read_config_byte(devpriv->pci_dev,
851 PCI_LATENCY_TIMER, &pci_latency);
852 if (pci_latency < 32) {
853 printk("%s: PCI latency changed from %d to %d\n",
854 dev->board_name, pci_latency, 32);
855 pci_write_config_byte(devpriv->pci_dev,
856 PCI_LATENCY_TIMER, 32);
857 } else {
858 DPRINTK("rtd520: PCI latency = %d\n", pci_latency);
859 }
860
861
862
863
864
865
866
867
868
869
870 }
871
872
873 printk("%s:", dev->board_name);
874
875
876
877
878
879 if (alloc_subdevices(dev, 4) < 0) {
880 return -ENOMEM;
881 }
882
883 s = dev->subdevices + 0;
884 dev->read_subdev = s;
885
886 s->type = COMEDI_SUBD_AI;
887 s->subdev_flags =
888 SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ;
889 s->n_chan = thisboard->aiChans;
890 s->maxdata = (1 << thisboard->aiBits) - 1;
891 if (thisboard->aiMaxGain <= 32) {
892 s->range_table = &rtd_ai_7520_range;
893 } else {
894 s->range_table = &rtd_ai_4520_range;
895 }
896 s->len_chanlist = RTD_MAX_CHANLIST;
897 s->insn_read = rtd_ai_rinsn;
898 s->do_cmd = rtd_ai_cmd;
899 s->do_cmdtest = rtd_ai_cmdtest;
900 s->cancel = rtd_ai_cancel;
901
902
903 s = dev->subdevices + 1;
904
905 s->type = COMEDI_SUBD_AO;
906 s->subdev_flags = SDF_WRITABLE;
907 s->n_chan = 2;
908 s->maxdata = (1 << thisboard->aiBits) - 1;
909 s->range_table = &rtd_ao_range;
910 s->insn_write = rtd_ao_winsn;
911 s->insn_read = rtd_ao_rinsn;
912
913 s = dev->subdevices + 2;
914
915 s->type = COMEDI_SUBD_DIO;
916 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
917
918 s->n_chan = 8;
919 s->maxdata = 1;
920 s->range_table = &range_digital;
921 s->insn_bits = rtd_dio_insn_bits;
922 s->insn_config = rtd_dio_insn_config;
923
924
925 s = dev->subdevices + 3;
926 s->type = COMEDI_SUBD_COUNTER;
927 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
928 s->n_chan = 3;
929 s->maxdata = 0xffff;
930
931
932
933 RtdResetBoard(dev);
934 udelay(100);
935 RtdPlxInterruptWrite(dev, 0);
936 RtdInterruptMask(dev, 0);
937 RtdInterruptClearMask(dev, ~0);
938 RtdInterruptClear(dev);
939 RtdInterruptOverrunClear(dev);
940 RtdClearCGT(dev);
941 RtdAdcClearFifo(dev);
942 RtdDacClearFifo(dev, 0);
943 RtdDacClearFifo(dev, 1);
944
945 RtdDioStatusWrite(dev, 0);
946 RtdUtcCtrlPut(dev, 0, 0x30);
947 RtdUtcCtrlPut(dev, 1, 0x30);
948 RtdUtcCtrlPut(dev, 2, 0x30);
949 RtdUtcCtrlPut(dev, 3, 0);
950
951
952
953 ret = request_irq(devpriv->pci_dev->irq, rtd_interrupt,
954 IRQF_SHARED, DRV_NAME, dev);
955
956 if (ret < 0) {
957 printk("Could not get interrupt! (%u)\n",
958 devpriv->pci_dev->irq);
959 return ret;
960 }
961 dev->irq = devpriv->pci_dev->irq;
962 printk("( irq=%u )", dev->irq);
963
964 ret = rtd520_probe_fifo_depth(dev);
965 if (ret < 0) {
966 return ret;
967 }
968 devpriv->fifoLen = ret;
969 printk("( fifoLen=%d )", devpriv->fifoLen);
970
971#ifdef USE_DMA
972 if (dev->irq > 0) {
973 printk("( DMA buff=%d )\n", DMA_CHAIN_COUNT);
974
975
976
977 devpriv->dma0Offset = 0;
978
979 for (index = 0; index < DMA_CHAIN_COUNT; index++) {
980 devpriv->dma0Buff[index] =
981 pci_alloc_consistent(devpriv->pci_dev,
982 sizeof(u16) *
983 devpriv->fifoLen / 2,
984 &devpriv->
985 dma0BuffPhysAddr[index]);
986 if (devpriv->dma0Buff[index] == NULL) {
987 ret = -ENOMEM;
988 goto rtd_attach_die_error;
989 }
990
991
992
993 }
994
995
996 devpriv->dma0Chain =
997 pci_alloc_consistent(devpriv->pci_dev,
998 sizeof(struct plx_dma_desc) *
999 DMA_CHAIN_COUNT,
1000 &devpriv->dma0ChainPhysAddr);
1001 for (index = 0; index < DMA_CHAIN_COUNT; index++) {
1002 devpriv->dma0Chain[index].pci_start_addr =
1003 devpriv->dma0BuffPhysAddr[index];
1004 devpriv->dma0Chain[index].local_start_addr =
1005 DMALADDR_ADC;
1006 devpriv->dma0Chain[index].transfer_size =
1007 sizeof(u16) * devpriv->fifoLen / 2;
1008 devpriv->dma0Chain[index].next =
1009 (devpriv->dma0ChainPhysAddr + ((index +
1010 1) %
1011 (DMA_CHAIN_COUNT))
1012 * sizeof(devpriv->dma0Chain[0]))
1013 | DMA_TRANSFER_BITS;
1014
1015
1016
1017
1018
1019
1020
1021
1022 }
1023
1024 if (devpriv->dma0Chain == NULL) {
1025 ret = -ENOMEM;
1026 goto rtd_attach_die_error;
1027 }
1028
1029 RtdDma0Mode(dev, DMA_MODE_BITS);
1030 RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL);
1031 } else {
1032 printk("( no IRQ->no DMA )");
1033 }
1034#endif
1035
1036 if (dev->irq) {
1037 RtdPlxInterruptWrite(dev, ICS_PIE | ICS_PLIE);
1038 }
1039
1040 printk("\ncomedi%d: rtd520 driver attached.\n", dev->minor);
1041
1042 return 1;
1043
1044#if 0
1045
1046
1047#ifdef USE_DMA
1048 for (index = 0; index < DMA_CHAIN_COUNT; index++) {
1049 if (NULL != devpriv->dma0Buff[index]) {
1050 pci_free_consistent(devpriv->pci_dev,
1051 sizeof(u16) * devpriv->fifoLen / 2,
1052 devpriv->dma0Buff[index],
1053 devpriv->dma0BuffPhysAddr[index]);
1054 devpriv->dma0Buff[index] = NULL;
1055 }
1056 }
1057 if (NULL != devpriv->dma0Chain) {
1058 pci_free_consistent(devpriv->pci_dev,
1059 sizeof(struct plx_dma_desc)
1060 * DMA_CHAIN_COUNT,
1061 devpriv->dma0Chain,
1062 devpriv->dma0ChainPhysAddr);
1063 devpriv->dma0Chain = NULL;
1064 }
1065#endif
1066
1067 if (dev->irq) {
1068
1069 RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev)
1070 & ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E));
1071 free_irq(dev->irq, dev);
1072 }
1073
1074
1075 if (devpriv->las0) {
1076 iounmap(devpriv->las0);
1077 }
1078 if (devpriv->las1) {
1079 iounmap(devpriv->las1);
1080 }
1081 if (devpriv->lcfg) {
1082 iounmap(devpriv->lcfg);
1083 }
1084 if (devpriv->pci_dev) {
1085 pci_dev_put(devpriv->pci_dev);
1086 }
1087 return ret;
1088#endif
1089}
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099static int rtd_detach(struct comedi_device *dev)
1100{
1101#ifdef USE_DMA
1102 int index;
1103#endif
1104
1105 DPRINTK("comedi%d: rtd520: removing (%ld ints)\n",
1106 dev->minor, (devpriv ? devpriv->intCount : 0L));
1107 if (devpriv && devpriv->lcfg) {
1108 DPRINTK
1109 ("(int status 0x%x, overrun status 0x%x, fifo status 0x%x)...\n",
1110 0xffff & RtdInterruptStatus(dev),
1111 0xffff & RtdInterruptOverrunStatus(dev),
1112 (0xffff & RtdFifoStatus(dev)) ^ 0x6666);
1113 }
1114
1115 if (devpriv) {
1116
1117#ifdef USE_DMA
1118 if (devpriv->lcfg) {
1119 RtdDma0Control(dev, 0);
1120 RtdDma1Control(dev, 0);
1121 RtdPlxInterruptWrite(dev, ICS_PIE | ICS_PLIE);
1122 }
1123#endif
1124 if (devpriv->las0) {
1125 RtdResetBoard(dev);
1126 RtdInterruptMask(dev, 0);
1127 RtdInterruptClearMask(dev, ~0);
1128 RtdInterruptClear(dev);
1129 }
1130#ifdef USE_DMA
1131
1132 for (index = 0; index < DMA_CHAIN_COUNT; index++) {
1133 if (NULL != devpriv->dma0Buff[index]) {
1134 pci_free_consistent(devpriv->pci_dev,
1135 sizeof(u16) *
1136 devpriv->fifoLen / 2,
1137 devpriv->dma0Buff[index],
1138 devpriv->
1139 dma0BuffPhysAddr[index]);
1140 devpriv->dma0Buff[index] = NULL;
1141 }
1142 }
1143 if (NULL != devpriv->dma0Chain) {
1144 pci_free_consistent(devpriv->pci_dev,
1145 sizeof(struct plx_dma_desc) *
1146 DMA_CHAIN_COUNT, devpriv->dma0Chain,
1147 devpriv->dma0ChainPhysAddr);
1148 devpriv->dma0Chain = NULL;
1149 }
1150#endif
1151
1152
1153 if (dev->irq) {
1154
1155 RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev)
1156 & ~(ICS_PLIE | ICS_DMA0_E |
1157 ICS_DMA1_E));
1158 free_irq(dev->irq, dev);
1159 }
1160
1161
1162 if (devpriv->las0) {
1163 iounmap(devpriv->las0);
1164 }
1165 if (devpriv->las1) {
1166 iounmap(devpriv->las1);
1167 }
1168 if (devpriv->lcfg) {
1169 iounmap(devpriv->lcfg);
1170 }
1171 if (devpriv->pci_dev) {
1172 if (devpriv->got_regions) {
1173 comedi_pci_disable(devpriv->pci_dev);
1174 }
1175 pci_dev_put(devpriv->pci_dev);
1176 }
1177 }
1178
1179 printk("comedi%d: rtd520: removed.\n", dev->minor);
1180
1181 return 0;
1182}
1183
1184
1185
1186
1187static unsigned short rtdConvertChanGain(struct comedi_device *dev,
1188 unsigned int comediChan, int chanIndex)
1189{
1190 unsigned int chan, range, aref;
1191 unsigned short r = 0;
1192
1193 chan = CR_CHAN(comediChan);
1194 range = CR_RANGE(comediChan);
1195 aref = CR_AREF(comediChan);
1196
1197 r |= chan & 0xf;
1198
1199
1200 if (range < thisboard->range10Start) {
1201 r |= 0x000;
1202 r |= (range & 0x7) << 4;
1203 CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
1204 } else if (range < thisboard->rangeUniStart) {
1205 r |= 0x100;
1206 r |= ((range - thisboard->range10Start) & 0x7) << 4;
1207 CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
1208 } else {
1209 r |= 0x200;
1210 r |= ((range - thisboard->rangeUniStart) & 0x7) << 4;
1211 CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex);
1212 }
1213
1214 switch (aref) {
1215 case AREF_GROUND:
1216 break;
1217
1218 case AREF_COMMON:
1219 r |= 0x80;
1220 break;
1221
1222 case AREF_DIFF:
1223 r |= 0x400;
1224 break;
1225
1226 case AREF_OTHER:
1227 break;
1228 }
1229
1230
1231 return r;
1232}
1233
1234
1235
1236
1237static void rtd_load_channelgain_list(struct comedi_device *dev,
1238 unsigned int n_chan, unsigned int *list)
1239{
1240 if (n_chan > 1) {
1241 int ii;
1242 RtdClearCGT(dev);
1243 RtdEnableCGT(dev, 1);
1244 for (ii = 0; ii < n_chan; ii++) {
1245 RtdWriteCGTable(dev, rtdConvertChanGain(dev, list[ii],
1246 ii));
1247 }
1248 } else {
1249 RtdEnableCGT(dev, 0);
1250 RtdWriteCGLatch(dev, rtdConvertChanGain(dev, list[0], 0));
1251 }
1252}
1253
1254
1255
1256static int rtd520_probe_fifo_depth(struct comedi_device *dev)
1257{
1258 unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
1259 unsigned i;
1260 static const unsigned limit = 0x2000;
1261 unsigned fifo_size = 0;
1262
1263 RtdAdcClearFifo(dev);
1264 rtd_load_channelgain_list(dev, 1, &chanspec);
1265 RtdAdcConversionSource(dev, 0);
1266
1267 for (i = 0; i < limit; ++i) {
1268 unsigned fifo_status;
1269
1270 RtdAdcStart(dev);
1271 udelay(1);
1272 fifo_status = RtdFifoStatus(dev);
1273 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
1274 fifo_size = 2 * i;
1275 break;
1276 }
1277 }
1278 if (i == limit) {
1279 printk("\ncomedi: %s: failed to probe fifo size.\n", DRV_NAME);
1280 return -EIO;
1281 }
1282 RtdAdcClearFifo(dev);
1283 if (fifo_size != 0x400 && fifo_size != 0x2000) {
1284 printk
1285 ("\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n",
1286 DRV_NAME, fifo_size);
1287 return -EIO;
1288 }
1289 return fifo_size;
1290}
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300static int rtd_ai_rinsn(struct comedi_device *dev,
1301 struct comedi_subdevice *s, struct comedi_insn *insn,
1302 unsigned int *data)
1303{
1304 int n, ii;
1305 int stat;
1306
1307
1308 RtdAdcClearFifo(dev);
1309
1310
1311 rtd_load_channelgain_list(dev, 1, &insn->chanspec);
1312
1313
1314 RtdAdcConversionSource(dev, 0);
1315
1316
1317 for (n = 0; n < insn->n; n++) {
1318 s16 d;
1319
1320 RtdAdcStart(dev);
1321
1322 for (ii = 0; ii < RTD_ADC_TIMEOUT; ++ii) {
1323 stat = RtdFifoStatus(dev);
1324 if (stat & FS_ADC_NOT_EMPTY)
1325 break;
1326 WAIT_QUIETLY;
1327 }
1328 if (ii >= RTD_ADC_TIMEOUT) {
1329 DPRINTK
1330 ("rtd520: Error: ADC never finished! FifoStatus=0x%x\n",
1331 stat ^ 0x6666);
1332 return -ETIMEDOUT;
1333 }
1334
1335
1336 d = RtdAdcFifoGet(dev);
1337
1338 d = d >> 3;
1339 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0)) {
1340 data[n] = d + 2048;
1341 } else {
1342 data[n] = d;
1343 }
1344 }
1345
1346
1347 return n;
1348}
1349
1350
1351
1352
1353
1354
1355
1356static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
1357 int count)
1358{
1359 int ii;
1360
1361 for (ii = 0; ii < count; ii++) {
1362 short sample;
1363 s16 d;
1364
1365 if (0 == devpriv->aiCount) {
1366 d = RtdAdcFifoGet(dev);
1367 continue;
1368 }
1369#if 0
1370 if (0 == (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY)) {
1371 DPRINTK("comedi: READ OOPS on %d of %d\n", ii + 1,
1372 count);
1373 break;
1374 }
1375#endif
1376 d = RtdAdcFifoGet(dev);
1377
1378 d = d >> 3;
1379 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
1380 sample = d + 2048;
1381 } else {
1382 sample = d;
1383 }
1384 if (!comedi_buf_put(s->async, sample))
1385 return -1;
1386
1387 if (devpriv->aiCount > 0)
1388 devpriv->aiCount--;
1389 }
1390 return 0;
1391}
1392
1393
1394
1395
1396static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
1397{
1398 while (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY) {
1399 short sample;
1400 s16 d = RtdAdcFifoGet(dev);
1401
1402 if (0 == devpriv->aiCount) {
1403 continue;
1404 }
1405
1406 d = d >> 3;
1407 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
1408 sample = d + 2048;
1409 } else {
1410 sample = d;
1411 }
1412 if (!comedi_buf_put(s->async, sample))
1413 return -1;
1414
1415 if (devpriv->aiCount > 0)
1416 devpriv->aiCount--;
1417 }
1418 return 0;
1419}
1420
1421#ifdef USE_DMA
1422
1423
1424
1425void abort_dma(struct comedi_device *dev, unsigned int channel)
1426{
1427 unsigned long dma_cs_addr;
1428 uint8_t status;
1429 unsigned int ii;
1430
1431
1432 dma_cs_addr = (unsigned long)devpriv->lcfg
1433 + ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1);
1434
1435
1436
1437
1438
1439 status = readb(dma_cs_addr);
1440 if ((status & PLX_DMA_EN_BIT) == 0) {
1441 DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n",
1442 channel, status);
1443 goto abortDmaExit;
1444 }
1445
1446
1447 for (ii = 0; (status & PLX_DMA_DONE_BIT) && ii < RTD_DMA_TIMEOUT; ii++) {
1448 WAIT_QUIETLY;
1449 status = readb(dma_cs_addr);
1450 }
1451 if (status & PLX_DMA_DONE_BIT) {
1452 printk("rtd520: Timeout waiting for dma %i done clear\n",
1453 channel);
1454 goto abortDmaExit;
1455 }
1456
1457
1458 writeb(0, dma_cs_addr);
1459 udelay(1);
1460
1461 writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
1462
1463
1464 status = readb(dma_cs_addr);
1465 for (ii = 0;
1466 (status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT; ii++) {
1467 status = readb(dma_cs_addr);
1468 WAIT_QUIETLY;
1469 }
1470 if ((status & PLX_DMA_DONE_BIT) == 0) {
1471 printk("rtd520: Timeout waiting for dma %i done set\n",
1472 channel);
1473 }
1474
1475abortDmaExit:
1476
1477}
1478
1479
1480
1481
1482
1483static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s)
1484{
1485 int ii, n;
1486 s16 *dp;
1487
1488 if (devpriv->aiCount == 0)
1489 return 0;
1490
1491 dp = devpriv->dma0Buff[devpriv->dma0Offset];
1492 for (ii = 0; ii < devpriv->fifoLen / 2;) {
1493 short sample;
1494
1495 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
1496 sample = (*dp >> 3) + 2048;
1497 } else {
1498 sample = *dp >> 3;
1499 }
1500 *dp++ = sample;
1501
1502 if (++s->async->cur_chan >= s->async->cmd.chanlist_len)
1503 s->async->cur_chan = 0;
1504
1505 ++ii;
1506 if (devpriv->aiCount > 0) {
1507 if (--devpriv->aiCount == 0) {
1508
1509 break;
1510 }
1511 }
1512 }
1513
1514
1515 dp = devpriv->dma0Buff[devpriv->dma0Offset];
1516 n = comedi_buf_write_alloc(s->async, ii * sizeof(s16));
1517 if (n < (ii * sizeof(s16))) {
1518 DPRINTK("rtd520:ai_process_dma buffer overflow %d samples!\n",
1519 ii - (n / sizeof(s16)));
1520 s->async->events |= COMEDI_CB_ERROR;
1521 return -1;
1522 }
1523 comedi_buf_memcpy_to(s->async, 0, dp, n);
1524 comedi_buf_write_free(s->async, n);
1525
1526
1527 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
1528
1529 if (++devpriv->dma0Offset >= DMA_CHAIN_COUNT) {
1530 devpriv->dma0Offset = 0;
1531 }
1532 return 0;
1533}
1534#endif
1535
1536
1537
1538
1539
1540
1541
1542static irqreturn_t rtd_interrupt(int irq,
1543 void *d)
1544{
1545 struct comedi_device *dev = d;
1546 u16 status;
1547 u16 fifoStatus;
1548 struct comedi_subdevice *s = dev->subdevices + 0;
1549
1550 if (!dev->attached) {
1551 return IRQ_NONE;
1552 }
1553
1554 devpriv->intCount++;
1555
1556 fifoStatus = RtdFifoStatus(dev);
1557
1558 if (!(fifoStatus & FS_ADC_NOT_FULL)) {
1559 DPRINTK("rtd520: FIFO full! fifo_status=0x%x\n", (fifoStatus ^ 0x6666) & 0x7777);
1560 goto abortTransfer;
1561 }
1562#ifdef USE_DMA
1563 if (devpriv->flags & DMA0_ACTIVE) {
1564 u32 istatus = RtdPlxInterruptRead(dev);
1565
1566 if (istatus & ICS_DMA0_A) {
1567 if (ai_process_dma(dev, s) < 0) {
1568 DPRINTK
1569 ("rtd520: comedi read buffer overflow (DMA) with %ld to go!\n",
1570 devpriv->aiCount);
1571 RtdDma0Control(dev,
1572 (devpriv->dma0Control &
1573 ~PLX_DMA_START_BIT)
1574 | PLX_CLEAR_DMA_INTR_BIT);
1575 goto abortTransfer;
1576 }
1577
1578
1579
1580 RtdDma0Control(dev,
1581 (devpriv->
1582 dma0Control & ~PLX_DMA_START_BIT)
1583 | PLX_CLEAR_DMA_INTR_BIT);
1584 if (0 == devpriv->aiCount) {
1585 DPRINTK("rtd520: Samples Done (DMA).\n");
1586 goto transferDone;
1587 }
1588 comedi_event(dev, s);
1589 } else {
1590
1591 }
1592 }
1593
1594#endif
1595
1596 status = RtdInterruptStatus(dev);
1597
1598 if (0 == status) {
1599 return IRQ_HANDLED;
1600 }
1601
1602 if (status & IRQM_ADC_ABOUT_CNT) {
1603
1604
1605
1606 if (!(fifoStatus & FS_ADC_HEMPTY)) {
1607
1608
1609 if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) {
1610 DPRINTK
1611 ("rtd520: comedi read buffer overflow (1/2FIFO) with %ld to go!\n",
1612 devpriv->aiCount);
1613 goto abortTransfer;
1614 }
1615 if (0 == devpriv->aiCount) {
1616 DPRINTK("rtd520: Samples Done (1/2). fifo_status was 0x%x\n", (fifoStatus ^ 0x6666) & 0x7777);
1617 goto transferDone;
1618 }
1619 comedi_event(dev, s);
1620 } else if (devpriv->transCount > 0) {
1621
1622
1623 if (fifoStatus & FS_ADC_NOT_EMPTY) {
1624 if (ai_read_n(dev, s, devpriv->transCount) < 0) {
1625 DPRINTK
1626 ("rtd520: comedi read buffer overflow (N) with %ld to go!\n",
1627 devpriv->aiCount);
1628 goto abortTransfer;
1629 }
1630 if (0 == devpriv->aiCount) {
1631 DPRINTK
1632 ("rtd520: Samples Done (N). fifo_status was 0x%x\n",
1633 (fifoStatus ^ 0x6666) & 0x7777);
1634 goto transferDone;
1635 }
1636 comedi_event(dev, s);
1637 }
1638 } else {
1639 DPRINTK
1640 ("rtd520: Sample int. Wait for 1/2. fifo_status 0x%x\n",
1641 (fifoStatus ^ 0x6666) & 0x7777);
1642 }
1643 } else {
1644 DPRINTK("rtd520: unknown interrupt source!\n");
1645 }
1646
1647 if (0xffff & RtdInterruptOverrunStatus(dev)) {
1648 DPRINTK
1649 ("rtd520: Interrupt overrun with %ld to go! over_status=0x%x\n",
1650 devpriv->aiCount, 0xffff & RtdInterruptOverrunStatus(dev));
1651 goto abortTransfer;
1652 }
1653
1654
1655 RtdInterruptClearMask(dev, status);
1656 RtdInterruptClear(dev);
1657 return IRQ_HANDLED;
1658
1659abortTransfer:
1660 RtdAdcClearFifo(dev);
1661 s->async->events |= COMEDI_CB_ERROR;
1662 devpriv->aiCount = 0;
1663
1664
1665transferDone:
1666 RtdPacerStopSource(dev, 0);
1667 RtdPacerStop(dev);
1668 RtdAdcConversionSource(dev, 0);
1669 RtdInterruptMask(dev, 0);
1670#ifdef USE_DMA
1671 if (devpriv->flags & DMA0_ACTIVE) {
1672 RtdPlxInterruptWrite(dev,
1673 RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
1674 abort_dma(dev, 0);
1675 devpriv->flags &= ~DMA0_ACTIVE;
1676
1677 if (devpriv->aiCount > 0) {
1678 DPRINTK("rtd520: Lost DMA data! %ld remain\n",
1679 devpriv->aiCount);
1680 }
1681 }
1682#endif
1683
1684 if (devpriv->aiCount > 0) {
1685 fifoStatus = RtdFifoStatus(dev);
1686 DPRINTK("rtd520: Finishing up. %ld remain, fifoStat=%x\n", devpriv->aiCount, (fifoStatus ^ 0x6666) & 0x7777);
1687 ai_read_dregs(dev, s);
1688 }
1689
1690 s->async->events |= COMEDI_CB_EOA;
1691 comedi_event(dev, s);
1692
1693
1694 status = RtdInterruptStatus(dev);
1695 RtdInterruptClearMask(dev, status);
1696 RtdInterruptClear(dev);
1697
1698 fifoStatus = RtdFifoStatus(dev);
1699 DPRINTK
1700 ("rtd520: Acquisition complete. %ld ints, intStat=%x, overStat=%x\n",
1701 devpriv->intCount, status,
1702 0xffff & RtdInterruptOverrunStatus(dev));
1703
1704 return IRQ_HANDLED;
1705}
1706
1707#if 0
1708
1709
1710
1711static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
1712{
1713
1714
1715 return s->async->buf_write_count - s->async->buf_read_count;
1716}
1717#endif
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728static int rtd_ai_cmdtest(struct comedi_device *dev,
1729 struct comedi_subdevice *s, struct comedi_cmd *cmd)
1730{
1731 int err = 0;
1732 int tmp;
1733
1734
1735
1736 tmp = cmd->start_src;
1737 cmd->start_src &= TRIG_NOW;
1738 if (!cmd->start_src || tmp != cmd->start_src) {
1739 err++;
1740 }
1741
1742 tmp = cmd->scan_begin_src;
1743 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
1744 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) {
1745 err++;
1746 }
1747
1748 tmp = cmd->convert_src;
1749 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1750 if (!cmd->convert_src || tmp != cmd->convert_src) {
1751 err++;
1752 }
1753
1754 tmp = cmd->scan_end_src;
1755 cmd->scan_end_src &= TRIG_COUNT;
1756 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) {
1757 err++;
1758 }
1759
1760 tmp = cmd->stop_src;
1761 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1762 if (!cmd->stop_src || tmp != cmd->stop_src) {
1763 err++;
1764 }
1765
1766 if (err)
1767 return 1;
1768
1769
1770
1771
1772 if (cmd->scan_begin_src != TRIG_TIMER &&
1773 cmd->scan_begin_src != TRIG_EXT) {
1774 err++;
1775 }
1776 if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) {
1777 err++;
1778 }
1779 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) {
1780 err++;
1781 }
1782
1783 if (err) {
1784 return 2;
1785 }
1786
1787
1788
1789 if (cmd->start_arg != 0) {
1790 cmd->start_arg = 0;
1791 err++;
1792 }
1793
1794 if (cmd->scan_begin_src == TRIG_TIMER) {
1795
1796 if (1 == cmd->chanlist_len) {
1797 if (cmd->scan_begin_arg < RTD_MAX_SPEED_1) {
1798 cmd->scan_begin_arg = RTD_MAX_SPEED_1;
1799 rtd_ns_to_timer(&cmd->scan_begin_arg,
1800 TRIG_ROUND_UP);
1801 err++;
1802 }
1803 if (cmd->scan_begin_arg > RTD_MIN_SPEED_1) {
1804 cmd->scan_begin_arg = RTD_MIN_SPEED_1;
1805 rtd_ns_to_timer(&cmd->scan_begin_arg,
1806 TRIG_ROUND_DOWN);
1807 err++;
1808 }
1809 } else {
1810 if (cmd->scan_begin_arg < RTD_MAX_SPEED) {
1811 cmd->scan_begin_arg = RTD_MAX_SPEED;
1812 rtd_ns_to_timer(&cmd->scan_begin_arg,
1813 TRIG_ROUND_UP);
1814 err++;
1815 }
1816 if (cmd->scan_begin_arg > RTD_MIN_SPEED) {
1817 cmd->scan_begin_arg = RTD_MIN_SPEED;
1818 rtd_ns_to_timer(&cmd->scan_begin_arg,
1819 TRIG_ROUND_DOWN);
1820 err++;
1821 }
1822 }
1823 } else {
1824
1825
1826
1827 if (cmd->scan_begin_arg > 9) {
1828 cmd->scan_begin_arg = 9;
1829 err++;
1830 }
1831 }
1832 if (cmd->convert_src == TRIG_TIMER) {
1833 if (1 == cmd->chanlist_len) {
1834 if (cmd->convert_arg < RTD_MAX_SPEED_1) {
1835 cmd->convert_arg = RTD_MAX_SPEED_1;
1836 rtd_ns_to_timer(&cmd->convert_arg,
1837 TRIG_ROUND_UP);
1838 err++;
1839 }
1840 if (cmd->convert_arg > RTD_MIN_SPEED_1) {
1841 cmd->convert_arg = RTD_MIN_SPEED_1;
1842 rtd_ns_to_timer(&cmd->convert_arg,
1843 TRIG_ROUND_DOWN);
1844 err++;
1845 }
1846 } else {
1847 if (cmd->convert_arg < RTD_MAX_SPEED) {
1848 cmd->convert_arg = RTD_MAX_SPEED;
1849 rtd_ns_to_timer(&cmd->convert_arg,
1850 TRIG_ROUND_UP);
1851 err++;
1852 }
1853 if (cmd->convert_arg > RTD_MIN_SPEED) {
1854 cmd->convert_arg = RTD_MIN_SPEED;
1855 rtd_ns_to_timer(&cmd->convert_arg,
1856 TRIG_ROUND_DOWN);
1857 err++;
1858 }
1859 }
1860 } else {
1861
1862
1863 if (cmd->convert_arg > 9) {
1864 cmd->convert_arg = 9;
1865 err++;
1866 }
1867 }
1868
1869#if 0
1870 if (cmd->scan_end_arg != cmd->chanlist_len) {
1871 cmd->scan_end_arg = cmd->chanlist_len;
1872 err++;
1873 }
1874#endif
1875 if (cmd->stop_src == TRIG_COUNT) {
1876
1877
1878 } else {
1879
1880 if (cmd->stop_arg != 0) {
1881 cmd->stop_arg = 0;
1882 err++;
1883 }
1884 }
1885
1886 if (err) {
1887 return 3;
1888 }
1889
1890
1891
1892 if (cmd->chanlist_len > RTD_MAX_CHANLIST) {
1893 cmd->chanlist_len = RTD_MAX_CHANLIST;
1894 err++;
1895 }
1896 if (cmd->scan_begin_src == TRIG_TIMER) {
1897 tmp = cmd->scan_begin_arg;
1898 rtd_ns_to_timer(&cmd->scan_begin_arg,
1899 cmd->flags & TRIG_ROUND_MASK);
1900 if (tmp != cmd->scan_begin_arg) {
1901 err++;
1902 }
1903 }
1904 if (cmd->convert_src == TRIG_TIMER) {
1905 tmp = cmd->convert_arg;
1906 rtd_ns_to_timer(&cmd->convert_arg,
1907 cmd->flags & TRIG_ROUND_MASK);
1908 if (tmp != cmd->convert_arg) {
1909 err++;
1910 }
1911 if (cmd->scan_begin_src == TRIG_TIMER
1912 && (cmd->scan_begin_arg
1913 < (cmd->convert_arg * cmd->scan_end_arg))) {
1914 cmd->scan_begin_arg =
1915 cmd->convert_arg * cmd->scan_end_arg;
1916 err++;
1917 }
1918 }
1919
1920 if (err) {
1921 return 4;
1922 }
1923
1924 return 0;
1925}
1926
1927
1928
1929
1930
1931
1932
1933static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1934{
1935 struct comedi_cmd *cmd = &s->async->cmd;
1936 int timer;
1937
1938
1939 RtdPacerStopSource(dev, 0);
1940 RtdPacerStop(dev);
1941 RtdAdcConversionSource(dev, 0);
1942 RtdInterruptMask(dev, 0);
1943#ifdef USE_DMA
1944 if (devpriv->flags & DMA0_ACTIVE) {
1945 RtdPlxInterruptWrite(dev,
1946 RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
1947 abort_dma(dev, 0);
1948 devpriv->flags &= ~DMA0_ACTIVE;
1949 if (RtdPlxInterruptRead(dev) & ICS_DMA0_A) {
1950 RtdDma0Control(dev, PLX_CLEAR_DMA_INTR_BIT);
1951 }
1952 }
1953 RtdDma0Reset(dev);
1954#endif
1955 RtdAdcClearFifo(dev);
1956 RtdInterruptOverrunClear(dev);
1957 devpriv->intCount = 0;
1958
1959 if (!dev->irq) {
1960 DPRINTK("rtd520: ERROR! No interrupt available!\n");
1961 return -ENXIO;
1962 }
1963
1964
1965
1966 rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
1967
1968
1969 if (cmd->chanlist_len > 1) {
1970
1971 RtdPacerStartSource(dev, 0);
1972 RtdBurstStartSource(dev, 1);
1973 RtdAdcConversionSource(dev, 2);
1974 } else {
1975
1976 RtdPacerStartSource(dev, 0);
1977 RtdAdcConversionSource(dev, 1);
1978 }
1979 RtdAboutCounter(dev, devpriv->fifoLen / 2 - 1);
1980
1981 if (TRIG_TIMER == cmd->scan_begin_src) {
1982
1983
1984 if (cmd->flags & TRIG_WAKE_EOS) {
1985
1986
1987 devpriv->transCount = cmd->chanlist_len;
1988 devpriv->flags |= SEND_EOS;
1989 } else {
1990
1991 devpriv->transCount
1992 =
1993 (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
1994 cmd->scan_begin_arg;
1995 if (devpriv->transCount < cmd->chanlist_len) {
1996
1997 devpriv->transCount = cmd->chanlist_len;
1998 } else {
1999 devpriv->transCount =
2000 (devpriv->transCount +
2001 cmd->chanlist_len - 1)
2002 / cmd->chanlist_len;
2003 devpriv->transCount *= cmd->chanlist_len;
2004 }
2005 devpriv->flags |= SEND_EOS;
2006 }
2007 if (devpriv->transCount >= (devpriv->fifoLen / 2)) {
2008
2009 devpriv->transCount = 0;
2010 devpriv->flags &= ~SEND_EOS;
2011 } else {
2012
2013 RtdAboutCounter(dev, devpriv->transCount - 1);
2014 }
2015
2016 DPRINTK
2017 ("rtd520: scanLen=%d tranferCount=%d fifoLen=%d\n scanTime(ns)=%d flags=0x%x\n",
2018 cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen,
2019 cmd->scan_begin_arg, devpriv->flags);
2020 } else {
2021 devpriv->transCount = 0;
2022 devpriv->flags &= ~SEND_EOS;
2023 }
2024 RtdPacerClockSource(dev, 1);
2025 RtdAboutStopEnable(dev, 1);
2026
2027
2028
2029
2030 switch (cmd->stop_src) {
2031 case TRIG_COUNT:
2032 devpriv->aiCount = cmd->stop_arg * cmd->chanlist_len;
2033 if ((devpriv->transCount > 0)
2034 && (devpriv->transCount > devpriv->aiCount)) {
2035 devpriv->transCount = devpriv->aiCount;
2036 }
2037 break;
2038
2039 case TRIG_NONE:
2040 devpriv->aiCount = -1;
2041 break;
2042
2043 default:
2044 DPRINTK("rtd520: Warning! ignoring stop_src mode %d\n",
2045 cmd->stop_src);
2046 }
2047
2048
2049 switch (cmd->scan_begin_src) {
2050 case TRIG_TIMER:
2051 timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
2052 TRIG_ROUND_NEAREST);
2053
2054
2055 RtdPacerCounter(dev, timer);
2056
2057 break;
2058
2059 case TRIG_EXT:
2060 RtdPacerStartSource(dev, 1);
2061 break;
2062
2063 default:
2064 DPRINTK("rtd520: Warning! ignoring scan_begin_src mode %d\n",
2065 cmd->scan_begin_src);
2066 }
2067
2068
2069 switch (cmd->convert_src) {
2070 case TRIG_TIMER:
2071 if (cmd->chanlist_len > 1) {
2072 timer = rtd_ns_to_timer(&cmd->convert_arg,
2073 TRIG_ROUND_NEAREST);
2074
2075
2076 RtdBurstCounter(dev, timer);
2077 }
2078
2079 break;
2080
2081 case TRIG_EXT:
2082 RtdBurstStartSource(dev, 2);
2083 break;
2084
2085 default:
2086 DPRINTK("rtd520: Warning! ignoring convert_src mode %d\n",
2087 cmd->convert_src);
2088 }
2089
2090
2091
2092
2093 RtdInterruptClearMask(dev, ~0);
2094 RtdInterruptClear(dev);
2095
2096
2097 if (devpriv->transCount > 0) {
2098 RtdInterruptMask(dev, IRQM_ADC_ABOUT_CNT);
2099 DPRINTK("rtd520: Transferring every %d\n", devpriv->transCount);
2100 } else {
2101#ifdef USE_DMA
2102 devpriv->flags |= DMA0_ACTIVE;
2103
2104
2105 devpriv->dma0Offset = 0;
2106 RtdDma0Mode(dev, DMA_MODE_BITS);
2107 RtdDma0Next(dev,
2108 devpriv->dma0Chain[DMA_CHAIN_COUNT - 1].next);
2109 RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL);
2110
2111 RtdPlxInterruptWrite(dev,
2112 RtdPlxInterruptRead(dev) | ICS_DMA0_E);
2113
2114 RtdDma0Control(dev, PLX_DMA_EN_BIT);
2115 RtdDma0Control(dev, PLX_DMA_EN_BIT | PLX_DMA_START_BIT);
2116 DPRINTK("rtd520: Using DMA0 transfers. plxInt %x RtdInt %x\n",
2117 RtdPlxInterruptRead(dev), devpriv->intMask);
2118#else
2119 RtdInterruptMask(dev, IRQM_ADC_ABOUT_CNT);
2120 DPRINTK("rtd520: Transferring every 1/2 FIFO\n");
2121#endif
2122 }
2123
2124
2125
2126 RtdPacerStart(dev);
2127 return 0;
2128}
2129
2130
2131
2132
2133static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
2134{
2135 u16 status;
2136
2137 RtdPacerStopSource(dev, 0);
2138 RtdPacerStop(dev);
2139 RtdAdcConversionSource(dev, 0);
2140 RtdInterruptMask(dev, 0);
2141 devpriv->aiCount = 0;
2142#ifdef USE_DMA
2143 if (devpriv->flags & DMA0_ACTIVE) {
2144 RtdPlxInterruptWrite(dev,
2145 RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
2146 abort_dma(dev, 0);
2147 devpriv->flags &= ~DMA0_ACTIVE;
2148 }
2149#endif
2150 status = RtdInterruptStatus(dev);
2151 DPRINTK
2152 ("rtd520: Acquisition canceled. %ld ints, intStat=%x, overStat=%x\n",
2153 devpriv->intCount, status,
2154 0xffff & RtdInterruptOverrunStatus(dev));
2155 return 0;
2156}
2157
2158
2159
2160
2161
2162
2163
2164static int rtd_ns_to_timer_base(unsigned int *nanosec,
2165 int round_mode, int base)
2166{
2167 int divider;
2168
2169 switch (round_mode) {
2170 case TRIG_ROUND_NEAREST:
2171 default:
2172 divider = (*nanosec + base / 2) / base;
2173 break;
2174 case TRIG_ROUND_DOWN:
2175 divider = (*nanosec) / base;
2176 break;
2177 case TRIG_ROUND_UP:
2178 divider = (*nanosec + base - 1) / base;
2179 break;
2180 }
2181 if (divider < 2)
2182 divider = 2;
2183
2184
2185
2186
2187 *nanosec = base * divider;
2188 return divider - 1;
2189}
2190
2191
2192
2193
2194
2195
2196static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
2197{
2198 return rtd_ns_to_timer_base(ns, round_mode, RTD_CLOCK_BASE);
2199}
2200
2201
2202
2203
2204static int rtd_ao_winsn(struct comedi_device *dev,
2205 struct comedi_subdevice *s, struct comedi_insn *insn,
2206 unsigned int *data)
2207{
2208 int i;
2209 int chan = CR_CHAN(insn->chanspec);
2210 int range = CR_RANGE(insn->chanspec);
2211
2212
2213 RtdDacRange(dev, chan, range);
2214
2215
2216
2217 for (i = 0; i < insn->n; ++i) {
2218 int val = data[i] << 3;
2219 int stat = 0;
2220 int ii;
2221
2222
2223
2224 if ((range > 1)
2225 &&(data[i] < 2048)) {
2226
2227 val = (((int)data[i]) - 2048) << 3;
2228 } else {
2229 val = data[i] << 3;
2230 }
2231
2232 DPRINTK
2233 ("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n",
2234 chan, range, data[i], val);
2235
2236
2237 RtdDacFifoPut(dev, chan, val);
2238 RtdDacUpdate(dev, chan);
2239
2240 devpriv->aoValue[chan] = data[i];
2241
2242 for (ii = 0; ii < RTD_DAC_TIMEOUT; ++ii) {
2243 stat = RtdFifoStatus(dev);
2244
2245 if (stat & ((0 == chan) ? FS_DAC1_NOT_EMPTY :
2246 FS_DAC2_NOT_EMPTY))
2247 break;
2248 WAIT_QUIETLY;
2249 }
2250 if (ii >= RTD_DAC_TIMEOUT) {
2251 DPRINTK
2252 ("rtd520: Error: DAC never finished! FifoStatus=0x%x\n",
2253 stat ^ 0x6666);
2254 return -ETIMEDOUT;
2255 }
2256 }
2257
2258
2259 return i;
2260}
2261
2262
2263
2264static int rtd_ao_rinsn(struct comedi_device *dev,
2265 struct comedi_subdevice *s, struct comedi_insn *insn,
2266 unsigned int *data)
2267{
2268 int i;
2269 int chan = CR_CHAN(insn->chanspec);
2270
2271 for (i = 0; i < insn->n; i++) {
2272 data[i] = devpriv->aoValue[chan];
2273 }
2274
2275 return i;
2276}
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288static int rtd_dio_insn_bits(struct comedi_device *dev,
2289 struct comedi_subdevice *s,
2290 struct comedi_insn *insn, unsigned int *data)
2291{
2292 if (insn->n != 2)
2293 return -EINVAL;
2294
2295
2296
2297 if (data[0]) {
2298 s->state &= ~data[0];
2299 s->state |= data[0] & data[1];
2300
2301
2302 RtdDio0Write(dev, s->state);
2303 }
2304
2305
2306 data[1] = RtdDio0Read(dev);
2307
2308
2309
2310 return 2;
2311}
2312
2313
2314
2315
2316static int rtd_dio_insn_config(struct comedi_device *dev,
2317 struct comedi_subdevice *s,
2318 struct comedi_insn *insn, unsigned int *data)
2319{
2320 int chan = CR_CHAN(insn->chanspec);
2321
2322
2323
2324
2325
2326 switch (data[0]) {
2327 case INSN_CONFIG_DIO_OUTPUT:
2328 s->io_bits |= 1 << chan;
2329 break;
2330 case INSN_CONFIG_DIO_INPUT:
2331 s->io_bits &= ~(1 << chan);
2332 break;
2333 case INSN_CONFIG_DIO_QUERY:
2334 data[1] =
2335 (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
2336 return insn->n;
2337 break;
2338 default:
2339 return -EINVAL;
2340 }
2341
2342 DPRINTK("rtd520: port_0_direction=0x%x (1 means out)\n", s->io_bits);
2343
2344 RtdDioStatusWrite(dev, 0x01);
2345 RtdDio0CtrlWrite(dev, s->io_bits);
2346 RtdDioStatusWrite(dev, 0);
2347
2348
2349
2350
2351
2352 return 1;
2353}
2354
2355
2356
2357
2358
2359COMEDI_PCI_INITCLEANUP(rtd520Driver, rtd520_pci_table);
2360