ae11fb7af323278a383475e686044a16a68f3b75
[deliverable/linux.git] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci3xxx.c
1 /**
2 @verbatim
3
4 Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
5
6 ADDI-DATA GmbH
7 Dieselstrasse 3
8 D-77833 Ottersweier
9 Tel: +19(0)7223/9493-0
10 Fax: +49(0)7223/9493-92
11 http://www.addi-data-com
12 info@addi-data.com
13
14 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 You shoud also find the complete GPL in the COPYING file accompanying this source code.
21
22 @endverbatim
23 */
24 /*
25 +-----------------------------------------------------------------------+
26 | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
27 +-----------------------------------------------------------------------+
28 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
29 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
30 +-----------------------------------------------------------------------+
31 | Project : APCI-3XXX | Compiler : GCC |
32 | Module name : hwdrv_apci3xxx.c| Version : 2.96 |
33 +-------------------------------+---------------------------------------+
34 | Project manager: S. Weber | Date : 15/09/2005 |
35 +-----------------------------------------------------------------------+
36 | Description :APCI3XXX Module. Hardware abstraction Layer for APCI3XXX|
37 +-----------------------------------------------------------------------+
38 | UPDATE'S |
39 +-----------------------------------------------------------------------+
40 | Date | Author | Description of updates |
41 +----------+-----------+------------------------------------------------+
42 | | | |
43 | | | |
44 +----------+-----------+------------------------------------------------+
45 */
46
47 #include "hwdrv_apci3xxx.h"
48
49 /*
50 +----------------------------------------------------------------------------+
51 | ANALOG INPUT FUNCTIONS |
52 +----------------------------------------------------------------------------+
53 */
54
55 /*
56 +----------------------------------------------------------------------------+
57 | Function Name : INT i_APCI3XXX_TestConversionStarted |
58 | (struct comedi_device *dev) |
59 +----------------------------------------------------------------------------+
60 | Task Test if any conversion started |
61 +----------------------------------------------------------------------------+
62 | Input Parameters : - |
63 +----------------------------------------------------------------------------+
64 | Output Parameters : - |
65 +----------------------------------------------------------------------------+
66 | Return Value : 0 : Conversion not started |
67 | 1 : Conversion started |
68 +----------------------------------------------------------------------------+
69 */
70
71 int i_APCI3XXX_TestConversionStarted(struct comedi_device * dev)
72 {
73 if ((readl((void *)(devpriv->dw_AiBase + 8)) & 0x80000UL) == 0x80000UL) {
74 return (1);
75 } else {
76 return (0);
77 }
78 }
79
80 /*
81 +----------------------------------------------------------------------------+
82 | Function Name : INT i_APCI3XXX_AnalogInputConfigOperatingMode |
83 | (struct comedi_device *dev, |
84 | struct comedi_subdevice *s, |
85 | comedi_insn *insn, |
86 | unsigned int *data) |
87 +----------------------------------------------------------------------------+
88 | Task Converting mode and convert time selection |
89 +----------------------------------------------------------------------------+
90 | Input Parameters : b_SingleDiff = (BYTE) data[1]; |
91 | b_TimeBase = (BYTE) data[2]; (0: ns, 1:micros 2:ms)|
92 | dw_ReloadValue = (DWORD) data[3]; |
93 | ........ |
94 +----------------------------------------------------------------------------+
95 | Output Parameters : - |
96 +----------------------------------------------------------------------------+
97 | Return Value :>0 : No error |
98 | -1 : Single/Diff selection error |
99 | -2 : Convert time base unity selection error |
100 | -3 : Convert time value selection error |
101 | -10: Any conversion started |
102 | .... |
103 | -100 : Config command error |
104 | -101 : Data size error |
105 +----------------------------------------------------------------------------+
106 */
107
108 int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device * dev,
109 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
110 {
111 INT i_ReturnValue = insn->n;
112 BYTE b_TimeBase = 0;
113 BYTE b_SingleDiff = 0;
114 DWORD dw_ReloadValue = 0;
115 DWORD dw_TestReloadValue = 0;
116
117 /************************/
118 /* Test the buffer size */
119 /************************/
120
121 if (insn->n == 4) {
122 /****************************/
123 /* Get the Singel/Diff flag */
124 /****************************/
125
126 b_SingleDiff = (BYTE) data[1];
127
128 /****************************/
129 /* Get the time base unitiy */
130 /****************************/
131
132 b_TimeBase = (BYTE) data[2];
133
134 /*************************************/
135 /* Get the convert time reload value */
136 /*************************************/
137
138 dw_ReloadValue = (DWORD) data[3];
139
140 /**********************/
141 /* Test the time base */
142 /**********************/
143
144 if ((devpriv->ps_BoardInfo->
145 b_AvailableConvertUnit & (1 << b_TimeBase)) !=
146 0) {
147 /*******************************/
148 /* Test the convert time value */
149 /*******************************/
150
151 if ((dw_ReloadValue >= 0) && (dw_ReloadValue <= 65535)) {
152 dw_TestReloadValue = dw_ReloadValue;
153
154 if (b_TimeBase == 1) {
155 dw_TestReloadValue =
156 dw_TestReloadValue * 1000UL;
157 }
158 if (b_TimeBase == 2) {
159 dw_TestReloadValue =
160 dw_TestReloadValue * 1000000UL;
161 }
162
163 /*******************************/
164 /* Test the convert time value */
165 /*******************************/
166
167 if (dw_TestReloadValue >=
168 devpriv->ps_BoardInfo->
169 ui_MinAcquisitiontimeNs) {
170 if ((b_SingleDiff == APCI3XXX_SINGLE)
171 || (b_SingleDiff ==
172 APCI3XXX_DIFF)) {
173 if (((b_SingleDiff == APCI3XXX_SINGLE) && (devpriv->ps_BoardInfo->i_NbrAiChannel == 0)) || ((b_SingleDiff == APCI3XXX_DIFF) && (devpriv->ps_BoardInfo->i_NbrAiChannelDiff == 0))) {
174 /*******************************/
175 /* Single/Diff selection error */
176 /*******************************/
177
178 printk("Single/Diff selection error\n");
179 i_ReturnValue = -1;
180 } else {
181 /**********************************/
182 /* Test if conversion not started */
183 /**********************************/
184
185 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
186 devpriv->
187 ui_EocEosConversionTime
188 =
189 (UINT)
190 dw_ReloadValue;
191 devpriv->
192 b_EocEosConversionTimeBase
193 =
194 b_TimeBase;
195 devpriv->
196 b_SingelDiff
197 =
198 b_SingleDiff;
199 devpriv->
200 b_AiInitialisation
201 = 1;
202
203 /*******************************/
204 /* Set the convert timing unit */
205 /*******************************/
206
207 writel((DWORD)
208 b_TimeBase,
209 (void *)
210 (devpriv->
211 dw_AiBase
212 +
213 36));
214
215 /**************************/
216 /* Set the convert timing */
217 /*************************/
218
219 writel(dw_ReloadValue, (void *)(devpriv->dw_AiBase + 32));
220 } else {
221 /**************************/
222 /* Any conversion started */
223 /**************************/
224
225 printk("Any conversion started\n");
226 i_ReturnValue =
227 -10;
228 }
229 }
230 } else {
231 /*******************************/
232 /* Single/Diff selection error */
233 /*******************************/
234
235 printk("Single/Diff selection error\n");
236 i_ReturnValue = -1;
237 }
238 } else {
239 /************************/
240 /* Time selection error */
241 /************************/
242
243 printk("Convert time value selection error\n");
244 i_ReturnValue = -3;
245 }
246 } else {
247 /************************/
248 /* Time selection error */
249 /************************/
250
251 printk("Convert time value selection error\n");
252 i_ReturnValue = -3;
253 }
254 } else {
255 /*****************************/
256 /* Time base selection error */
257 /*****************************/
258
259 printk("Convert time base unity selection error\n");
260 i_ReturnValue = -2;
261 }
262 } else {
263 /*******************/
264 /* Data size error */
265 /*******************/
266
267 printk("Buffer size error\n");
268 i_ReturnValue = -101;
269 }
270
271 return (i_ReturnValue);
272 }
273
274 /*
275 +----------------------------------------------------------------------------+
276 | Function Name : INT i_APCI3XXX_InsnConfigAnalogInput |
277 | (struct comedi_device *dev, |
278 | struct comedi_subdevice *s, |
279 | comedi_insn *insn, |
280 | unsigned int *data) |
281 +----------------------------------------------------------------------------+
282 | Task Converting mode and convert time selection |
283 +----------------------------------------------------------------------------+
284 | Input Parameters : b_ConvertMode = (BYTE) data[0]; |
285 | b_TimeBase = (BYTE) data[1]; (0: ns, 1:micros 2:ms)|
286 | dw_ReloadValue = (DWORD) data[2]; |
287 | ........ |
288 +----------------------------------------------------------------------------+
289 | Output Parameters : - |
290 +----------------------------------------------------------------------------+
291 | Return Value :>0: No error |
292 | .... |
293 | -100 : Config command error |
294 | -101 : Data size error |
295 +----------------------------------------------------------------------------+
296 */
297
298 int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device * dev,
299 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
300 {
301 INT i_ReturnValue = insn->n;
302
303 /************************/
304 /* Test the buffer size */
305 /************************/
306
307 if (insn->n >= 1) {
308 switch ((BYTE) data[0]) {
309 case APCI3XXX_CONFIGURATION:
310 i_ReturnValue =
311 i_APCI3XXX_AnalogInputConfigOperatingMode(dev,
312 s, insn, data);
313 break;
314
315 default:
316 i_ReturnValue = -100;
317 printk("Config command error %d\n", data[0]);
318 break;
319 }
320 } else {
321 /*******************/
322 /* Data size error */
323 /*******************/
324
325 printk("Buffer size error\n");
326 i_ReturnValue = -101;
327 }
328
329 return (i_ReturnValue);
330 }
331
332 /*
333 +----------------------------------------------------------------------------+
334 | Function Name : INT i_APCI3XXX_InsnReadAnalogInput |
335 | (struct comedi_device *dev, |
336 | struct comedi_subdevice *s, |
337 | comedi_insn *insn, |
338 | unsigned int *data) |
339 +----------------------------------------------------------------------------+
340 | Task Read 1 analog input |
341 +----------------------------------------------------------------------------+
342 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
343 | b_Channel = CR_CHAN(insn->chanspec); |
344 | dw_NbrOfAcquisition = insn->n; |
345 +----------------------------------------------------------------------------+
346 | Output Parameters : - |
347 +----------------------------------------------------------------------------+
348 | Return Value :>0: No error |
349 | -3 : Channel selection error |
350 | -4 : Configuration selelection error |
351 | -10: Any conversion started |
352 | .... |
353 | -100 : Config command error |
354 | -101 : Data size error |
355 +----------------------------------------------------------------------------+
356 */
357
358 int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device * dev,
359 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
360 {
361 INT i_ReturnValue = insn->n;
362 BYTE b_Configuration = (BYTE) CR_RANGE(insn->chanspec);
363 BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
364 DWORD dw_Temp = 0;
365 DWORD dw_Configuration = 0;
366 DWORD dw_AcquisitionCpt = 0;
367 BYTE b_Interrupt = 0;
368
369 /*************************************/
370 /* Test if operating mode configured */
371 /*************************************/
372
373 if (devpriv->b_AiInitialisation) {
374 /***************************/
375 /* Test the channel number */
376 /***************************/
377
378 if (((b_Channel < devpriv->ps_BoardInfo->i_NbrAiChannel)
379 && (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
380 || ((b_Channel < devpriv->ps_BoardInfo->
381 i_NbrAiChannelDiff)
382 && (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
383 /**********************************/
384 /* Test the channel configuration */
385 /**********************************/
386
387 if (b_Configuration > 7) {
388 /***************************/
389 /* Channel not initialised */
390 /***************************/
391
392 i_ReturnValue = -4;
393 printk("Channel %d range %d selection error\n",
394 b_Channel, b_Configuration);
395 }
396 } else {
397 /***************************/
398 /* Channel selection error */
399 /***************************/
400
401 i_ReturnValue = -3;
402 printk("Channel %d selection error\n", b_Channel);
403 }
404
405 /**************************/
406 /* Test if no error occur */
407 /**************************/
408
409 if (i_ReturnValue >= 0) {
410 /************************/
411 /* Test the buffer size */
412 /************************/
413
414 if ((b_Interrupt != 0) || ((b_Interrupt == 0)
415 && (insn->n >= 1))) {
416 /**********************************/
417 /* Test if conversion not started */
418 /**********************************/
419
420 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
421 /******************/
422 /* Clear the FIFO */
423 /******************/
424
425 writel(0x10000UL,
426 (void *)(devpriv->dw_AiBase +
427 12));
428
429 /*******************************/
430 /* Get and save the delay mode */
431 /*******************************/
432
433 dw_Temp =
434 readl((void *)(devpriv->
435 dw_AiBase + 4));
436 dw_Temp = dw_Temp & 0xFFFFFEF0UL;
437
438 /***********************************/
439 /* Channel configuration selection */
440 /***********************************/
441
442 writel(dw_Temp,
443 (void *)(devpriv->dw_AiBase +
444 4));
445
446 /**************************/
447 /* Make the configuration */
448 /**************************/
449
450 dw_Configuration =
451 (b_Configuration & 3) |
452 ((DWORD) (b_Configuration >> 2)
453 << 6) | ((DWORD) devpriv->
454 b_SingelDiff << 7);
455
456 /***************************/
457 /* Write the configuration */
458 /***************************/
459
460 writel(dw_Configuration,
461 (void *)(devpriv->dw_AiBase +
462 0));
463
464 /*********************/
465 /* Channel selection */
466 /*********************/
467
468 writel(dw_Temp | 0x100UL,
469 (void *)(devpriv->dw_AiBase +
470 4));
471 writel((DWORD) b_Channel,
472 (void *)(devpriv->dw_AiBase +
473 0));
474
475 /***********************/
476 /* Restaure delay mode */
477 /***********************/
478
479 writel(dw_Temp,
480 (void *)(devpriv->dw_AiBase +
481 4));
482
483 /***********************************/
484 /* Set the number of sequence to 1 */
485 /***********************************/
486
487 writel(1,
488 (void *)(devpriv->dw_AiBase +
489 48));
490
491 /***************************/
492 /* Save the interrupt flag */
493 /***************************/
494
495 devpriv->b_EocEosInterrupt =
496 b_Interrupt;
497
498 /*******************************/
499 /* Save the number of channels */
500 /*******************************/
501
502 devpriv->ui_AiNbrofChannels = 1;
503
504 /******************************/
505 /* Test if interrupt not used */
506 /******************************/
507
508 if (b_Interrupt == 0) {
509 for (dw_AcquisitionCpt = 0;
510 dw_AcquisitionCpt <
511 insn->n;
512 dw_AcquisitionCpt++) {
513 /************************/
514 /* Start the conversion */
515 /************************/
516
517 writel(0x80000UL,
518 (void *)
519 (devpriv->
520 dw_AiBase
521 + 8));
522
523 /****************/
524 /* Wait the EOS */
525 /****************/
526
527 do {
528 dw_Temp =
529 readl(
530 (void *)
531 (devpriv->
532 dw_AiBase
533 +
534 20));
535 dw_Temp =
536 dw_Temp
537 & 1;
538 }
539 while (dw_Temp != 1);
540
541 /*************************/
542 /* Read the analog value */
543 /*************************/
544
545 data[dw_AcquisitionCpt]
546 =
547 (unsigned int)
548 readl((void
549 *)
550 (devpriv->
551 dw_AiBase
552 + 28));
553 }
554 } else {
555 /************************/
556 /* Start the conversion */
557 /************************/
558
559 writel(0x180000UL,
560 (void *)(devpriv->
561 dw_AiBase + 8));
562 }
563 } else {
564 /**************************/
565 /* Any conversion started */
566 /**************************/
567
568 printk("Any conversion started\n");
569 i_ReturnValue = -10;
570 }
571 } else {
572 /*******************/
573 /* Data size error */
574 /*******************/
575
576 printk("Buffer size error\n");
577 i_ReturnValue = -101;
578 }
579 }
580 } else {
581 /***************************/
582 /* Channel selection error */
583 /***************************/
584
585 printk("Operating mode not configured\n");
586 i_ReturnValue = -1;
587 }
588 return (i_ReturnValue);
589 }
590
591 /*
592 +----------------------------------------------------------------------------+
593 | Function name : void v_APCI3XXX_Interrupt (int irq, |
594 | void *d) |
595 +----------------------------------------------------------------------------+
596 | Task :Interrupt handler for APCI3XXX |
597 | When interrupt occurs this gets called. |
598 | First it finds which interrupt has been generated and |
599 | handles corresponding interrupt |
600 +----------------------------------------------------------------------------+
601 | Input Parameters : - |
602 +----------------------------------------------------------------------------+
603 | Return Value : - |
604 +----------------------------------------------------------------------------+
605 */
606
607 void v_APCI3XXX_Interrupt(int irq, void *d)
608 {
609 struct comedi_device *dev = d;
610 BYTE b_CopyCpt = 0;
611 DWORD dw_Status = 0;
612
613 /***************************/
614 /* Test if interrupt occur */
615 /***************************/
616
617 if (((dw_Status = readl((void *)(devpriv->dw_AiBase + 16))) & 0x2UL) ==
618 0x2UL) {
619 /***********************/
620 /* Reset the interrupt */
621 /***********************/
622
623 writel(dw_Status, (void *)(devpriv->dw_AiBase + 16));
624
625 /*****************************/
626 /* Test if interrupt enabled */
627 /*****************************/
628
629 if (devpriv->b_EocEosInterrupt == 1) {
630 /********************************/
631 /* Read all analog inputs value */
632 /********************************/
633
634 for (b_CopyCpt = 0;
635 b_CopyCpt < devpriv->ui_AiNbrofChannels;
636 b_CopyCpt++) {
637 devpriv->ui_AiReadData[b_CopyCpt] =
638 (UINT) readl((void *)(devpriv->
639 dw_AiBase + 28));
640 }
641
642 /**************************/
643 /* Set the interrupt flag */
644 /**************************/
645
646 devpriv->b_EocEosInterrupt = 2;
647
648 /**********************************************/
649 /* Send a signal to from kernel to user space */
650 /**********************************************/
651
652 send_sig(SIGIO, devpriv->tsk_Current, 0);
653 }
654 }
655 }
656
657 /*
658 +----------------------------------------------------------------------------+
659 | ANALOG OUTPUT SUBDEVICE |
660 +----------------------------------------------------------------------------+
661 */
662
663 /*
664 +----------------------------------------------------------------------------+
665 | Function Name : INT i_APCI3XXX_InsnWriteAnalogOutput |
666 | (struct comedi_device *dev, |
667 | struct comedi_subdevice *s, |
668 | comedi_insn *insn, |
669 | unsigned int *data) |
670 +----------------------------------------------------------------------------+
671 | Task Read 1 analog input |
672 +----------------------------------------------------------------------------+
673 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
674 | b_Channel = CR_CHAN(insn->chanspec); |
675 | data[0] = analog value; |
676 +----------------------------------------------------------------------------+
677 | Output Parameters : - |
678 +----------------------------------------------------------------------------+
679 | Return Value :>0: No error |
680 | -3 : Channel selection error |
681 | -4 : Configuration selelection error |
682 | .... |
683 | -101 : Data size error |
684 +----------------------------------------------------------------------------+
685 */
686
687 int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device * dev,
688 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
689 {
690 BYTE b_Range = (BYTE) CR_RANGE(insn->chanspec);
691 BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
692 DWORD dw_Status = 0;
693 INT i_ReturnValue = insn->n;
694
695 /************************/
696 /* Test the buffer size */
697 /************************/
698
699 if (insn->n >= 1) {
700 /***************************/
701 /* Test the channel number */
702 /***************************/
703
704 if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) {
705 /**********************************/
706 /* Test the channel configuration */
707 /**********************************/
708
709 if (b_Range < 2) {
710 /***************************/
711 /* Set the range selection */
712 /***************************/
713
714 writel(b_Range,
715 (void *)(devpriv->dw_AiBase + 96));
716
717 /**************************************************/
718 /* Write the analog value to the selected channel */
719 /**************************************************/
720
721 writel((data[0] << 8) | b_Channel,
722 (void *)(devpriv->dw_AiBase + 100));
723
724 /****************************/
725 /* Wait the end of transfer */
726 /****************************/
727
728 do {
729 dw_Status =
730 readl((void *)(devpriv->
731 dw_AiBase + 96));
732 }
733 while ((dw_Status & 0x100) != 0x100);
734 } else {
735 /***************************/
736 /* Channel not initialised */
737 /***************************/
738
739 i_ReturnValue = -4;
740 printk("Channel %d range %d selection error\n",
741 b_Channel, b_Range);
742 }
743 } else {
744 /***************************/
745 /* Channel selection error */
746 /***************************/
747
748 i_ReturnValue = -3;
749 printk("Channel %d selection error\n", b_Channel);
750 }
751 } else {
752 /*******************/
753 /* Data size error */
754 /*******************/
755
756 printk("Buffer size error\n");
757 i_ReturnValue = -101;
758 }
759
760 return (i_ReturnValue);
761 }
762
763 /*
764 +----------------------------------------------------------------------------+
765 | TTL FUNCTIONS |
766 +----------------------------------------------------------------------------+
767 */
768
769 /*
770 +----------------------------------------------------------------------------+
771 | Function Name : INT i_APCI3XXX_InsnConfigInitTTLIO |
772 | (struct comedi_device *dev, |
773 | struct comedi_subdevice *s, |
774 | comedi_insn *insn, |
775 | unsigned int *data) |
776 +----------------------------------------------------------------------------+
777 | Task You must calling this function be |
778 | for you call any other function witch access of TTL. |
779 | APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
780 +----------------------------------------------------------------------------+
781 | Input Parameters : b_InitType = (BYTE) data[0]; |
782 | b_Port2Mode = (BYTE) data[1]; |
783 +----------------------------------------------------------------------------+
784 | Output Parameters : - |
785 +----------------------------------------------------------------------------+
786 | Return Value :>0: No error |
787 | -1: Port 2 mode selection is wrong |
788 | .... |
789 | -100 : Config command error |
790 | -101 : Data size error |
791 +----------------------------------------------------------------------------+
792 */
793
794 int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device * dev,
795 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
796 {
797 INT i_ReturnValue = insn->n;
798 BYTE b_Command = 0;
799
800 /************************/
801 /* Test the buffer size */
802 /************************/
803
804 if (insn->n >= 1) {
805 /*******************/
806 /* Get the command */
807 /* **************** */
808
809 b_Command = (BYTE) data[0];
810
811 /********************/
812 /* Test the command */
813 /********************/
814
815 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
816 /***************************************/
817 /* Test the initialisation buffer size */
818 /***************************************/
819
820 if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
821 && (insn->n != 2)) {
822 /*******************/
823 /* Data size error */
824 /*******************/
825
826 printk("Buffer size error\n");
827 i_ReturnValue = -101;
828 }
829 } else {
830 /************************/
831 /* Config command error */
832 /************************/
833
834 printk("Command selection error\n");
835 i_ReturnValue = -100;
836 }
837 } else {
838 /*******************/
839 /* Data size error */
840 /*******************/
841
842 printk("Buffer size error\n");
843 i_ReturnValue = -101;
844 }
845
846 /*********************************************************************************/
847 /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
848 /*********************************************************************************/
849
850 if ((i_ReturnValue >= 0)
851 && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
852 /**********************/
853 /* Test the direction */
854 /**********************/
855
856 if ((data[1] == 0) || (data[1] == 0xFF)) {
857 /**************************/
858 /* Save the configuration */
859 /**************************/
860
861 devpriv->ul_TTLPortConfiguration[0] =
862 devpriv->ul_TTLPortConfiguration[0] | data[1];
863 } else {
864 /************************/
865 /* Port direction error */
866 /************************/
867
868 printk("Port 2 direction selection error\n");
869 i_ReturnValue = -1;
870 }
871 }
872
873 /**************************/
874 /* Test if no error occur */
875 /**************************/
876
877 if (i_ReturnValue >= 0) {
878 /***********************************/
879 /* Test if TTL port initilaisation */
880 /***********************************/
881
882 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
883 /*************************/
884 /* Set the configuration */
885 /*************************/
886
887 outl(data[1], devpriv->iobase + 224);
888 }
889 }
890
891 return (i_ReturnValue);
892 }
893
894 /*
895 +----------------------------------------------------------------------------+
896 | TTL INPUT FUNCTIONS |
897 +----------------------------------------------------------------------------+
898 */
899
900 /*
901 +----------------------------------------------------------------------------+
902 | Function Name : INT i_APCI3XXX_InsnBitsTTLIO |
903 | (struct comedi_device *dev, |
904 | struct comedi_subdevice *s, |
905 | comedi_insn *insn, |
906 | unsigned int *data) |
907 +----------------------------------------------------------------------------+
908 | Task : Write the selected output mask and read the status from|
909 | all TTL channles |
910 +----------------------------------------------------------------------------+
911 | Input Parameters : dw_ChannelMask = data [0]; |
912 | dw_BitMask = data [1]; |
913 +----------------------------------------------------------------------------+
914 | Output Parameters : data[1] : All TTL channles states |
915 +----------------------------------------------------------------------------+
916 | Return Value : >0 : No error |
917 | -4 : Channel mask error |
918 | -101 : Data size error |
919 +----------------------------------------------------------------------------+
920 */
921
922 int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device * dev,
923 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
924 {
925 INT i_ReturnValue = insn->n;
926 BYTE b_ChannelCpt = 0;
927 DWORD dw_ChannelMask = 0;
928 DWORD dw_BitMask = 0;
929 DWORD dw_Status = 0;
930
931 /************************/
932 /* Test the buffer size */
933 /************************/
934
935 if (insn->n >= 2) {
936 /*******************************/
937 /* Get the channe and bit mask */
938 /*******************************/
939
940 dw_ChannelMask = data[0];
941 dw_BitMask = data[1];
942
943 /*************************/
944 /* Test the channel mask */
945 /*************************/
946
947 if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
948 (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
949 || (((devpriv->ul_TTLPortConfiguration[0] &
950 0xFF) == 0)
951 && ((dw_ChannelMask & 0XFF0000) ==
952 0)))) {
953 /*********************************/
954 /* Test if set/reset any channel */
955 /*********************************/
956
957 if (dw_ChannelMask) {
958 /****************************************/
959 /* Test if set/rest any port 0 channels */
960 /****************************************/
961
962 if (dw_ChannelMask & 0xFF) {
963 /*******************************************/
964 /* Read port 0 (first digital output port) */
965 /*******************************************/
966
967 dw_Status = inl(devpriv->iobase + 80);
968
969 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
970 b_ChannelCpt++) {
971 if ((dw_ChannelMask >>
972 b_ChannelCpt) &
973 1) {
974 dw_Status =
975 (dw_Status &
976 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
977 }
978 }
979
980 outl(dw_Status, devpriv->iobase + 80);
981 }
982
983 /****************************************/
984 /* Test if set/rest any port 2 channels */
985 /****************************************/
986
987 if (dw_ChannelMask & 0xFF0000) {
988 dw_BitMask = dw_BitMask >> 16;
989 dw_ChannelMask = dw_ChannelMask >> 16;
990
991 /********************************************/
992 /* Read port 2 (second digital output port) */
993 /********************************************/
994
995 dw_Status = inl(devpriv->iobase + 112);
996
997 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
998 b_ChannelCpt++) {
999 if ((dw_ChannelMask >>
1000 b_ChannelCpt) &
1001 1) {
1002 dw_Status =
1003 (dw_Status &
1004 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
1005 }
1006 }
1007
1008 outl(dw_Status, devpriv->iobase + 112);
1009 }
1010 }
1011
1012 /*******************************************/
1013 /* Read port 0 (first digital output port) */
1014 /*******************************************/
1015
1016 data[1] = inl(devpriv->iobase + 80);
1017
1018 /******************************************/
1019 /* Read port 1 (first digital input port) */
1020 /******************************************/
1021
1022 data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
1023
1024 /************************/
1025 /* Test if port 2 input */
1026 /************************/
1027
1028 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
1029 data[1] =
1030 data[1] | (inl(devpriv->iobase +
1031 96) << 16);
1032 } else {
1033 data[1] =
1034 data[1] | (inl(devpriv->iobase +
1035 112) << 16);
1036 }
1037 } else {
1038 /************************/
1039 /* Config command error */
1040 /************************/
1041
1042 printk("Channel mask error\n");
1043 i_ReturnValue = -4;
1044 }
1045 } else {
1046 /*******************/
1047 /* Data size error */
1048 /*******************/
1049
1050 printk("Buffer size error\n");
1051 i_ReturnValue = -101;
1052 }
1053
1054 return (i_ReturnValue);
1055 }
1056
1057 /*
1058 +----------------------------------------------------------------------------+
1059 | Function Name : INT i_APCI3XXX_InsnReadTTLIO |
1060 | (struct comedi_device *dev, |
1061 | struct comedi_subdevice *s, |
1062 | comedi_insn *insn, |
1063 | unsigned int *data) |
1064 +----------------------------------------------------------------------------+
1065 | Task : Read the status from selected channel |
1066 +----------------------------------------------------------------------------+
1067 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1068 +----------------------------------------------------------------------------+
1069 | Output Parameters : data[0] : Selected TTL channel state |
1070 +----------------------------------------------------------------------------+
1071 | Return Value : 0 : No error |
1072 | -3 : Channel selection error |
1073 | -101 : Data size error |
1074 +----------------------------------------------------------------------------+
1075 */
1076
1077 int i_APCI3XXX_InsnReadTTLIO(struct comedi_device * dev,
1078 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
1079 {
1080 BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
1081 INT i_ReturnValue = insn->n;
1082 unsigned int *pls_ReadData = data;
1083
1084 /************************/
1085 /* Test the buffer size */
1086 /************************/
1087
1088 if (insn->n >= 1) {
1089 /***********************/
1090 /* Test if read port 0 */
1091 /***********************/
1092
1093 if (b_Channel < 8) {
1094 /*******************************************/
1095 /* Read port 0 (first digital output port) */
1096 /*******************************************/
1097
1098 pls_ReadData[0] = inl(devpriv->iobase + 80);
1099 pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
1100 } else {
1101 /***********************/
1102 /* Test if read port 1 */
1103 /***********************/
1104
1105 if ((b_Channel > 7) && (b_Channel < 16)) {
1106 /******************************************/
1107 /* Read port 1 (first digital input port) */
1108 /******************************************/
1109
1110 pls_ReadData[0] = inl(devpriv->iobase + 64);
1111 pls_ReadData[0] =
1112 (pls_ReadData[0] >> (b_Channel -
1113 8)) & 1;
1114 } else {
1115 /***********************/
1116 /* Test if read port 2 */
1117 /***********************/
1118
1119 if ((b_Channel > 15) && (b_Channel < 24)) {
1120 /************************/
1121 /* Test if port 2 input */
1122 /************************/
1123
1124 if ((devpriv->ul_TTLPortConfiguration[0]
1125 & 0xFF) == 0) {
1126 pls_ReadData[0] =
1127 inl(devpriv->iobase +
1128 96);
1129 pls_ReadData[0] =
1130 (pls_ReadData[0] >>
1131 (b_Channel - 16)) & 1;
1132 } else {
1133 pls_ReadData[0] =
1134 inl(devpriv->iobase +
1135 112);
1136 pls_ReadData[0] =
1137 (pls_ReadData[0] >>
1138 (b_Channel - 16)) & 1;
1139 }
1140 } else {
1141 /***************************/
1142 /* Channel selection error */
1143 /***************************/
1144
1145 i_ReturnValue = -3;
1146 printk("Channel %d selection error\n",
1147 b_Channel);
1148 }
1149 }
1150 }
1151 } else {
1152 /*******************/
1153 /* Data size error */
1154 /*******************/
1155
1156 printk("Buffer size error\n");
1157 i_ReturnValue = -101;
1158 }
1159
1160 return (i_ReturnValue);
1161 }
1162
1163 /*
1164 +----------------------------------------------------------------------------+
1165 | TTL OUTPUT FUNCTIONS |
1166 +----------------------------------------------------------------------------+
1167 */
1168
1169 /*
1170 +----------------------------------------------------------------------------+
1171 | Function Name : INT i_APCI3XXX_InsnWriteTTLIO |
1172 | (struct comedi_device *dev, |
1173 | struct comedi_subdevice *s, |
1174 | comedi_insn *insn, |
1175 | unsigned int *data) |
1176 +----------------------------------------------------------------------------+
1177 | Task : Set the state from TTL output channel |
1178 +----------------------------------------------------------------------------+
1179 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1180 | b_State = data [0] |
1181 +----------------------------------------------------------------------------+
1182 | Output Parameters : - |
1183 +----------------------------------------------------------------------------+
1184 | Return Value : 0 : No error |
1185 | -3 : Channel selection error |
1186 | -101 : Data size error |
1187 +----------------------------------------------------------------------------+
1188 */
1189
1190 int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device * dev,
1191 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
1192 {
1193 INT i_ReturnValue = insn->n;
1194 BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
1195 BYTE b_State = 0;
1196 DWORD dw_Status = 0;
1197
1198 /************************/
1199 /* Test the buffer size */
1200 /************************/
1201
1202 if (insn->n >= 1) {
1203 b_State = (BYTE) data[0];
1204
1205 /***********************/
1206 /* Test if read port 0 */
1207 /***********************/
1208
1209 if (b_Channel < 8) {
1210 /*****************************************************************************/
1211 /* Read port 0 (first digital output port) and set/reset the selcted channel */
1212 /*****************************************************************************/
1213
1214 dw_Status = inl(devpriv->iobase + 80);
1215 dw_Status =
1216 (dw_Status & (0xFF -
1217 (1 << b_Channel))) | ((b_State & 1) <<
1218 b_Channel);
1219 outl(dw_Status, devpriv->iobase + 80);
1220 } else {
1221 /***********************/
1222 /* Test if read port 2 */
1223 /***********************/
1224
1225 if ((b_Channel > 15) && (b_Channel < 24)) {
1226 /*************************/
1227 /* Test if port 2 output */
1228 /*************************/
1229
1230 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
1231 == 0xFF) {
1232 /*****************************************************************************/
1233 /* Read port 2 (first digital output port) and set/reset the selcted channel */
1234 /*****************************************************************************/
1235
1236 dw_Status = inl(devpriv->iobase + 112);
1237 dw_Status =
1238 (dw_Status & (0xFF -
1239 (1 << (b_Channel -
1240 16)))) |
1241 ((b_State & 1) << (b_Channel -
1242 16));
1243 outl(dw_Status, devpriv->iobase + 112);
1244 } else {
1245 /***************************/
1246 /* Channel selection error */
1247 /***************************/
1248
1249 i_ReturnValue = -3;
1250 printk("Channel %d selection error\n",
1251 b_Channel);
1252 }
1253 } else {
1254 /***************************/
1255 /* Channel selection error */
1256 /***************************/
1257
1258 i_ReturnValue = -3;
1259 printk("Channel %d selection error\n",
1260 b_Channel);
1261 }
1262 }
1263 } else {
1264 /*******************/
1265 /* Data size error */
1266 /*******************/
1267
1268 printk("Buffer size error\n");
1269 i_ReturnValue = -101;
1270 }
1271
1272 return (i_ReturnValue);
1273 }
1274
1275 /*
1276 +----------------------------------------------------------------------------+
1277 | DIGITAL INPUT SUBDEVICE |
1278 +----------------------------------------------------------------------------+
1279 */
1280
1281 /*
1282 +----------------------------------------------------------------------------+
1283 | Function name :int i_APCI3XXX_InsnReadDigitalInput |
1284 | (struct comedi_device *dev, |
1285 | struct comedi_subdevice *s, |
1286 | comedi_insn *insn, |
1287 | unsigned int *data) |
1288 +----------------------------------------------------------------------------+
1289 | Task : Reads the value of the specified Digital input channel |
1290 +----------------------------------------------------------------------------+
1291 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) |
1292 +----------------------------------------------------------------------------+
1293 | Output Parameters : data[0] : Channel value |
1294 +----------------------------------------------------------------------------+
1295 | Return Value : 0 : No error |
1296 | -3 : Channel selection error |
1297 | -101 : Data size error |
1298 +----------------------------------------------------------------------------+
1299 */
1300
1301 int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device * dev,
1302 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
1303 {
1304 INT i_ReturnValue = insn->n;
1305 BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
1306 DWORD dw_Temp = 0;
1307
1308 /***************************/
1309 /* Test the channel number */
1310 /***************************/
1311
1312 if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) {
1313 /************************/
1314 /* Test the buffer size */
1315 /************************/
1316
1317 if (insn->n >= 1) {
1318 dw_Temp = inl(devpriv->iobase + 32);
1319 *data = (dw_Temp >> b_Channel) & 1;
1320 } else {
1321 /*******************/
1322 /* Data size error */
1323 /*******************/
1324
1325 printk("Buffer size error\n");
1326 i_ReturnValue = -101;
1327 }
1328 } else {
1329 /***************************/
1330 /* Channel selection error */
1331 /***************************/
1332
1333 printk("Channel selection error\n");
1334 i_ReturnValue = -3;
1335 }
1336
1337 return (i_ReturnValue);
1338 }
1339
1340 /*
1341 +----------------------------------------------------------------------------+
1342 | Function name :int i_APCI3XXX_InsnBitsDigitalInput |
1343 | (struct comedi_device *dev, |
1344 | struct comedi_subdevice *s, |
1345 | comedi_insn *insn, |
1346 | unsigned int *data) |
1347 +----------------------------------------------------------------------------+
1348 | Task : Reads the value of the Digital input Port i.e.4channels|
1349 +----------------------------------------------------------------------------+
1350 | Input Parameters : - |
1351 +----------------------------------------------------------------------------+
1352 | Output Parameters : data[0] : Port value |
1353 +----------------------------------------------------------------------------+
1354 | Return Value :>0: No error |
1355 | .... |
1356 | -101 : Data size error |
1357 +----------------------------------------------------------------------------+
1358 */
1359 int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device * dev,
1360 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
1361 {
1362 INT i_ReturnValue = insn->n;
1363 DWORD dw_Temp = 0;
1364
1365 /************************/
1366 /* Test the buffer size */
1367 /************************/
1368
1369 if (insn->n >= 1) {
1370 dw_Temp = inl(devpriv->iobase + 32);
1371 *data = dw_Temp & 0xf;
1372 } else {
1373 /*******************/
1374 /* Data size error */
1375 /*******************/
1376
1377 printk("Buffer size error\n");
1378 i_ReturnValue = -101;
1379 }
1380
1381 return (i_ReturnValue);
1382 }
1383
1384 /*
1385 +----------------------------------------------------------------------------+
1386 | DIGITAL OUTPUT SUBDEVICE |
1387 +----------------------------------------------------------------------------+
1388
1389 */
1390
1391 /*
1392 +----------------------------------------------------------------------------+
1393 | Function name :int i_APCI3XXX_InsnBitsDigitalOutput |
1394 | (struct comedi_device *dev, |
1395 | struct comedi_subdevice *s, |
1396 | comedi_insn *insn, |
1397 | unsigned int *data) |
1398 +----------------------------------------------------------------------------+
1399 | Task : Write the selected output mask and read the status from|
1400 | all digital output channles |
1401 +----------------------------------------------------------------------------+
1402 | Input Parameters : dw_ChannelMask = data [0]; |
1403 | dw_BitMask = data [1]; |
1404 +----------------------------------------------------------------------------+
1405 | Output Parameters : data[1] : All digital output channles states |
1406 +----------------------------------------------------------------------------+
1407 | Return Value : >0 : No error |
1408 | -4 : Channel mask error |
1409 | -101 : Data size error |
1410 +----------------------------------------------------------------------------+
1411 */
1412 int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device * dev,
1413 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
1414 {
1415 INT i_ReturnValue = insn->n;
1416 BYTE b_ChannelCpt = 0;
1417 DWORD dw_ChannelMask = 0;
1418 DWORD dw_BitMask = 0;
1419 DWORD dw_Status = 0;
1420
1421 /************************/
1422 /* Test the buffer size */
1423 /************************/
1424
1425 if (insn->n >= 2) {
1426 /*******************************/
1427 /* Get the channe and bit mask */
1428 /*******************************/
1429
1430 dw_ChannelMask = data[0];
1431 dw_BitMask = data[1];
1432
1433 /*************************/
1434 /* Test the channel mask */
1435 /*************************/
1436
1437 if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
1438 /*********************************/
1439 /* Test if set/reset any channel */
1440 /*********************************/
1441
1442 if (dw_ChannelMask & 0xF) {
1443 /********************************/
1444 /* Read the digital output port */
1445 /********************************/
1446
1447 dw_Status = inl(devpriv->iobase + 48);
1448
1449 for (b_ChannelCpt = 0; b_ChannelCpt < 4;
1450 b_ChannelCpt++) {
1451 if ((dw_ChannelMask >> b_ChannelCpt) &
1452 1) {
1453 dw_Status =
1454 (dw_Status & (0xF -
1455 (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
1456 }
1457 }
1458
1459 outl(dw_Status, devpriv->iobase + 48);
1460 }
1461
1462 /********************************/
1463 /* Read the digital output port */
1464 /********************************/
1465
1466 data[1] = inl(devpriv->iobase + 48);
1467 } else {
1468 /************************/
1469 /* Config command error */
1470 /************************/
1471
1472 printk("Channel mask error\n");
1473 i_ReturnValue = -4;
1474 }
1475 } else {
1476 /*******************/
1477 /* Data size error */
1478 /*******************/
1479
1480 printk("Buffer size error\n");
1481 i_ReturnValue = -101;
1482 }
1483
1484 return (i_ReturnValue);
1485 }
1486
1487 /*
1488 +----------------------------------------------------------------------------+
1489 | Function name :int i_APCI3XXX_InsnWriteDigitalOutput |
1490 | (struct comedi_device *dev, |
1491 | struct comedi_subdevice *s, |
1492 | comedi_insn *insn, |
1493 | unsigned int *data) |
1494 +----------------------------------------------------------------------------+
1495 | Task : Set the state from digital output channel |
1496 +----------------------------------------------------------------------------+
1497 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1498 | b_State = data [0] |
1499 +----------------------------------------------------------------------------+
1500 | Output Parameters : - |
1501 +----------------------------------------------------------------------------+
1502 | Return Value : >0 : No error |
1503 | -3 : Channel selection error |
1504 | -101 : Data size error |
1505 +----------------------------------------------------------------------------+
1506 */
1507
1508 int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device * dev,
1509 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
1510 {
1511 INT i_ReturnValue = insn->n;
1512 BYTE b_Channel = CR_CHAN(insn->chanspec);
1513 BYTE b_State = 0;
1514 DWORD dw_Status = 0;
1515
1516 /************************/
1517 /* Test the buffer size */
1518 /************************/
1519
1520 if (insn->n >= 1) {
1521 /***************************/
1522 /* Test the channel number */
1523 /***************************/
1524
1525 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
1526 /*******************/
1527 /* Get the command */
1528 /*******************/
1529
1530 b_State = (BYTE) data[0];
1531
1532 /********************************/
1533 /* Read the digital output port */
1534 /********************************/
1535
1536 dw_Status = inl(devpriv->iobase + 48);
1537
1538 dw_Status =
1539 (dw_Status & (0xF -
1540 (1 << b_Channel))) | ((b_State & 1) <<
1541 b_Channel);
1542 outl(dw_Status, devpriv->iobase + 48);
1543 } else {
1544 /***************************/
1545 /* Channel selection error */
1546 /***************************/
1547
1548 printk("Channel selection error\n");
1549 i_ReturnValue = -3;
1550 }
1551 } else {
1552 /*******************/
1553 /* Data size error */
1554 /*******************/
1555
1556 printk("Buffer size error\n");
1557 i_ReturnValue = -101;
1558 }
1559
1560 return (i_ReturnValue);
1561 }
1562
1563 /*
1564 +----------------------------------------------------------------------------+
1565 | Function name :int i_APCI3XXX_InsnReadDigitalOutput |
1566 | (struct comedi_device *dev, |
1567 | struct comedi_subdevice *s, |
1568 | comedi_insn *insn, |
1569 | unsigned int *data) |
1570 +----------------------------------------------------------------------------+
1571 | Task : Read the state from digital output channel |
1572 +----------------------------------------------------------------------------+
1573 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1574 +----------------------------------------------------------------------------+
1575 | Output Parameters : b_State = data [0] |
1576 +----------------------------------------------------------------------------+
1577 | Return Value : >0 : No error |
1578 | -3 : Channel selection error |
1579 | -101 : Data size error |
1580 +----------------------------------------------------------------------------+
1581 */
1582
1583 int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device * dev,
1584 struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
1585 {
1586 INT i_ReturnValue = insn->n;
1587 BYTE b_Channel = CR_CHAN(insn->chanspec);
1588 DWORD dw_Status = 0;
1589
1590 /************************/
1591 /* Test the buffer size */
1592 /************************/
1593
1594 if (insn->n >= 1) {
1595 /***************************/
1596 /* Test the channel number */
1597 /***************************/
1598
1599 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
1600 /********************************/
1601 /* Read the digital output port */
1602 /********************************/
1603
1604 dw_Status = inl(devpriv->iobase + 48);
1605
1606 dw_Status = (dw_Status >> b_Channel) & 1;
1607 *data = dw_Status;
1608 } else {
1609 /***************************/
1610 /* Channel selection error */
1611 /***************************/
1612
1613 printk("Channel selection error\n");
1614 i_ReturnValue = -3;
1615 }
1616 } else {
1617 /*******************/
1618 /* Data size error */
1619 /*******************/
1620
1621 printk("Buffer size error\n");
1622 i_ReturnValue = -101;
1623 }
1624
1625 return (i_ReturnValue);
1626 }
1627
1628 /*
1629 +----------------------------------------------------------------------------+
1630 | Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
1631 | Task :resets all the registers |
1632 +----------------------------------------------------------------------------+
1633 | Input Parameters : struct comedi_device *dev |
1634 +----------------------------------------------------------------------------+
1635 | Output Parameters : - |
1636 +----------------------------------------------------------------------------+
1637 | Return Value : - |
1638 +----------------------------------------------------------------------------+
1639 */
1640
1641 int i_APCI3XXX_Reset(struct comedi_device * dev)
1642 {
1643 unsigned char b_Cpt = 0;
1644
1645 /*************************/
1646 /* Disable the interrupt */
1647 /*************************/
1648
1649 disable_irq(dev->irq);
1650
1651 /****************************/
1652 /* Reset the interrupt flag */
1653 /****************************/
1654
1655 devpriv->b_EocEosInterrupt = 0;
1656
1657 /***************************/
1658 /* Clear the start command */
1659 /***************************/
1660
1661 writel(0, (void *)(devpriv->dw_AiBase + 8));
1662
1663 /*****************************/
1664 /* Reset the interrupt flags */
1665 /*****************************/
1666
1667 writel(readl((void *)(devpriv->dw_AiBase + 16)),
1668 (void *)(devpriv->dw_AiBase + 16));
1669
1670 /*****************/
1671 /* clear the EOS */
1672 /*****************/
1673
1674 readl((void *)(devpriv->dw_AiBase + 20));
1675
1676 /******************/
1677 /* Clear the FIFO */
1678 /******************/
1679
1680 for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
1681 readl((void *)(devpriv->dw_AiBase + 28));
1682 }
1683
1684 /************************/
1685 /* Enable the interrupt */
1686 /************************/
1687
1688 enable_irq(dev->irq);
1689
1690 return 0;
1691 }
This page took 0.079325 seconds and 4 git commands to generate.