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#include <linux/interrupt.h>
72#include <linux/kernel.h>
73#include <linux/types.h>
74
75#include "../comedidev.h"
76
77#include "comedi_pci.h"
78
79#include "comedi_fc.h"
80#include "s626.h"
81
82MODULE_AUTHOR("Gianluca Palli <gpalli@deis.unibo.it>");
83MODULE_DESCRIPTION("Sensoray 626 Comedi driver module");
84MODULE_LICENSE("GPL");
85
86struct s626_board {
87 const char *name;
88 int ai_chans;
89 int ai_bits;
90 int ao_chans;
91 int ao_bits;
92 int dio_chans;
93 int dio_banks;
94 int enc_chans;
95};
96
97static const struct s626_board s626_boards[] = {
98 {
99 .name = "s626",
100 .ai_chans = S626_ADC_CHANNELS,
101 .ai_bits = 14,
102 .ao_chans = S626_DAC_CHANNELS,
103 .ao_bits = 13,
104 .dio_chans = S626_DIO_CHANNELS,
105 .dio_banks = S626_DIO_BANKS,
106 .enc_chans = S626_ENCODER_CHANNELS,
107 }
108};
109
110#define thisboard ((const struct s626_board *)dev->board_ptr)
111#define PCI_VENDOR_ID_S626 0x1131
112#define PCI_DEVICE_ID_S626 0x7146
113
114
115
116
117
118
119static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = {
120 {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, 0x6000, 0x0272, 0, 0, 0},
121 {0}
122};
123
124MODULE_DEVICE_TABLE(pci, s626_pci_table);
125
126static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it);
127static int s626_detach(struct comedi_device *dev);
128
129static struct comedi_driver driver_s626 = {
130 .driver_name = "s626",
131 .module = THIS_MODULE,
132 .attach = s626_attach,
133 .detach = s626_detach,
134};
135
136struct s626_private {
137 struct pci_dev *pdev;
138 void *base_addr;
139 int got_regions;
140 short allocatedBuf;
141 uint8_t ai_cmd_running;
142 uint8_t ai_continous;
143 int ai_sample_count;
144 unsigned int ai_sample_timer;
145
146 int ai_convert_count;
147 unsigned int ai_convert_timer;
148
149 uint16_t CounterIntEnabs;
150
151 uint8_t AdcItems;
152 struct bufferDMA RPSBuf;
153 struct bufferDMA ANABuf;
154
155 uint32_t *pDacWBuf;
156
157 uint16_t Dacpol;
158 uint8_t TrimSetpoint[12];
159 uint16_t ChargeEnabled;
160
161 uint16_t WDInterval;
162 uint32_t I2CAdrs;
163
164
165 unsigned int ao_readback[S626_DAC_CHANNELS];
166};
167
168struct dio_private {
169 uint16_t RDDIn;
170 uint16_t WRDOut;
171 uint16_t RDEdgSel;
172 uint16_t WREdgSel;
173 uint16_t RDCapSel;
174 uint16_t WRCapSel;
175 uint16_t RDCapFlg;
176 uint16_t RDIntSel;
177 uint16_t WRIntSel;
178};
179
180static struct dio_private dio_private_A = {
181 .RDDIn = LP_RDDINA,
182 .WRDOut = LP_WRDOUTA,
183 .RDEdgSel = LP_RDEDGSELA,
184 .WREdgSel = LP_WREDGSELA,
185 .RDCapSel = LP_RDCAPSELA,
186 .WRCapSel = LP_WRCAPSELA,
187 .RDCapFlg = LP_RDCAPFLGA,
188 .RDIntSel = LP_RDINTSELA,
189 .WRIntSel = LP_WRINTSELA,
190};
191
192static struct dio_private dio_private_B = {
193 .RDDIn = LP_RDDINB,
194 .WRDOut = LP_WRDOUTB,
195 .RDEdgSel = LP_RDEDGSELB,
196 .WREdgSel = LP_WREDGSELB,
197 .RDCapSel = LP_RDCAPSELB,
198 .WRCapSel = LP_WRCAPSELB,
199 .RDCapFlg = LP_RDCAPFLGB,
200 .RDIntSel = LP_RDINTSELB,
201 .WRIntSel = LP_WRINTSELB,
202};
203
204static struct dio_private dio_private_C = {
205 .RDDIn = LP_RDDINC,
206 .WRDOut = LP_WRDOUTC,
207 .RDEdgSel = LP_RDEDGSELC,
208 .WREdgSel = LP_WREDGSELC,
209 .RDCapSel = LP_RDCAPSELC,
210 .WRCapSel = LP_WRCAPSELC,
211 .RDCapFlg = LP_RDCAPFLGC,
212 .RDIntSel = LP_RDINTSELC,
213 .WRIntSel = LP_WRINTSELC,
214};
215
216
217
218
219
220
221
222
223
224#define devpriv ((struct s626_private *)dev->private)
225#define diopriv ((struct dio_private *)s->private)
226
227COMEDI_PCI_INITCLEANUP_NOMODULE(driver_s626, s626_pci_table);
228
229
230static int s626_ai_insn_config(struct comedi_device *dev,
231 struct comedi_subdevice *s,
232 struct comedi_insn *insn, unsigned int *data);
233
234static int s626_ai_insn_read(struct comedi_device *dev,
235 struct comedi_subdevice *s,
236 struct comedi_insn *insn, unsigned int *data);
237static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
238static int s626_ai_cmdtest(struct comedi_device *dev,
239 struct comedi_subdevice *s, struct comedi_cmd *cmd);
240static int s626_ai_cancel(struct comedi_device *dev,
241 struct comedi_subdevice *s);
242static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
243 struct comedi_insn *insn, unsigned int *data);
244static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
245 struct comedi_insn *insn, unsigned int *data);
246static int s626_dio_insn_bits(struct comedi_device *dev,
247 struct comedi_subdevice *s,
248 struct comedi_insn *insn, unsigned int *data);
249static int s626_dio_insn_config(struct comedi_device *dev,
250 struct comedi_subdevice *s,
251 struct comedi_insn *insn, unsigned int *data);
252static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan);
253static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int gruop,
254 unsigned int mask);
255static int s626_dio_clear_irq(struct comedi_device *dev);
256static int s626_enc_insn_config(struct comedi_device *dev,
257 struct comedi_subdevice *s,
258 struct comedi_insn *insn, unsigned int *data);
259static int s626_enc_insn_read(struct comedi_device *dev,
260 struct comedi_subdevice *s,
261 struct comedi_insn *insn, unsigned int *data);
262static int s626_enc_insn_write(struct comedi_device *dev,
263 struct comedi_subdevice *s,
264 struct comedi_insn *insn, unsigned int *data);
265static int s626_ns_to_timer(int *nanosec, int round_mode);
266static int s626_ai_load_polllist(uint8_t * ppl, struct comedi_cmd *cmd);
267static int s626_ai_inttrig(struct comedi_device *dev,
268 struct comedi_subdevice *s, unsigned int trignum);
269static irqreturn_t s626_irq_handler(int irq, void *d);
270static unsigned int s626_ai_reg_to_uint(int data);
271
272
273
274
275
276static void s626_dio_init(struct comedi_device *dev);
277static void ResetADC(struct comedi_device *dev, uint8_t * ppl);
278static void LoadTrimDACs(struct comedi_device *dev);
279static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
280 uint8_t DacData);
281static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr);
282static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val);
283static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata);
284static void SendDAC(struct comedi_device *dev, uint32_t val);
285static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage);
286static void DEBItransfer(struct comedi_device *dev);
287static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr);
288static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata);
289static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
290 uint16_t wdata);
291static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
292 size_t bsize);
293
294
295struct enc_private {
296
297 uint16_t(*GetEnable) (struct comedi_device * dev, struct enc_private *);
298 uint16_t(*GetIntSrc) (struct comedi_device * dev, struct enc_private *);
299 uint16_t(*GetLoadTrig) (struct comedi_device * dev, struct enc_private *);
300 uint16_t(*GetMode) (struct comedi_device * dev, struct enc_private *);
301 void (*PulseIndex) (struct comedi_device * dev, struct enc_private *);
302 void (*SetEnable) (struct comedi_device * dev, struct enc_private *, uint16_t enab);
303 void (*SetIntSrc) (struct comedi_device * dev, struct enc_private *, uint16_t IntSource);
304 void (*SetLoadTrig) (struct comedi_device * dev, struct enc_private *, uint16_t Trig);
305 void (*SetMode) (struct comedi_device * dev, struct enc_private *, uint16_t Setup, uint16_t DisableIntSrc);
306 void (*ResetCapFlags) (struct comedi_device * dev, struct enc_private *);
307
308 uint16_t MyCRA;
309 uint16_t MyCRB;
310 uint16_t MyLatchLsw;
311
312 uint16_t MyEventBits[4];
313};
314
315#define encpriv ((struct enc_private *)(dev->subdevices+5)->private)
316
317
318static void s626_timer_load(struct comedi_device *dev, struct enc_private *k,
319 int tick);
320static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k);
321static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k);
322static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k);
323static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k);
324static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k);
325static void SetMode_A(struct comedi_device *dev, struct enc_private *k,
326 uint16_t Setup, uint16_t DisableIntSrc);
327static void SetMode_B(struct comedi_device *dev, struct enc_private *k,
328 uint16_t Setup, uint16_t DisableIntSrc);
329static void SetEnable_A(struct comedi_device *dev, struct enc_private *k,
330 uint16_t enab);
331static void SetEnable_B(struct comedi_device *dev, struct enc_private *k,
332 uint16_t enab);
333static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k);
334static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k);
335static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
336 uint16_t value);
337
338static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k,
339 uint16_t Trig);
340static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k,
341 uint16_t Trig);
342static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k);
343static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k);
344static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
345 uint16_t IntSource);
346static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
347 uint16_t IntSource);
348static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k);
349static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k);
350
351
352
353
354
355
356
357
358static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k);
359static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k);
360static void Preload(struct comedi_device *dev, struct enc_private *k,
361 uint32_t value);
362static void CountersInit(struct comedi_device *dev);
363
364
365
366
367
368#define INDXMASK(C) (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 + 4)))
369#define OVERMASK(C) (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
370#define EVBITS(C) { 0, OVERMASK(C), INDXMASK(C), OVERMASK(C) | INDXMASK(C) }
371
372
373
374
375
376static struct enc_private enc_private_data[] = {
377 {
378 .GetEnable = GetEnable_A,
379 .GetIntSrc = GetIntSrc_A,
380 .GetLoadTrig = GetLoadTrig_A,
381 .GetMode = GetMode_A,
382 .PulseIndex = PulseIndex_A,
383 .SetEnable = SetEnable_A,
384 .SetIntSrc = SetIntSrc_A,
385 .SetLoadTrig = SetLoadTrig_A,
386 .SetMode = SetMode_A,
387 .ResetCapFlags = ResetCapFlags_A,
388 .MyCRA = LP_CR0A,
389 .MyCRB = LP_CR0B,
390 .MyLatchLsw = LP_CNTR0ALSW,
391 .MyEventBits = EVBITS(0),
392 },
393 {
394 .GetEnable = GetEnable_A,
395 .GetIntSrc = GetIntSrc_A,
396 .GetLoadTrig = GetLoadTrig_A,
397 .GetMode = GetMode_A,
398 .PulseIndex = PulseIndex_A,
399 .SetEnable = SetEnable_A,
400 .SetIntSrc = SetIntSrc_A,
401 .SetLoadTrig = SetLoadTrig_A,
402 .SetMode = SetMode_A,
403 .ResetCapFlags = ResetCapFlags_A,
404 .MyCRA = LP_CR1A,
405 .MyCRB = LP_CR1B,
406 .MyLatchLsw = LP_CNTR1ALSW,
407 .MyEventBits = EVBITS(1),
408 },
409 {
410 .GetEnable = GetEnable_A,
411 .GetIntSrc = GetIntSrc_A,
412 .GetLoadTrig = GetLoadTrig_A,
413 .GetMode = GetMode_A,
414 .PulseIndex = PulseIndex_A,
415 .SetEnable = SetEnable_A,
416 .SetIntSrc = SetIntSrc_A,
417 .SetLoadTrig = SetLoadTrig_A,
418 .SetMode = SetMode_A,
419 .ResetCapFlags = ResetCapFlags_A,
420 .MyCRA = LP_CR2A,
421 .MyCRB = LP_CR2B,
422 .MyLatchLsw = LP_CNTR2ALSW,
423 .MyEventBits = EVBITS(2),
424 },
425 {
426 .GetEnable = GetEnable_B,
427 .GetIntSrc = GetIntSrc_B,
428 .GetLoadTrig = GetLoadTrig_B,
429 .GetMode = GetMode_B,
430 .PulseIndex = PulseIndex_B,
431 .SetEnable = SetEnable_B,
432 .SetIntSrc = SetIntSrc_B,
433 .SetLoadTrig = SetLoadTrig_B,
434 .SetMode = SetMode_B,
435 .ResetCapFlags = ResetCapFlags_B,
436 .MyCRA = LP_CR0A,
437 .MyCRB = LP_CR0B,
438 .MyLatchLsw = LP_CNTR0BLSW,
439 .MyEventBits = EVBITS(3),
440 },
441 {
442 .GetEnable = GetEnable_B,
443 .GetIntSrc = GetIntSrc_B,
444 .GetLoadTrig = GetLoadTrig_B,
445 .GetMode = GetMode_B,
446 .PulseIndex = PulseIndex_B,
447 .SetEnable = SetEnable_B,
448 .SetIntSrc = SetIntSrc_B,
449 .SetLoadTrig = SetLoadTrig_B,
450 .SetMode = SetMode_B,
451 .ResetCapFlags = ResetCapFlags_B,
452 .MyCRA = LP_CR1A,
453 .MyCRB = LP_CR1B,
454 .MyLatchLsw = LP_CNTR1BLSW,
455 .MyEventBits = EVBITS(4),
456 },
457 {
458 .GetEnable = GetEnable_B,
459 .GetIntSrc = GetIntSrc_B,
460 .GetLoadTrig = GetLoadTrig_B,
461 .GetMode = GetMode_B,
462 .PulseIndex = PulseIndex_B,
463 .SetEnable = SetEnable_B,
464 .SetIntSrc = SetIntSrc_B,
465 .SetLoadTrig = SetLoadTrig_B,
466 .SetMode = SetMode_B,
467 .ResetCapFlags = ResetCapFlags_B,
468 .MyCRA = LP_CR2A,
469 .MyCRB = LP_CR2B,
470 .MyLatchLsw = LP_CNTR2BLSW,
471 .MyEventBits = EVBITS(5),
472 },
473};
474
475
476
477#define MC_ENABLE(REGADRS, CTRLWORD) writel(((uint32_t)(CTRLWORD) << 16) | (uint32_t)(CTRLWORD), devpriv->base_addr+(REGADRS))
478
479#define MC_DISABLE(REGADRS, CTRLWORD) writel((uint32_t)(CTRLWORD) << 16 , devpriv->base_addr+(REGADRS))
480
481#define MC_TEST(REGADRS, CTRLWORD) ((readl(devpriv->base_addr+(REGADRS)) & CTRLWORD) != 0)
482
483
484
485#define WR7146(REGARDS, CTRLWORD) writel(CTRLWORD, devpriv->base_addr+(REGARDS))
486
487
488
489#define RR7146(REGARDS) readl(devpriv->base_addr+(REGARDS))
490
491#define BUGFIX_STREG(REGADRS) (REGADRS - 4)
492
493
494#define VECTPORT(VECTNUM) (P_TSL2 + ((VECTNUM) << 2))
495#define SETVECT(VECTNUM, VECTVAL) WR7146(VECTPORT(VECTNUM), (VECTVAL))
496
497
498#define I2C_B2(ATTR, VAL) (((ATTR) << 6) | ((VAL) << 24))
499#define I2C_B1(ATTR, VAL) (((ATTR) << 4) | ((VAL) << 16))
500#define I2C_B0(ATTR, VAL) (((ATTR) << 2) | ((VAL) << 8))
501
502static const struct comedi_lrange s626_range_table = { 2, {
503 RANGE(-5, 5),
504 RANGE(-10, 10),
505 }
506};
507
508static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
509{
510
511
512
513
514
515 int result;
516 int i;
517 int ret;
518 resource_size_t resourceStart;
519 dma_addr_t appdma;
520 struct comedi_subdevice *s;
521 const struct pci_device_id *ids;
522 struct pci_dev *pdev = NULL;
523
524 if (alloc_private(dev, sizeof(struct s626_private)) < 0)
525 return -ENOMEM;
526
527 for (i = 0; i < (ARRAY_SIZE(s626_pci_table) - 1) && !pdev; i++) {
528 ids = &s626_pci_table[i];
529 do {
530 pdev = pci_get_subsys(ids->vendor, ids->device,
531 ids->subvendor, ids->subdevice,
532 pdev);
533
534 if ((it->options[0] || it->options[1]) && pdev) {
535
536 if (pdev->bus->number == it->options[0] &&
537 PCI_SLOT(pdev->devfn) == it->options[1])
538 break;
539 } else
540 break;
541 } while (1);
542 }
543 devpriv->pdev = pdev;
544
545 if (pdev == NULL) {
546 printk("s626_attach: Board not present!!!\n");
547 return -ENODEV;
548 }
549
550 result = comedi_pci_enable(pdev, "s626");
551 if (result < 0) {
552 printk("s626_attach: comedi_pci_enable fails\n");
553 return -ENODEV;
554 }
555 devpriv->got_regions = 1;
556
557 resourceStart = pci_resource_start(devpriv->pdev, 0);
558
559 devpriv->base_addr = ioremap(resourceStart, SIZEOF_ADDRESS_SPACE);
560 if (devpriv->base_addr == NULL) {
561 printk("s626_attach: IOREMAP failed\n");
562 return -ENODEV;
563 }
564
565 if (devpriv->base_addr) {
566
567 writel(0, devpriv->base_addr + P_IER);
568
569
570 writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1);
571
572
573 DEBUG("s626_attach: DMA ALLOCATION\n");
574
575
576 devpriv->allocatedBuf = 0;
577
578 devpriv->ANABuf.LogicalBase =
579 pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
580
581 if (devpriv->ANABuf.LogicalBase == NULL) {
582 printk("s626_attach: DMA Memory mapping error\n");
583 return -ENOMEM;
584 }
585
586 devpriv->ANABuf.PhysicalBase = appdma;
587
588 DEBUG
589 ("s626_attach: AllocDMAB ADC Logical=%p, bsize=%d, Physical=0x%x\n",
590 devpriv->ANABuf.LogicalBase, DMABUF_SIZE,
591 (uint32_t) devpriv->ANABuf.PhysicalBase);
592
593 devpriv->allocatedBuf++;
594
595 devpriv->RPSBuf.LogicalBase =
596 pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
597
598 if (devpriv->RPSBuf.LogicalBase == NULL) {
599 printk("s626_attach: DMA Memory mapping error\n");
600 return -ENOMEM;
601 }
602
603 devpriv->RPSBuf.PhysicalBase = appdma;
604
605 DEBUG
606 ("s626_attach: AllocDMAB RPS Logical=%p, bsize=%d, Physical=0x%x\n",
607 devpriv->RPSBuf.LogicalBase, DMABUF_SIZE,
608 (uint32_t) devpriv->RPSBuf.PhysicalBase);
609
610 devpriv->allocatedBuf++;
611
612 }
613
614 dev->board_ptr = s626_boards;
615 dev->board_name = thisboard->name;
616
617 if (alloc_subdevices(dev, 6) < 0)
618 return -ENOMEM;
619
620 dev->iobase = (unsigned long)devpriv->base_addr;
621 dev->irq = devpriv->pdev->irq;
622
623
624 if (dev->irq == 0) {
625 printk(" unknown irq (bad)\n");
626 } else {
627 ret = request_irq(dev->irq, s626_irq_handler, IRQF_SHARED,
628 "s626", dev);
629
630 if (ret < 0) {
631 printk(" irq not available\n");
632 dev->irq = 0;
633 }
634 }
635
636 DEBUG("s626_attach: -- it opts %d,%d -- \n",
637 it->options[0], it->options[1]);
638
639 s = dev->subdevices + 0;
640
641 dev->read_subdev = s;
642
643 s->type = COMEDI_SUBD_AI;
644 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ;
645 s->n_chan = thisboard->ai_chans;
646 s->maxdata = (0xffff >> 2);
647 s->range_table = &s626_range_table;
648 s->len_chanlist = thisboard->ai_chans;
649
650
651 s->insn_config = s626_ai_insn_config;
652 s->insn_read = s626_ai_insn_read;
653 s->do_cmd = s626_ai_cmd;
654 s->do_cmdtest = s626_ai_cmdtest;
655 s->cancel = s626_ai_cancel;
656
657 s = dev->subdevices + 1;
658
659 s->type = COMEDI_SUBD_AO;
660 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
661 s->n_chan = thisboard->ao_chans;
662 s->maxdata = (0x3fff);
663 s->range_table = &range_bipolar10;
664 s->insn_write = s626_ao_winsn;
665 s->insn_read = s626_ao_rinsn;
666
667 s = dev->subdevices + 2;
668
669 s->type = COMEDI_SUBD_DIO;
670 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
671 s->n_chan = S626_DIO_CHANNELS;
672 s->maxdata = 1;
673 s->io_bits = 0xffff;
674 s->private = &dio_private_A;
675 s->range_table = &range_digital;
676 s->insn_config = s626_dio_insn_config;
677 s->insn_bits = s626_dio_insn_bits;
678
679 s = dev->subdevices + 3;
680
681 s->type = COMEDI_SUBD_DIO;
682 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
683 s->n_chan = 16;
684 s->maxdata = 1;
685 s->io_bits = 0xffff;
686 s->private = &dio_private_B;
687 s->range_table = &range_digital;
688 s->insn_config = s626_dio_insn_config;
689 s->insn_bits = s626_dio_insn_bits;
690
691 s = dev->subdevices + 4;
692
693 s->type = COMEDI_SUBD_DIO;
694 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
695 s->n_chan = 16;
696 s->maxdata = 1;
697 s->io_bits = 0xffff;
698 s->private = &dio_private_C;
699 s->range_table = &range_digital;
700 s->insn_config = s626_dio_insn_config;
701 s->insn_bits = s626_dio_insn_bits;
702
703 s = dev->subdevices + 5;
704
705 s->type = COMEDI_SUBD_COUNTER;
706 s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL;
707 s->n_chan = thisboard->enc_chans;
708 s->private = enc_private_data;
709 s->insn_config = s626_enc_insn_config;
710 s->insn_read = s626_enc_insn_read;
711 s->insn_write = s626_enc_insn_write;
712 s->maxdata = 0xffffff;
713 s->range_table = &range_unknown;
714
715
716 devpriv->ai_cmd_running = 0;
717
718 if (devpriv->base_addr && (devpriv->allocatedBuf == 2)) {
719 dma_addr_t pPhysBuf;
720 uint16_t chan;
721
722
723 MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C);
724
725 WR7146(P_DEBICFG, DEBI_CFG_SLAVE16
726
727 | (DEBI_TOUT << DEBI_CFG_TOUT_BIT)
728
729
730
731
732 |DEBI_SWAP
733
734 | DEBI_CFG_INTEL);
735
736
737 DEBUG("s626_attach: %d debi init -- %d\n",
738 DEBI_CFG_SLAVE16 | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) |
739 DEBI_SWAP | DEBI_CFG_INTEL,
740 DEBI_CFG_INTEL | DEBI_CFG_TOQ | DEBI_CFG_INCQ |
741 DEBI_CFG_16Q);
742
743
744
745
746
747 WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE);
748
749
750 WR7146(P_GPIO, GPIO_BASE | GPIO1_HI);
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773 devpriv->I2CAdrs = 0xA0;
774
775
776
777
778 WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT);
779
780 MC_ENABLE(P_MC2, MC2_UPLD_IIC);
781
782 while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) ;
783
784
785
786
787 for (i = 0; i < 2; i++) {
788 WR7146(P_I2CSTAT, I2C_CLKSEL);
789
790 MC_ENABLE(P_MC2, MC2_UPLD_IIC);
791 while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ;
792
793 }
794
795
796
797
798
799
800
801 WR7146(P_ACON2, ACON2_INIT);
802
803
804
805
806
807 WR7146(P_TSL1, RSD1 | SIB_A1);
808
809 WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS);
810
811
812
813 WR7146(P_ACON1, ACON1_ADCSTART);
814
815
816
817
818 WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
819
820 WR7146(P_RPSPAGE1, 0);
821
822 WR7146(P_RPS1_TOUT, 0);
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864 WR7146(P_PCI_BT_A, 0);
865
866
867
868
869
870
871 pPhysBuf =
872 devpriv->ANABuf.PhysicalBase +
873 (DAC_WDMABUF_OS * sizeof(uint32_t));
874
875 WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf);
876 WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t)));
877
878
879
880 devpriv->pDacWBuf =
881 (uint32_t *) devpriv->ANABuf.LogicalBase + DAC_WDMABUF_OS;
882
883
884
885
886
887
888 WR7146(P_PAGEA2_OUT, 8);
889
890
891
892
893
894
895
896
897
898
899
900
901 SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS);
902
903
904
905
906
907
908
909
910
911 SETVECT(1, LF_A2);
912
913
914
915 WR7146(P_ACON1, ACON1_DACSTART);
916
917
918
919
920
921
922
923
924 LoadTrimDACs(dev);
925 LoadTrimDACs(dev);
926
927
928
929
930
931
932
933
934
935
936 for (chan = 0; chan < S626_DAC_CHANNELS; chan++)
937 SetDAC(dev, chan, 0);
938
939
940
941
942
943 devpriv->ChargeEnabled = 0;
944
945
946
947
948
949 devpriv->WDInterval = 0;
950
951
952
953
954
955 devpriv->CounterIntEnabs = 0;
956
957
958 CountersInit(dev);
959
960
961
962
963
964
965 WriteMISC2(dev, (uint16_t) (DEBIread(dev,
966 LP_RDMISC2) &
967 MISC2_BATT_ENABLE));
968
969
970 s626_dio_init(dev);
971
972
973
974 }
975
976 DEBUG("s626_attach: comedi%d s626 attached %04x\n", dev->minor,
977 (uint32_t) devpriv->base_addr);
978
979 return 1;
980}
981
982static unsigned int s626_ai_reg_to_uint(int data)
983{
984 unsigned int tempdata;
985
986 tempdata = (data >> 18);
987 if (tempdata & 0x2000)
988 tempdata &= 0x1fff;
989 else
990 tempdata += (1 << 13);
991
992 return tempdata;
993}
994
995
996
997
998
999static irqreturn_t s626_irq_handler(int irq, void *d)
1000{
1001 struct comedi_device *dev = d;
1002 struct comedi_subdevice *s;
1003 struct comedi_cmd *cmd;
1004 struct enc_private *k;
1005 unsigned long flags;
1006 int32_t *readaddr;
1007 uint32_t irqtype, irqstatus;
1008 int i = 0;
1009 short tempdata;
1010 uint8_t group;
1011 uint16_t irqbit;
1012
1013 DEBUG("s626_irq_handler: interrupt request recieved!!!\n");
1014
1015 if (dev->attached == 0)
1016 return IRQ_NONE;
1017
1018 spin_lock_irqsave(&dev->spinlock, flags);
1019
1020
1021 irqstatus = readl(devpriv->base_addr + P_IER);
1022
1023
1024 irqtype = readl(devpriv->base_addr + P_ISR);
1025
1026
1027 writel(0, devpriv->base_addr + P_IER);
1028
1029
1030 writel(irqtype, devpriv->base_addr + P_ISR);
1031
1032
1033 DEBUG("s626_irq_handler: interrupt type %d\n", irqtype);
1034
1035 switch (irqtype) {
1036 case IRQ_RPS1:
1037
1038 DEBUG("s626_irq_handler: RPS1 irq detected\n");
1039
1040
1041 s = dev->subdevices;
1042 cmd = &(s->async->cmd);
1043
1044
1045
1046
1047
1048 readaddr = (int32_t *) devpriv->ANABuf.LogicalBase + 1;
1049
1050
1051 for (i = 0; i < (s->async->cmd.chanlist_len); i++) {
1052
1053
1054 tempdata = s626_ai_reg_to_uint((int)*readaddr);
1055 readaddr++;
1056
1057
1058
1059 if (cfc_write_to_buffer(s, tempdata) == 0)
1060 printk
1061 ("s626_irq_handler: cfc_write_to_buffer error!\n");
1062
1063 DEBUG("s626_irq_handler: ai channel %d acquired: %d\n",
1064 i, tempdata);
1065 }
1066
1067
1068 s->async->events |= COMEDI_CB_EOS;
1069
1070 if (!(devpriv->ai_continous))
1071 devpriv->ai_sample_count--;
1072 if (devpriv->ai_sample_count <= 0) {
1073 devpriv->ai_cmd_running = 0;
1074
1075
1076 MC_DISABLE(P_MC1, MC1_ERPS1);
1077
1078
1079 s->async->events |= COMEDI_CB_EOA;
1080
1081
1082 irqstatus = 0;
1083 }
1084
1085 if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) {
1086 DEBUG
1087 ("s626_irq_handler: enable interrupt on dio channel %d\n",
1088 cmd->scan_begin_arg);
1089
1090 s626_dio_set_irq(dev, cmd->scan_begin_arg);
1091
1092 DEBUG("s626_irq_handler: External trigger is set!!!\n");
1093 }
1094
1095 DEBUG("s626_irq_handler: events %d\n", s->async->events);
1096 comedi_event(dev, s);
1097 break;
1098 case IRQ_GPIO3:
1099
1100 DEBUG("s626_irq_handler: GPIO3 irq detected\n");
1101
1102
1103 s = dev->subdevices;
1104 cmd = &(s->async->cmd);
1105
1106
1107
1108 for (group = 0; group < S626_DIO_BANKS; group++) {
1109 irqbit = 0;
1110
1111 irqbit = DEBIread(dev,
1112 ((struct dio_private *)(dev->
1113 subdevices +
1114 2 +
1115 group)->
1116 private)->RDCapFlg);
1117
1118
1119 if (irqbit) {
1120 s626_dio_reset_irq(dev, group, irqbit);
1121 DEBUG
1122 ("s626_irq_handler: check interrupt on dio group %d %d\n",
1123 group, i);
1124 if (devpriv->ai_cmd_running) {
1125
1126 if ((irqbit >> (cmd->start_arg -
1127 (16 * group)))
1128 == 1 && cmd->start_src == TRIG_EXT) {
1129 DEBUG
1130 ("s626_irq_handler: Edge capture interrupt recieved from channel %d\n",
1131 cmd->start_arg);
1132
1133
1134 MC_ENABLE(P_MC1, MC1_ERPS1);
1135
1136 DEBUG
1137 ("s626_irq_handler: aquisition start triggered!!!\n");
1138
1139 if (cmd->scan_begin_src ==
1140 TRIG_EXT) {
1141 DEBUG
1142 ("s626_ai_cmd: enable interrupt on dio channel %d\n",
1143 cmd->
1144 scan_begin_arg);
1145
1146 s626_dio_set_irq(dev,
1147 cmd->scan_begin_arg);
1148
1149 DEBUG
1150 ("s626_irq_handler: External scan trigger is set!!!\n");
1151 }
1152 }
1153 if ((irqbit >> (cmd->scan_begin_arg -
1154 (16 * group)))
1155 == 1
1156 && cmd->scan_begin_src ==
1157 TRIG_EXT) {
1158 DEBUG
1159 ("s626_irq_handler: Edge capture interrupt recieved from channel %d\n",
1160 cmd->scan_begin_arg);
1161
1162
1163 MC_ENABLE(P_MC2, MC2_ADC_RPS);
1164
1165 DEBUG
1166 ("s626_irq_handler: scan triggered!!! %d\n",
1167 devpriv->ai_sample_count);
1168 if (cmd->convert_src ==
1169 TRIG_EXT) {
1170
1171 DEBUG
1172 ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n",
1173 cmd->convert_arg -
1174 (16 * group),
1175 group);
1176
1177 devpriv->ai_convert_count
1178 = cmd->chanlist_len;
1179
1180 s626_dio_set_irq(dev,
1181 cmd->convert_arg);
1182
1183 DEBUG
1184 ("s626_irq_handler: External convert trigger is set!!!\n");
1185 }
1186
1187 if (cmd->convert_src ==
1188 TRIG_TIMER) {
1189 k = &encpriv[5];
1190 devpriv->ai_convert_count
1191 = cmd->chanlist_len;
1192 k->SetEnable(dev, k,
1193 CLKENAB_ALWAYS);
1194 }
1195 }
1196 if ((irqbit >> (cmd->convert_arg -
1197 (16 * group)))
1198 == 1
1199 && cmd->convert_src == TRIG_EXT) {
1200 DEBUG
1201 ("s626_irq_handler: Edge capture interrupt recieved from channel %d\n",
1202 cmd->convert_arg);
1203
1204
1205 MC_ENABLE(P_MC2, MC2_ADC_RPS);
1206
1207 DEBUG
1208 ("s626_irq_handler: adc convert triggered!!!\n");
1209
1210 devpriv->ai_convert_count--;
1211
1212 if (devpriv->ai_convert_count >
1213 0) {
1214
1215 DEBUG
1216 ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n",
1217 cmd->convert_arg -
1218 (16 * group),
1219 group);
1220
1221 s626_dio_set_irq(dev,
1222 cmd->convert_arg);
1223
1224 DEBUG
1225 ("s626_irq_handler: External trigger is set!!!\n");
1226 }
1227 }
1228 }
1229 break;
1230 }
1231 }
1232
1233
1234 irqbit = DEBIread(dev, LP_RDMISC2);
1235
1236
1237 DEBUG("s626_irq_handler: check counters interrupt %d\n",
1238 irqbit);
1239
1240 if (irqbit & IRQ_COINT1A) {
1241 DEBUG
1242 ("s626_irq_handler: interrupt on counter 1A overflow\n");
1243 k = &encpriv[0];
1244
1245
1246 k->ResetCapFlags(dev, k);
1247 }
1248 if (irqbit & IRQ_COINT2A) {
1249 DEBUG
1250 ("s626_irq_handler: interrupt on counter 2A overflow\n");
1251 k = &encpriv[1];
1252
1253
1254 k->ResetCapFlags(dev, k);
1255 }
1256 if (irqbit & IRQ_COINT3A) {
1257 DEBUG
1258 ("s626_irq_handler: interrupt on counter 3A overflow\n");
1259 k = &encpriv[2];
1260
1261
1262 k->ResetCapFlags(dev, k);
1263 }
1264 if (irqbit & IRQ_COINT1B) {
1265 DEBUG
1266 ("s626_irq_handler: interrupt on counter 1B overflow\n");
1267 k = &encpriv[3];
1268
1269
1270 k->ResetCapFlags(dev, k);
1271 }
1272 if (irqbit & IRQ_COINT2B) {
1273 DEBUG
1274 ("s626_irq_handler: interrupt on counter 2B overflow\n");
1275 k = &encpriv[4];
1276
1277
1278 k->ResetCapFlags(dev, k);
1279
1280 if (devpriv->ai_convert_count > 0) {
1281 devpriv->ai_convert_count--;
1282 if (devpriv->ai_convert_count == 0)
1283 k->SetEnable(dev, k, CLKENAB_INDEX);
1284
1285 if (cmd->convert_src == TRIG_TIMER) {
1286 DEBUG
1287 ("s626_irq_handler: conver timer trigger!!! %d\n",
1288 devpriv->ai_convert_count);
1289
1290
1291 MC_ENABLE(P_MC2, MC2_ADC_RPS);
1292 }
1293 }
1294 }
1295 if (irqbit & IRQ_COINT3B) {
1296 DEBUG
1297 ("s626_irq_handler: interrupt on counter 3B overflow\n");
1298 k = &encpriv[5];
1299
1300
1301 k->ResetCapFlags(dev, k);
1302
1303 if (cmd->scan_begin_src == TRIG_TIMER) {
1304 DEBUG
1305 ("s626_irq_handler: scan timer trigger!!!\n");
1306
1307
1308 MC_ENABLE(P_MC2, MC2_ADC_RPS);
1309 }
1310
1311 if (cmd->convert_src == TRIG_TIMER) {
1312 DEBUG
1313 ("s626_irq_handler: convert timer trigger is set\n");
1314 k = &encpriv[4];
1315 devpriv->ai_convert_count = cmd->chanlist_len;
1316 k->SetEnable(dev, k, CLKENAB_ALWAYS);
1317 }
1318 }
1319 }
1320
1321
1322 writel(irqstatus, devpriv->base_addr + P_IER);
1323
1324 DEBUG("s626_irq_handler: exit interrupt service routine.\n");
1325
1326 spin_unlock_irqrestore(&dev->spinlock, flags);
1327 return IRQ_HANDLED;
1328}
1329
1330static int s626_detach(struct comedi_device *dev)
1331{
1332 if (devpriv) {
1333
1334 devpriv->ai_cmd_running = 0;
1335
1336 if (devpriv->base_addr) {
1337
1338 WR7146(P_IER, 0);
1339 WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1);
1340
1341
1342 WriteMISC2(dev, 0);
1343
1344
1345 WR7146(P_MC1, MC1_SHUTDOWN);
1346 WR7146(P_ACON1, ACON1_BASE);
1347
1348 CloseDMAB(dev, &devpriv->RPSBuf, DMABUF_SIZE);
1349 CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE);
1350 }
1351
1352 if (dev->irq)
1353 free_irq(dev->irq, dev);
1354
1355 if (devpriv->base_addr)
1356 iounmap(devpriv->base_addr);
1357
1358 if (devpriv->pdev) {
1359 if (devpriv->got_regions)
1360 comedi_pci_disable(devpriv->pdev);
1361 pci_dev_put(devpriv->pdev);
1362 }
1363 }
1364
1365 DEBUG("s626_detach: S626 detached!\n");
1366
1367 return 0;
1368}
1369
1370
1371
1372
1373void ResetADC(struct comedi_device *dev, uint8_t * ppl)
1374{
1375 register uint32_t *pRPS;
1376 uint32_t JmpAdrs;
1377 uint16_t i;
1378 uint16_t n;
1379 uint32_t LocalPPL;
1380 struct comedi_cmd *cmd = &(dev->subdevices->async->cmd);
1381
1382
1383 MC_DISABLE(P_MC1, MC1_ERPS1);
1384
1385
1386 pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase;
1387
1388
1389 WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
1390
1391
1392
1393 if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) {
1394 DEBUG("ResetADC: scan_begin pause inserted\n");
1395
1396 *pRPS++ = RPS_PAUSE | RPS_SIGADC;
1397 *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
1398 }
1399
1400
1401
1402
1403
1404
1405
1406
1407 *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
1408
1409
1410 *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
1411 *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
1412
1413
1414 *pRPS++ = GSEL_BIPOLAR5V;
1415
1416
1417 *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
1418
1419 *pRPS++ = RPS_UPLOAD | RPS_DEBI;
1420 *pRPS++ = RPS_PAUSE | RPS_DEBI;
1421
1422
1423
1424
1425
1426 for (devpriv->AdcItems = 0; devpriv->AdcItems < 16; devpriv->AdcItems++) {
1427
1428
1429
1430
1431
1432 LocalPPL =
1433 (*ppl << 8) | (*ppl & 0x10 ? GSEL_BIPOLAR5V :
1434 GSEL_BIPOLAR10V);
1435
1436
1437 *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
1438
1439
1440 *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
1441 *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
1442
1443
1444 *pRPS++ = LocalPPL;
1445 *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
1446
1447 *pRPS++ = RPS_UPLOAD | RPS_DEBI;
1448 *pRPS++ = RPS_PAUSE | RPS_DEBI;
1449
1450
1451
1452 *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
1453
1454 *pRPS++ = DEBI_CMD_WRWORD | LP_ISEL;
1455 *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
1456
1457 *pRPS++ = LocalPPL;
1458 *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
1459
1460
1461 *pRPS++ = RPS_UPLOAD | RPS_DEBI;
1462
1463
1464 *pRPS++ = RPS_PAUSE | RPS_DEBI;
1465
1466
1467
1468
1469
1470
1471
1472
1473 JmpAdrs =
1474 (uint32_t) devpriv->RPSBuf.PhysicalBase +
1475 (uint32_t) ((unsigned long)pRPS -
1476 (unsigned long)devpriv->RPSBuf.LogicalBase);
1477 for (i = 0; i < (10 * RPSCLK_PER_US / 2); i++) {
1478 JmpAdrs += 8;
1479 *pRPS++ = RPS_JUMP;
1480 *pRPS++ = JmpAdrs;
1481 }
1482
1483 if (cmd != NULL && cmd->convert_src != TRIG_NOW) {
1484 DEBUG("ResetADC: convert pause inserted\n");
1485
1486 *pRPS++ = RPS_PAUSE | RPS_SIGADC;
1487 *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
1488 }
1489
1490 *pRPS++ = RPS_LDREG | (P_GPIO >> 2);
1491 *pRPS++ = GPIO_BASE | GPIO1_LO;
1492 *pRPS++ = RPS_NOP;
1493
1494 *pRPS++ = RPS_LDREG | (P_GPIO >> 2);
1495 *pRPS++ = GPIO_BASE | GPIO1_HI;
1496
1497
1498
1499
1500
1501 *pRPS++ = RPS_PAUSE | RPS_GPIO2;
1502
1503
1504 *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);
1505 *pRPS++ =
1506 (uint32_t) devpriv->ANABuf.PhysicalBase +
1507 (devpriv->AdcItems << 2);
1508
1509
1510
1511 if (*ppl++ & EOPL) {
1512 devpriv->AdcItems++;
1513 break;
1514 }
1515 }
1516 DEBUG("ResetADC: ADC items %d \n", devpriv->AdcItems);
1517
1518
1519
1520
1521
1522
1523
1524
1525 for (n = 0; n < (2 * RPSCLK_PER_US); n++)
1526 *pRPS++ = RPS_NOP;
1527
1528
1529
1530
1531 *pRPS++ = RPS_LDREG | (P_GPIO >> 2);
1532 *pRPS++ = GPIO_BASE | GPIO1_LO;
1533 *pRPS++ = RPS_NOP;
1534
1535 *pRPS++ = RPS_LDREG | (P_GPIO >> 2);
1536 *pRPS++ = GPIO_BASE | GPIO1_HI;
1537
1538
1539
1540
1541 *pRPS++ = RPS_PAUSE | RPS_GPIO2;
1542
1543
1544 *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);
1545 *pRPS++ =
1546 (uint32_t) devpriv->ANABuf.PhysicalBase + (devpriv->AdcItems << 2);
1547
1548
1549
1550
1551
1552 if (devpriv->ai_cmd_running == 1) {
1553 DEBUG("ResetADC: insert irq in ADC RPS task\n");
1554 *pRPS++ = RPS_IRQ;
1555 }
1556
1557 *pRPS++ = RPS_JUMP;
1558 *pRPS++ = (uint32_t) devpriv->RPSBuf.PhysicalBase;
1559
1560
1561}
1562
1563
1564static int s626_ai_insn_config(struct comedi_device *dev,
1565 struct comedi_subdevice *s,
1566 struct comedi_insn *insn, unsigned int *data)
1567{
1568
1569 return -EINVAL;
1570}
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602static int s626_ai_insn_read(struct comedi_device *dev,
1603 struct comedi_subdevice *s,
1604 struct comedi_insn *insn, unsigned int *data)
1605{
1606 uint16_t chan = CR_CHAN(insn->chanspec);
1607 uint16_t range = CR_RANGE(insn->chanspec);
1608 uint16_t AdcSpec = 0;
1609 uint32_t GpioImage;
1610 int n;
1611
1612
1613
1614
1615
1616
1617
1618 DEBUG("s626_ai_insn_read: entering\n");
1619
1620
1621
1622
1623 if (range == 0)
1624 AdcSpec = (chan << 8) | (GSEL_BIPOLAR5V);
1625 else
1626 AdcSpec = (chan << 8) | (GSEL_BIPOLAR10V);
1627
1628
1629 DEBIwrite(dev, LP_GSEL, AdcSpec);
1630
1631
1632 DEBIwrite(dev, LP_ISEL, AdcSpec);
1633
1634 for (n = 0; n < insn->n; n++) {
1635
1636
1637 udelay(10);
1638
1639
1640 GpioImage = RR7146(P_GPIO);
1641
1642 WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1643
1644 WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1645 WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1646
1647 WR7146(P_GPIO, GpioImage | GPIO1_HI);
1648
1649
1650
1651
1652
1653
1654 while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
1655
1656
1657 if (n != 0)
1658 data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668 udelay(4);
1669 }
1670
1671
1672
1673 GpioImage = RR7146(P_GPIO);
1674
1675
1676 WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1677
1678 WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1679 WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1680
1681 WR7146(P_GPIO, GpioImage | GPIO1_HI);
1682
1683
1684
1685
1686 while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
1687
1688
1689
1690
1691 if (n != 0)
1692 data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
1693
1694 DEBUG("s626_ai_insn_read: samples %d, data %d\n", n, data[n - 1]);
1695
1696 return n;
1697}
1698
1699static int s626_ai_load_polllist(uint8_t * ppl, struct comedi_cmd *cmd)
1700{
1701
1702 int n;
1703
1704 for (n = 0; n < cmd->chanlist_len; n++) {
1705 if (CR_RANGE((cmd->chanlist)[n]) == 0)
1706 ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_5V);
1707 else
1708 ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_10V);
1709 }
1710 if (n != 0)
1711 ppl[n - 1] |= EOPL;
1712
1713 return n;
1714}
1715
1716static int s626_ai_inttrig(struct comedi_device *dev,
1717 struct comedi_subdevice *s, unsigned int trignum)
1718{
1719 if (trignum != 0)
1720 return -EINVAL;
1721
1722 DEBUG("s626_ai_inttrig: trigger adc start...");
1723
1724
1725 MC_ENABLE(P_MC1, MC1_ERPS1);
1726
1727 s->async->inttrig = NULL;
1728
1729 DEBUG(" done\n");
1730
1731 return 1;
1732}
1733
1734
1735static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1736{
1737
1738 uint8_t ppl[16];
1739 struct comedi_cmd *cmd = &s->async->cmd;
1740 struct enc_private *k;
1741 int tick;
1742
1743 DEBUG("s626_ai_cmd: entering command function\n");
1744
1745 if (devpriv->ai_cmd_running) {
1746 printk("s626_ai_cmd: Another ai_cmd is running %d\n",
1747 dev->minor);
1748 return -EBUSY;
1749 }
1750
1751 writel(0, devpriv->base_addr + P_IER);
1752
1753
1754 writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->base_addr + P_ISR);
1755
1756
1757 s626_dio_clear_irq(dev);
1758
1759
1760
1761 devpriv->ai_cmd_running = 0;
1762
1763
1764 if (cmd == NULL) {
1765 DEBUG("s626_ai_cmd: NULL command\n");
1766 return -EINVAL;
1767 } else {
1768 DEBUG("s626_ai_cmd: command recieved!!!\n");
1769 }
1770
1771 if (dev->irq == 0) {
1772 comedi_error(dev,
1773 "s626_ai_cmd: cannot run command without an irq");
1774 return -EIO;
1775 }
1776
1777 s626_ai_load_polllist(ppl, cmd);
1778 devpriv->ai_cmd_running = 1;
1779 devpriv->ai_convert_count = 0;
1780
1781 switch (cmd->scan_begin_src) {
1782 case TRIG_FOLLOW:
1783 break;
1784 case TRIG_TIMER:
1785
1786 k = &encpriv[5];
1787 tick = s626_ns_to_timer((int *)&cmd->scan_begin_arg,
1788 cmd->flags & TRIG_ROUND_MASK);
1789
1790
1791 s626_timer_load(dev, k, tick);
1792 k->SetEnable(dev, k, CLKENAB_ALWAYS);
1793
1794 DEBUG("s626_ai_cmd: scan trigger timer is set with value %d\n",
1795 tick);
1796
1797 break;
1798 case TRIG_EXT:
1799
1800 if (cmd->start_src != TRIG_EXT)
1801 s626_dio_set_irq(dev, cmd->scan_begin_arg);
1802
1803 DEBUG("s626_ai_cmd: External scan trigger is set!!!\n");
1804
1805 break;
1806 }
1807
1808 switch (cmd->convert_src) {
1809 case TRIG_NOW:
1810 break;
1811 case TRIG_TIMER:
1812
1813 k = &encpriv[4];
1814 tick = s626_ns_to_timer((int *)&cmd->convert_arg,
1815 cmd->flags & TRIG_ROUND_MASK);
1816
1817
1818 s626_timer_load(dev, k, tick);
1819 k->SetEnable(dev, k, CLKENAB_INDEX);
1820
1821 DEBUG
1822 ("s626_ai_cmd: convert trigger timer is set with value %d\n",
1823 tick);
1824 break;
1825 case TRIG_EXT:
1826
1827 if (cmd->scan_begin_src != TRIG_EXT
1828 && cmd->start_src == TRIG_EXT)
1829 s626_dio_set_irq(dev, cmd->convert_arg);
1830
1831 DEBUG("s626_ai_cmd: External convert trigger is set!!!\n");
1832
1833 break;
1834 }
1835
1836 switch (cmd->stop_src) {
1837 case TRIG_COUNT:
1838
1839 devpriv->ai_sample_count = cmd->stop_arg;
1840 devpriv->ai_continous = 0;
1841 break;
1842 case TRIG_NONE:
1843
1844 devpriv->ai_continous = 1;
1845 devpriv->ai_sample_count = 0;
1846 break;
1847 }
1848
1849 ResetADC(dev, ppl);
1850
1851 switch (cmd->start_src) {
1852 case TRIG_NOW:
1853
1854
1855
1856
1857 MC_ENABLE(P_MC1, MC1_ERPS1);
1858
1859 DEBUG("s626_ai_cmd: ADC triggered\n");
1860 s->async->inttrig = NULL;
1861 break;
1862 case TRIG_EXT:
1863
1864 s626_dio_set_irq(dev, cmd->start_arg);
1865
1866 DEBUG("s626_ai_cmd: External start trigger is set!!!\n");
1867
1868 s->async->inttrig = NULL;
1869 break;
1870 case TRIG_INT:
1871 s->async->inttrig = s626_ai_inttrig;
1872 break;
1873 }
1874
1875
1876 writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER);
1877
1878 DEBUG("s626_ai_cmd: command function terminated\n");
1879
1880 return 0;
1881}
1882
1883static int s626_ai_cmdtest(struct comedi_device *dev,
1884 struct comedi_subdevice *s, struct comedi_cmd *cmd)
1885{
1886 int err = 0;
1887 int tmp;
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898 tmp = cmd->start_src;
1899 cmd->start_src &= TRIG_NOW | TRIG_INT | TRIG_EXT;
1900 if (!cmd->start_src || tmp != cmd->start_src)
1901 err++;
1902
1903 tmp = cmd->scan_begin_src;
1904 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
1905 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1906 err++;
1907
1908 tmp = cmd->convert_src;
1909 cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
1910 if (!cmd->convert_src || tmp != cmd->convert_src)
1911 err++;
1912
1913 tmp = cmd->scan_end_src;
1914 cmd->scan_end_src &= TRIG_COUNT;
1915 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1916 err++;
1917
1918 tmp = cmd->stop_src;
1919 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1920 if (!cmd->stop_src || tmp != cmd->stop_src)
1921 err++;
1922
1923 if (err)
1924 return 1;
1925
1926
1927
1928
1929
1930 if (cmd->scan_begin_src != TRIG_TIMER &&
1931 cmd->scan_begin_src != TRIG_EXT
1932 && cmd->scan_begin_src != TRIG_FOLLOW)
1933 err++;
1934 if (cmd->convert_src != TRIG_TIMER &&
1935 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
1936 err++;
1937 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1938 err++;
1939
1940 if (err)
1941 return 2;
1942
1943
1944
1945 if (cmd->start_src != TRIG_EXT && cmd->start_arg != 0) {
1946 cmd->start_arg = 0;
1947 err++;
1948 }
1949
1950 if (cmd->start_src == TRIG_EXT && cmd->start_arg > 39) {
1951 cmd->start_arg = 39;
1952 err++;
1953 }
1954
1955 if (cmd->scan_begin_src == TRIG_EXT && cmd->scan_begin_arg > 39) {
1956 cmd->scan_begin_arg = 39;
1957 err++;
1958 }
1959
1960 if (cmd->convert_src == TRIG_EXT && cmd->convert_arg > 39) {
1961 cmd->convert_arg = 39;
1962 err++;
1963 }
1964#define MAX_SPEED 200000
1965#define MIN_SPEED 2000000000
1966
1967 if (cmd->scan_begin_src == TRIG_TIMER) {
1968 if (cmd->scan_begin_arg < MAX_SPEED) {
1969 cmd->scan_begin_arg = MAX_SPEED;
1970 err++;
1971 }
1972 if (cmd->scan_begin_arg > MIN_SPEED) {
1973 cmd->scan_begin_arg = MIN_SPEED;
1974 err++;
1975 }
1976 } else {
1977
1978
1979
1980
1981
1982
1983
1984 }
1985 if (cmd->convert_src == TRIG_TIMER) {
1986 if (cmd->convert_arg < MAX_SPEED) {
1987 cmd->convert_arg = MAX_SPEED;
1988 err++;
1989 }
1990 if (cmd->convert_arg > MIN_SPEED) {
1991 cmd->convert_arg = MIN_SPEED;
1992 err++;
1993 }
1994 } else {
1995
1996
1997
1998
1999
2000
2001 }
2002
2003 if (cmd->scan_end_arg != cmd->chanlist_len) {
2004 cmd->scan_end_arg = cmd->chanlist_len;
2005 err++;
2006 }
2007 if (cmd->stop_src == TRIG_COUNT) {
2008 if (cmd->stop_arg > 0x00ffffff) {
2009 cmd->stop_arg = 0x00ffffff;
2010 err++;
2011 }
2012 } else {
2013
2014 if (cmd->stop_arg != 0) {
2015 cmd->stop_arg = 0;
2016 err++;
2017 }
2018 }
2019
2020 if (err)
2021 return 3;
2022
2023
2024
2025 if (cmd->scan_begin_src == TRIG_TIMER) {
2026 tmp = cmd->scan_begin_arg;
2027 s626_ns_to_timer((int *)&cmd->scan_begin_arg,
2028 cmd->flags & TRIG_ROUND_MASK);
2029 if (tmp != cmd->scan_begin_arg)
2030 err++;
2031 }
2032 if (cmd->convert_src == TRIG_TIMER) {
2033 tmp = cmd->convert_arg;
2034 s626_ns_to_timer((int *)&cmd->convert_arg,
2035 cmd->flags & TRIG_ROUND_MASK);
2036 if (tmp != cmd->convert_arg)
2037 err++;
2038 if (cmd->scan_begin_src == TRIG_TIMER &&
2039 cmd->scan_begin_arg <
2040 cmd->convert_arg * cmd->scan_end_arg) {
2041 cmd->scan_begin_arg =
2042 cmd->convert_arg * cmd->scan_end_arg;
2043 err++;
2044 }
2045 }
2046
2047 if (err)
2048 return 4;
2049
2050 return 0;
2051}
2052
2053static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
2054{
2055
2056 MC_DISABLE(P_MC1, MC1_ERPS1);
2057
2058
2059 writel(0, devpriv->base_addr + P_IER);
2060
2061 devpriv->ai_cmd_running = 0;
2062
2063 return 0;
2064}
2065
2066
2067
2068
2069
2070
2071static int s626_ns_to_timer(int *nanosec, int round_mode)
2072{
2073 int divider, base;
2074
2075 base = 500;
2076
2077 switch (round_mode) {
2078 case TRIG_ROUND_NEAREST:
2079 default:
2080 divider = (*nanosec + base / 2) / base;
2081 break;
2082 case TRIG_ROUND_DOWN:
2083 divider = (*nanosec) / base;
2084 break;
2085 case TRIG_ROUND_UP:
2086 divider = (*nanosec + base - 1) / base;
2087 break;
2088 }
2089
2090 *nanosec = base * divider;
2091 return divider - 1;
2092}
2093
2094static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
2095 struct comedi_insn *insn, unsigned int *data)
2096{
2097
2098 int i;
2099 uint16_t chan = CR_CHAN(insn->chanspec);
2100 int16_t dacdata;
2101
2102 for (i = 0; i < insn->n; i++) {
2103 dacdata = (int16_t) data[i];
2104 devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[i];
2105 dacdata -= (0x1fff);
2106
2107 SetDAC(dev, chan, dacdata);
2108 }
2109
2110 return i;
2111}
2112
2113static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
2114 struct comedi_insn *insn, unsigned int *data)
2115{
2116 int i;
2117
2118 for (i = 0; i < insn->n; i++)
2119 data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
2120
2121 return i;
2122}
2123
2124
2125
2126
2127
2128
2129
2130static void s626_dio_init(struct comedi_device *dev)
2131{
2132 uint16_t group;
2133 struct comedi_subdevice *s;
2134
2135
2136 DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
2137
2138
2139 for (group = 0; group < S626_DIO_BANKS; group++) {
2140 s = dev->subdevices + 2 + group;
2141 DEBIwrite(dev, diopriv->WRIntSel, 0);
2142 DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF);
2143
2144 DEBIwrite(dev, diopriv->WREdgSel, 0);
2145
2146
2147 DEBIwrite(dev, diopriv->WRDOut, 0);
2148
2149 }
2150 DEBUG("s626_dio_init: DIO initialized \n");
2151}
2152
2153
2154
2155
2156
2157
2158
2159static int s626_dio_insn_bits(struct comedi_device *dev,
2160 struct comedi_subdevice *s,
2161 struct comedi_insn *insn, unsigned int *data)
2162{
2163
2164
2165 if (insn->n == 0)
2166 return 0;
2167
2168 if (insn->n != 2) {
2169 printk
2170 ("comedi%d: s626: s626_dio_insn_bits(): Invalid instruction length\n",
2171 dev->minor);
2172 return -EINVAL;
2173 }
2174
2175
2176
2177
2178
2179
2180
2181 if (data[0]) {
2182
2183 if ((s->io_bits & data[0]) != data[0])
2184 return -EIO;
2185
2186 s->state &= ~data[0];
2187 s->state |= data[0] & data[1];
2188
2189
2190
2191 DEBIwrite(dev, diopriv->WRDOut, s->state);
2192 }
2193 data[1] = DEBIread(dev, diopriv->RDDIn);
2194
2195 return 2;
2196}
2197
2198static int s626_dio_insn_config(struct comedi_device *dev,
2199 struct comedi_subdevice *s,
2200 struct comedi_insn *insn, unsigned int *data)
2201{
2202
2203 switch (data[0]) {
2204 case INSN_CONFIG_DIO_QUERY:
2205 data[1] =
2206 (s->
2207 io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
2208 COMEDI_INPUT;
2209 return insn->n;
2210 break;
2211 case COMEDI_INPUT:
2212 s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
2213 break;
2214 case COMEDI_OUTPUT:
2215 s->io_bits |= 1 << CR_CHAN(insn->chanspec);
2216 break;
2217 default:
2218 return -EINVAL;
2219 break;
2220 }
2221 DEBIwrite(dev, diopriv->WRDOut, s->io_bits);
2222
2223 return 1;
2224}
2225
2226static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
2227{
2228 unsigned int group;
2229 unsigned int bitmask;
2230 unsigned int status;
2231
2232
2233 group = chan / 16;
2234 bitmask = 1 << (chan - (16 * group));
2235 DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n",
2236 chan - (16 * group), group);
2237
2238
2239 status = DEBIread(dev,
2240 ((struct dio_private *)(dev->subdevices + 2 +
2241 group)->private)->RDEdgSel);
2242 DEBIwrite(dev,
2243 ((struct dio_private *)(dev->subdevices + 2 +
2244 group)->private)->WREdgSel,
2245 bitmask | status);
2246
2247
2248 status = DEBIread(dev,
2249 ((struct dio_private *)(dev->subdevices + 2 +
2250 group)->private)->RDIntSel);
2251 DEBIwrite(dev,
2252 ((struct dio_private *)(dev->subdevices + 2 +
2253 group)->private)->WRIntSel,
2254 bitmask | status);
2255
2256
2257 DEBIwrite(dev, LP_MISC1, MISC1_EDCAP);
2258
2259
2260 status = DEBIread(dev,
2261 ((struct dio_private *)(dev->subdevices + 2 +
2262 group)->private)->RDCapSel);
2263 DEBIwrite(dev,
2264 ((struct dio_private *)(dev->subdevices + 2 +
2265 group)->private)->WRCapSel,
2266 bitmask | status);
2267
2268 return 0;
2269}
2270
2271static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
2272 unsigned int mask)
2273{
2274 DEBUG
2275 ("s626_dio_reset_irq: disable interrupt on dio channel %d group %d\n",
2276 mask, group);
2277
2278
2279 DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
2280
2281
2282 DEBIwrite(dev,
2283 ((struct dio_private *)(dev->subdevices + 2 +
2284 group)->private)->WRCapSel, mask);
2285
2286 return 0;
2287}
2288
2289static int s626_dio_clear_irq(struct comedi_device *dev)
2290{
2291 unsigned int group;
2292
2293
2294 DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
2295
2296 for (group = 0; group < S626_DIO_BANKS; group++) {
2297
2298 DEBIwrite(dev,
2299 ((struct dio_private *)(dev->subdevices + 2 +
2300 group)->private)->WRCapSel,
2301 0xffff);
2302 }
2303
2304 return 0;
2305}
2306
2307
2308
2309
2310static int s626_enc_insn_config(struct comedi_device *dev,
2311 struct comedi_subdevice *s,
2312 struct comedi_insn *insn, unsigned int *data)
2313{
2314 uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) |
2315
2316 (INDXSRC_SOFT << BF_INDXSRC) |
2317 (CLKSRC_COUNTER << BF_CLKSRC) |
2318 (CLKPOL_POS << BF_CLKPOL) |
2319
2320 (CLKMULT_1X << BF_CLKMULT) |
2321 (CLKENAB_INDEX << BF_CLKENAB);
2322
2323
2324 uint16_t valueSrclatch = LATCHSRC_AB_READ;
2325 uint16_t enab = CLKENAB_ALWAYS;
2326 struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
2327
2328 DEBUG("s626_enc_insn_config: encoder config\n");
2329
2330
2331
2332 k->SetMode(dev, k, Setup, TRUE);
2333 Preload(dev, k, *(insn->data));
2334 k->PulseIndex(dev, k);
2335 SetLatchSource(dev, k, valueSrclatch);
2336 k->SetEnable(dev, k, (uint16_t) (enab != 0));
2337
2338 return insn->n;
2339}
2340
2341static int s626_enc_insn_read(struct comedi_device *dev,
2342 struct comedi_subdevice *s,
2343 struct comedi_insn *insn, unsigned int *data)
2344{
2345
2346 int n;
2347 struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
2348
2349 DEBUG("s626_enc_insn_read: encoder read channel %d \n",
2350 CR_CHAN(insn->chanspec));
2351
2352 for (n = 0; n < insn->n; n++)
2353 data[n] = ReadLatch(dev, k);
2354
2355 DEBUG("s626_enc_insn_read: encoder sample %d\n", data[n]);
2356
2357 return n;
2358}
2359
2360static int s626_enc_insn_write(struct comedi_device *dev,
2361 struct comedi_subdevice *s,
2362 struct comedi_insn *insn, unsigned int *data)
2363{
2364
2365 struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
2366
2367 DEBUG("s626_enc_insn_write: encoder write channel %d \n",
2368 CR_CHAN(insn->chanspec));
2369
2370
2371 Preload(dev, k, data[0]);
2372
2373
2374
2375 k->SetLoadTrig(dev, k, 0);
2376 k->PulseIndex(dev, k);
2377 k->SetLoadTrig(dev, k, 2);
2378
2379 DEBUG("s626_enc_insn_write: End encoder write\n");
2380
2381 return 1;
2382}
2383
2384static void s626_timer_load(struct comedi_device *dev, struct enc_private *k,
2385 int tick)
2386{
2387 uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) |
2388
2389 (INDXSRC_SOFT << BF_INDXSRC) |
2390 (CLKSRC_TIMER << BF_CLKSRC) |
2391 (CLKPOL_POS << BF_CLKPOL) |
2392 (CNTDIR_DOWN << BF_CLKPOL) |
2393 (CLKMULT_1X << BF_CLKMULT) |
2394 (CLKENAB_INDEX << BF_CLKENAB);
2395 uint16_t valueSrclatch = LATCHSRC_A_INDXA;
2396
2397
2398 k->SetMode(dev, k, Setup, FALSE);
2399
2400
2401 Preload(dev, k, tick);
2402
2403
2404
2405 k->SetLoadTrig(dev, k, 0);
2406 k->PulseIndex(dev, k);
2407
2408
2409 k->SetLoadTrig(dev, k, 1);
2410
2411
2412 k->SetIntSrc(dev, k, INTSRC_OVER);
2413
2414 SetLatchSource(dev, k, valueSrclatch);
2415
2416}
2417
2418
2419
2420
2421#define VECT0 (XSD2 | RSD3 | SIB_A2)
2422
2423
2424
2425static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
2426
2427
2428static uint8_t trimadrs[] =
2429 { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
2430
2431static void LoadTrimDACs(struct comedi_device *dev)
2432{
2433 register uint8_t i;
2434
2435
2436 for (i = 0; i < ARRAY_SIZE(trimchan); i++)
2437 WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i]));
2438}
2439
2440static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
2441 uint8_t DacData)
2442{
2443 uint32_t chan;
2444
2445
2446 devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData;
2447
2448
2449 chan = (uint32_t) trimchan[LogicalChan];
2450
2451
2452
2453
2454
2455
2456 SETVECT(2, XSD2 | XFIFO_1 | WS3);
2457
2458 SETVECT(3, XSD2 | XFIFO_0 | WS3);
2459
2460 SETVECT(4, XSD2 | XFIFO_3 | WS1);
2461
2462 SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS);
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474 SendDAC(dev, ((uint32_t) chan << 8)
2475 | (uint32_t) DacData);
2476}
2477
2478
2479
2480
2481static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
2482{
2483 uint8_t rtnval;
2484
2485
2486 if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW)
2487
2488 | I2C_B1(I2C_ATTRSTOP, addr)
2489
2490 | I2C_B0(I2C_ATTRNOP, 0))) {
2491
2492 DEBUG("I2Cread: error handshake I2Cread a\n");
2493 return 0;
2494 }
2495
2496 if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR)
2497
2498
2499
2500
2501
2502 |I2C_B1(I2C_ATTRSTOP, 0)
2503
2504
2505
2506
2507 |I2C_B0(I2C_ATTRNOP, 0))) {
2508
2509
2510 DEBUG("I2Cread: error handshake I2Cread b\n");
2511 return 0;
2512 }
2513
2514 rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16);
2515 return rtnval;
2516}
2517
2518static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
2519{
2520
2521 WR7146(P_I2CCTRL, val);
2522
2523
2524
2525
2526 MC_ENABLE(P_MC2, MC2_UPLD_IIC);
2527 while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ;
2528
2529
2530 while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) ;
2531
2532
2533 return RR7146(P_I2CCTRL) & I2C_ERR;
2534
2535}
2536
2537
2538
2539static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
2540{
2541 register uint16_t signmask;
2542 register uint32_t WSImage;
2543
2544
2545
2546 signmask = 1 << chan;
2547 if (dacdata < 0) {
2548 dacdata = -dacdata;
2549 devpriv->Dacpol |= signmask;
2550 } else
2551 devpriv->Dacpol &= ~signmask;
2552
2553
2554 if ((uint16_t) dacdata > 0x1FFF)
2555 dacdata = 0x1FFF;
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567 WSImage = (chan & 2) ? WS1 : WS2;
2568
2569 SETVECT(2, XSD2 | XFIFO_1 | WSImage);
2570
2571 SETVECT(3, XSD2 | XFIFO_0 | WSImage);
2572
2573 SETVECT(4, XSD2 | XFIFO_3 | WS3);
2574
2575 SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS);
2576
2577
2578
2579
2580
2581
2582
2583
2584 SendDAC(dev, 0x0F000000
2585
2586 | 0x00004000
2587
2588
2589 | ((uint32_t) (chan & 1) << 15)
2590
2591 | (uint32_t) dacdata);
2592
2593}
2594
2595
2596
2597
2598
2599
2600static void SendDAC(struct comedi_device *dev, uint32_t val)
2601{
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614 DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol);
2615
2616
2617
2618
2619
2620
2621 *devpriv->pDacWBuf = val;
2622
2623
2624
2625
2626
2627
2628 MC_ENABLE(P_MC1, MC1_A2OUT);
2629
2630
2631
2632
2633
2634
2635
2636 WR7146(P_ISR, ISR_AFOU);
2637
2638
2639
2640
2641
2642
2643
2644 while ((RR7146(P_MC1) & MC1_A2OUT) != 0) ;
2645
2646
2647
2648
2649
2650
2651
2652
2653 SETVECT(0, XSD2 | RSD3 | SIB_A2);
2654
2655
2656
2657
2658
2659
2660
2661 while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0) ;
2662
2663
2664
2665
2666
2667
2668
2669 SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS);
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690 if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) {
2691
2692
2693
2694
2695
2696
2697 while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) ;
2698 }
2699
2700
2701
2702
2703
2704
2705
2706
2707 SETVECT(0, RSD3 | SIB_A2 | EOS);
2708
2709
2710
2711
2712
2713 while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) ;
2714}
2715
2716static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage)
2717{
2718 DEBIwrite(dev, LP_MISC1, MISC1_WENABLE);
2719
2720 DEBIwrite(dev, LP_WRMISC2, NewImage);
2721 DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE);
2722}
2723
2724
2725
2726static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr)
2727{
2728 uint16_t retval;
2729
2730
2731 WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
2732
2733
2734 DEBItransfer(dev);
2735
2736
2737 retval = (uint16_t) RR7146(P_DEBIAD);
2738
2739
2740 return retval;
2741}
2742
2743
2744
2745static void DEBItransfer(struct comedi_device *dev)
2746{
2747
2748 MC_ENABLE(P_MC2, MC2_UPLD_DEBI);
2749
2750
2751
2752 while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) ;
2753
2754
2755 while (RR7146(P_PSR) & PSR_DEBI_S) ;
2756}
2757
2758
2759static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
2760{
2761
2762
2763 WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
2764 WR7146(P_DEBIAD, wdata);
2765
2766
2767 DEBItransfer(dev);
2768}
2769
2770
2771
2772
2773
2774static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
2775 uint16_t wdata)
2776{
2777
2778
2779 WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
2780
2781 DEBItransfer(dev);
2782
2783
2784 WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
2785
2786
2787 WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask));
2788
2789 DEBItransfer(dev);
2790}
2791
2792static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
2793 size_t bsize)
2794{
2795 void *vbptr;
2796 dma_addr_t vpptr;
2797
2798 DEBUG("CloseDMAB: Entering S626DRV_CloseDMAB():\n");
2799 if (pdma == NULL)
2800 return;
2801
2802
2803 vbptr = pdma->LogicalBase;
2804 vpptr = pdma->PhysicalBase;
2805 if (vbptr) {
2806 pci_free_consistent(devpriv->pdev, bsize, vbptr, vpptr);
2807 pdma->LogicalBase = 0;
2808 pdma->PhysicalBase = 0;
2809
2810 DEBUG("CloseDMAB(): Logical=%p, bsize=%d, Physical=0x%x\n",
2811 vbptr, bsize, (uint32_t) vpptr);
2812 }
2813}
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k)
2829{
2830 register uint32_t value;
2831
2832
2833
2834 value = (uint32_t) DEBIread(dev, k->MyLatchLsw);
2835
2836
2837 value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16);
2838
2839
2840
2841
2842 return value;
2843}
2844
2845
2846
2847static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k)
2848{
2849 DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
2850 CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
2851}
2852
2853static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k)
2854{
2855 DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
2856 CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B);
2857}
2858
2859
2860
2861
2862static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k)
2863{
2864 register uint16_t cra;
2865 register uint16_t crb;
2866 register uint16_t setup;
2867
2868
2869 cra = DEBIread(dev, k->MyCRA);
2870 crb = DEBIread(dev, k->MyCRB);
2871
2872
2873
2874 setup = ((cra & STDMSK_LOADSRC)
2875 |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)
2876 |((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC)
2877 |((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC)
2878 |((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL)
2879 |((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB));
2880
2881
2882 if (cra & (2 << CRABIT_CLKSRC_A))
2883 setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)
2884 |((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL)
2885 |(MULT_X1 << STDBIT_CLKMULT));
2886
2887 else
2888 setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)
2889 |((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL)
2890 |(((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ?
2891 (MULT_X1 << STDBIT_CLKMULT) :
2892 ((cra >> (CRABIT_CLKMULT_A -
2893 STDBIT_CLKMULT)) & STDMSK_CLKMULT)));
2894
2895
2896 return setup;
2897}
2898
2899static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k)
2900{
2901 register uint16_t cra;
2902 register uint16_t crb;
2903 register uint16_t setup;
2904
2905
2906 cra = DEBIread(dev, k->MyCRA);
2907 crb = DEBIread(dev, k->MyCRB);
2908
2909
2910
2911 setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC)
2912 |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)
2913 |((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC)
2914 |((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL)
2915 |((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB)
2916 |((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC));
2917
2918
2919 if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B))
2920 setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC)
2921 |(MULT_X1 << STDBIT_CLKMULT)
2922 |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));
2923
2924 else if (cra & (2 << CRABIT_CLKSRC_B))
2925 setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)
2926 |(MULT_X1 << STDBIT_CLKMULT)
2927 |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));
2928
2929 else
2930 setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)
2931 |((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT)
2932 |((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL));
2933
2934
2935 return setup;
2936}
2937
2938
2939
2940
2941
2942
2943
2944
2945static void SetMode_A(struct comedi_device *dev, struct enc_private *k,
2946 uint16_t Setup, uint16_t DisableIntSrc)
2947{
2948 register uint16_t cra;
2949 register uint16_t crb;
2950 register uint16_t setup = Setup;
2951
2952
2953 cra = ((setup & CRAMSK_LOADSRC_A)
2954 |((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))));
2955
2956 crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A
2957 | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)));
2958
2959
2960 if (!DisableIntSrc)
2961 cra |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
2962 CRABIT_INTSRC_A));
2963
2964
2965 switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
2966 case CLKSRC_EXTENDER:
2967
2968
2969 case CLKSRC_TIMER:
2970 cra |= ((2 << CRABIT_CLKSRC_A)
2971 |((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A))
2972 |(1 << CRABIT_CLKPOL_A)
2973 |(MULT_X1 << CRABIT_CLKMULT_A));
2974 break;
2975
2976 default:
2977 cra |= (CLKSRC_COUNTER
2978 | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL))
2979 |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?
2980 (MULT_X1 << CRABIT_CLKMULT_A) :
2981 ((setup & STDMSK_CLKMULT) << (CRABIT_CLKMULT_A -
2982 STDBIT_CLKMULT))));
2983 }
2984
2985
2986
2987 if (~setup & STDMSK_INDXSRC)
2988 cra |= ((setup & STDMSK_INDXPOL) << (CRABIT_INDXPOL_A -
2989 STDBIT_INDXPOL));
2990
2991
2992
2993 if (DisableIntSrc)
2994 devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
2995
2996
2997
2998 DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra);
2999 DEBIreplace(dev, k->MyCRB,
3000 (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), crb);
3001}
3002
3003static void SetMode_B(struct comedi_device *dev, struct enc_private *k,
3004 uint16_t Setup, uint16_t DisableIntSrc)
3005{
3006 register uint16_t cra;
3007 register uint16_t crb;
3008 register uint16_t setup = Setup;
3009
3010
3011 cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC));
3012
3013 crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B
3014 | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB))
3015 |((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)));
3016
3017
3018 if (!DisableIntSrc)
3019 crb |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
3020 CRBBIT_INTSRC_B));
3021
3022
3023 switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
3024 case CLKSRC_TIMER:
3025 cra |= ((2 << CRABIT_CLKSRC_B)
3026 |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));
3027 crb |= ((1 << CRBBIT_CLKPOL_B)
3028 |(MULT_X1 << CRBBIT_CLKMULT_B));
3029 break;
3030
3031 case CLKSRC_EXTENDER:
3032 cra |= ((2 << CRABIT_CLKSRC_B)
3033 |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));
3034 crb |= ((1 << CRBBIT_CLKPOL_B)
3035 |(MULT_X0 << CRBBIT_CLKMULT_B));
3036 break;
3037
3038 default:
3039 cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B);
3040 crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B))
3041 |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?
3042 (MULT_X1 << CRBBIT_CLKMULT_B) :
3043 ((setup & STDMSK_CLKMULT) << (CRBBIT_CLKMULT_B -
3044 STDBIT_CLKMULT))));
3045 }
3046
3047
3048
3049 if (~setup & STDMSK_INDXSRC)
3050 crb |= ((setup & STDMSK_INDXPOL) >> (STDBIT_INDXPOL -
3051 CRBBIT_INDXPOL_B));
3052
3053
3054
3055 if (DisableIntSrc)
3056 devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
3057
3058
3059
3060 DEBIreplace(dev, k->MyCRA,
3061 (uint16_t) (~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B)), cra);
3062 DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb);
3063}
3064
3065
3066
3067static void SetEnable_A(struct comedi_device *dev, struct enc_private *k,
3068 uint16_t enab)
3069{
3070 DEBUG("SetEnable_A: SetEnable_A enter 3541\n");
3071 DEBIreplace(dev, k->MyCRB,
3072 (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)),
3073 (uint16_t) (enab << CRBBIT_CLKENAB_A));
3074}
3075
3076static void SetEnable_B(struct comedi_device *dev, struct enc_private *k,
3077 uint16_t enab)
3078{
3079 DEBIreplace(dev, k->MyCRB,
3080 (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)),
3081 (uint16_t) (enab << CRBBIT_CLKENAB_B));
3082}
3083
3084static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k)
3085{
3086 return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_A) & 1;
3087}
3088
3089static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k)
3090{
3091 return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_B) & 1;
3092}
3093
3094
3095
3096
3097
3098
3099static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
3100 uint16_t value)
3101{
3102 DEBUG("SetLatchSource: SetLatchSource enter 3550 \n");
3103 DEBIreplace(dev, k->MyCRB,
3104 (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)),
3105 (uint16_t) (value << CRBBIT_LATCHSRC));
3106
3107 DEBUG("SetLatchSource: SetLatchSource exit \n");
3108}
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k,
3124 uint16_t Trig)
3125{
3126 DEBIreplace(dev, k->MyCRA, (uint16_t) (~CRAMSK_LOADSRC_A),
3127 (uint16_t) (Trig << CRABIT_LOADSRC_A));
3128}
3129
3130static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k,
3131 uint16_t Trig)
3132{
3133 DEBIreplace(dev, k->MyCRB,
3134 (uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)),
3135 (uint16_t) (Trig << CRBBIT_LOADSRC_B));
3136}
3137
3138static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k)
3139{
3140 return (DEBIread(dev, k->MyCRA) >> CRABIT_LOADSRC_A) & 3;
3141}
3142
3143static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k)
3144{
3145 return (DEBIread(dev, k->MyCRB) >> CRBBIT_LOADSRC_B) & 3;
3146}
3147
3148
3149
3150
3151
3152
3153static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
3154 uint16_t IntSource)
3155{
3156
3157 DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
3158 CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
3159
3160
3161 DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A,
3162 (uint16_t) (IntSource << CRABIT_INTSRC_A));
3163
3164
3165 devpriv->CounterIntEnabs =
3166 (devpriv->CounterIntEnabs & ~k->
3167 MyEventBits[3]) | k->MyEventBits[IntSource];
3168}
3169
3170static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
3171 uint16_t IntSource)
3172{
3173 uint16_t crb;
3174
3175
3176 crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;
3177
3178
3179 DEBIwrite(dev, k->MyCRB,
3180 (uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B));
3181
3182
3183 DEBIwrite(dev, k->MyCRB,
3184 (uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource <<
3185 CRBBIT_INTSRC_B)));
3186
3187
3188 devpriv->CounterIntEnabs =
3189 (devpriv->CounterIntEnabs & ~k->
3190 MyEventBits[3]) | k->MyEventBits[IntSource];
3191}
3192
3193static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k)
3194{
3195 return (DEBIread(dev, k->MyCRA) >> CRABIT_INTSRC_A) & 3;
3196}
3197
3198static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k)
3199{
3200 return (DEBIread(dev, k->MyCRB) >> CRBBIT_INTSRC_B) & 3;
3201}
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k)
3267{
3268 register uint16_t cra;
3269
3270 DEBUG("PulseIndex_A: pulse index enter\n");
3271
3272 cra = DEBIread(dev, k->MyCRA);
3273 DEBIwrite(dev, k->MyCRA, (uint16_t) (cra ^ CRAMSK_INDXPOL_A));
3274 DEBUG("PulseIndex_A: pulse index step1\n");
3275 DEBIwrite(dev, k->MyCRA, cra);
3276}
3277
3278static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k)
3279{
3280 register uint16_t crb;
3281
3282 crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;
3283 DEBIwrite(dev, k->MyCRB, (uint16_t) (crb ^ CRBMSK_INDXPOL_B));
3284 DEBIwrite(dev, k->MyCRB, crb);
3285}
3286
3287
3288
3289static void Preload(struct comedi_device *dev, struct enc_private *k,
3290 uint32_t value)
3291{
3292 DEBUG("Preload: preload enter\n");
3293 DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value);
3294 DEBUG("Preload: preload step 1\n");
3295 DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2),
3296 (uint16_t) (value >> 16));
3297}
3298
3299static void CountersInit(struct comedi_device *dev)
3300{
3301 int chan;
3302 struct enc_private *k;
3303 uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) |
3304
3305 (INDXSRC_SOFT << BF_INDXSRC) |
3306 (CLKSRC_COUNTER << BF_CLKSRC) |
3307 (CLKPOL_POS << BF_CLKPOL) |
3308 (CNTDIR_UP << BF_CLKPOL) |
3309 (CLKMULT_1X << BF_CLKMULT) |
3310 (CLKENAB_INDEX << BF_CLKENAB);
3311
3312
3313 for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
3314 k = &encpriv[chan];
3315 k->SetMode(dev, k, Setup, TRUE);
3316 k->SetIntSrc(dev, k, 0);
3317 k->ResetCapFlags(dev, k);
3318 k->SetEnable(dev, k, CLKENAB_ALWAYS);
3319 }
3320 DEBUG("CountersInit: counters initialized \n");
3321
3322}
3323