1d1e5fc2ea9a44feb3666597211f9939c77bdd78
[GitHub/mt8127/android_kernel_alcatel_ttab.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 | struct comedi_insn *insn, |
86 | unsigned int *data) |
87 +----------------------------------------------------------------------------+
88 | Task Converting mode and convert time selection |
89 +----------------------------------------------------------------------------+
90 | Input Parameters : b_SingleDiff = (unsigned char) data[1]; |
91 | b_TimeBase = (unsigned char) data[2]; (0: ns, 1:micros 2:ms)|
92 | dw_ReloadValue = (unsigned int) 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, struct comedi_insn *insn, unsigned int *data)
110 {
111 int i_ReturnValue = insn->n;
112 unsigned char b_TimeBase = 0;
113 unsigned char b_SingleDiff = 0;
114 unsigned int dw_ReloadValue = 0;
115 unsigned int 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 = (unsigned char) data[1];
127
128 /****************************/
129 /* Get the time base unitiy */
130 /****************************/
131
132 b_TimeBase = (unsigned char) data[2];
133
134 /*************************************/
135 /* Get the convert time reload value */
136 /*************************************/
137
138 dw_ReloadValue = (unsigned int) 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 <= 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 (unsigned int)
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((unsigned int)
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 | struct comedi_insn *insn, |
280 | unsigned int *data) |
281 +----------------------------------------------------------------------------+
282 | Task Converting mode and convert time selection |
283 +----------------------------------------------------------------------------+
284 | Input Parameters : b_ConvertMode = (unsigned char) data[0]; |
285 | b_TimeBase = (unsigned char) data[1]; (0: ns, 1:micros 2:ms)|
286 | dw_ReloadValue = (unsigned int) 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, struct 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 ((unsigned char) 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 | struct 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, struct comedi_insn *insn, unsigned int *data)
360 {
361 int i_ReturnValue = insn->n;
362 unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec);
363 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
364 unsigned int dw_Temp = 0;
365 unsigned int dw_Configuration = 0;
366 unsigned int dw_AcquisitionCpt = 0;
367 unsigned char 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 ((unsigned int) (b_Configuration >> 2)
453 << 6) | ((unsigned int) 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((unsigned int) 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 } while (dw_Temp != 1);
539
540 /*************************/
541 /* Read the analog value */
542 /*************************/
543
544 data[dw_AcquisitionCpt]
545 =
546 (unsigned int)
547 readl((void
548 *)
549 (devpriv->
550 dw_AiBase
551 + 28));
552 }
553 } else {
554 /************************/
555 /* Start the conversion */
556 /************************/
557
558 writel(0x180000UL,
559 (void *)(devpriv->
560 dw_AiBase + 8));
561 }
562 } else {
563 /**************************/
564 /* Any conversion started */
565 /**************************/
566
567 printk("Any conversion started\n");
568 i_ReturnValue = -10;
569 }
570 } else {
571 /*******************/
572 /* Data size error */
573 /*******************/
574
575 printk("Buffer size error\n");
576 i_ReturnValue = -101;
577 }
578 }
579 } else {
580 /***************************/
581 /* Channel selection error */
582 /***************************/
583
584 printk("Operating mode not configured\n");
585 i_ReturnValue = -1;
586 }
587 return i_ReturnValue;
588 }
589
590 /*
591 +----------------------------------------------------------------------------+
592 | Function name : void v_APCI3XXX_Interrupt (int irq, |
593 | void *d) |
594 +----------------------------------------------------------------------------+
595 | Task :Interrupt handler for APCI3XXX |
596 | When interrupt occurs this gets called. |
597 | First it finds which interrupt has been generated and |
598 | handles corresponding interrupt |
599 +----------------------------------------------------------------------------+
600 | Input Parameters : - |
601 +----------------------------------------------------------------------------+
602 | Return Value : - |
603 +----------------------------------------------------------------------------+
604 */
605
606 void v_APCI3XXX_Interrupt(int irq, void *d)
607 {
608 struct comedi_device *dev = d;
609 unsigned char b_CopyCpt = 0;
610 unsigned int dw_Status = 0;
611
612 /***************************/
613 /* Test if interrupt occur */
614 /***************************/
615
616 dw_Status = readl((void *)(devpriv->dw_AiBase + 16));
617 if ( (dw_Status & 0x2UL) == 0x2UL) {
618 /***********************/
619 /* Reset the interrupt */
620 /***********************/
621
622 writel(dw_Status, (void *)(devpriv->dw_AiBase + 16));
623
624 /*****************************/
625 /* Test if interrupt enabled */
626 /*****************************/
627
628 if (devpriv->b_EocEosInterrupt == 1) {
629 /********************************/
630 /* Read all analog inputs value */
631 /********************************/
632
633 for (b_CopyCpt = 0;
634 b_CopyCpt < devpriv->ui_AiNbrofChannels;
635 b_CopyCpt++) {
636 devpriv->ui_AiReadData[b_CopyCpt] =
637 (unsigned int) readl((void *)(devpriv->
638 dw_AiBase + 28));
639 }
640
641 /**************************/
642 /* Set the interrupt flag */
643 /**************************/
644
645 devpriv->b_EocEosInterrupt = 2;
646
647 /**********************************************/
648 /* Send a signal to from kernel to user space */
649 /**********************************************/
650
651 send_sig(SIGIO, devpriv->tsk_Current, 0);
652 }
653 }
654 }
655
656 /*
657 +----------------------------------------------------------------------------+
658 | ANALOG OUTPUT SUBDEVICE |
659 +----------------------------------------------------------------------------+
660 */
661
662 /*
663 +----------------------------------------------------------------------------+
664 | Function Name : int i_APCI3XXX_InsnWriteAnalogOutput |
665 | (struct comedi_device *dev, |
666 | struct comedi_subdevice *s, |
667 | struct comedi_insn *insn, |
668 | unsigned int *data) |
669 +----------------------------------------------------------------------------+
670 | Task Read 1 analog input |
671 +----------------------------------------------------------------------------+
672 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
673 | b_Channel = CR_CHAN(insn->chanspec); |
674 | data[0] = analog value; |
675 +----------------------------------------------------------------------------+
676 | Output Parameters : - |
677 +----------------------------------------------------------------------------+
678 | Return Value :>0: No error |
679 | -3 : Channel selection error |
680 | -4 : Configuration selelection error |
681 | .... |
682 | -101 : Data size error |
683 +----------------------------------------------------------------------------+
684 */
685
686 int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev,
687 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
688 {
689 unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec);
690 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
691 unsigned int dw_Status = 0;
692 int i_ReturnValue = insn->n;
693
694 /************************/
695 /* Test the buffer size */
696 /************************/
697
698 if (insn->n >= 1) {
699 /***************************/
700 /* Test the channel number */
701 /***************************/
702
703 if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) {
704 /**********************************/
705 /* Test the channel configuration */
706 /**********************************/
707
708 if (b_Range < 2) {
709 /***************************/
710 /* Set the range selection */
711 /***************************/
712
713 writel(b_Range,
714 (void *)(devpriv->dw_AiBase + 96));
715
716 /**************************************************/
717 /* Write the analog value to the selected channel */
718 /**************************************************/
719
720 writel((data[0] << 8) | b_Channel,
721 (void *)(devpriv->dw_AiBase + 100));
722
723 /****************************/
724 /* Wait the end of transfer */
725 /****************************/
726
727 do {
728 dw_Status =
729 readl((void *)(devpriv->
730 dw_AiBase + 96));
731 } while ((dw_Status & 0x100) != 0x100);
732 } else {
733 /***************************/
734 /* Channel not initialised */
735 /***************************/
736
737 i_ReturnValue = -4;
738 printk("Channel %d range %d selection error\n",
739 b_Channel, b_Range);
740 }
741 } else {
742 /***************************/
743 /* Channel selection error */
744 /***************************/
745
746 i_ReturnValue = -3;
747 printk("Channel %d selection error\n", b_Channel);
748 }
749 } else {
750 /*******************/
751 /* Data size error */
752 /*******************/
753
754 printk("Buffer size error\n");
755 i_ReturnValue = -101;
756 }
757
758 return i_ReturnValue;
759 }
760
761 /*
762 +----------------------------------------------------------------------------+
763 | TTL FUNCTIONS |
764 +----------------------------------------------------------------------------+
765 */
766
767 /*
768 +----------------------------------------------------------------------------+
769 | Function Name : int i_APCI3XXX_InsnConfigInitTTLIO |
770 | (struct comedi_device *dev, |
771 | struct comedi_subdevice *s, |
772 | struct comedi_insn *insn, |
773 | unsigned int *data) |
774 +----------------------------------------------------------------------------+
775 | Task You must calling this function be |
776 | for you call any other function witch access of TTL. |
777 | APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
778 +----------------------------------------------------------------------------+
779 | Input Parameters : b_InitType = (unsigned char) data[0]; |
780 | b_Port2Mode = (unsigned char) data[1]; |
781 +----------------------------------------------------------------------------+
782 | Output Parameters : - |
783 +----------------------------------------------------------------------------+
784 | Return Value :>0: No error |
785 | -1: Port 2 mode selection is wrong |
786 | .... |
787 | -100 : Config command error |
788 | -101 : Data size error |
789 +----------------------------------------------------------------------------+
790 */
791
792 int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev,
793 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
794 {
795 int i_ReturnValue = insn->n;
796 unsigned char b_Command = 0;
797
798 /************************/
799 /* Test the buffer size */
800 /************************/
801
802 if (insn->n >= 1) {
803 /*******************/
804 /* Get the command */
805 /* **************** */
806
807 b_Command = (unsigned char) data[0];
808
809 /********************/
810 /* Test the command */
811 /********************/
812
813 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
814 /***************************************/
815 /* Test the initialisation buffer size */
816 /***************************************/
817
818 if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
819 && (insn->n != 2)) {
820 /*******************/
821 /* Data size error */
822 /*******************/
823
824 printk("Buffer size error\n");
825 i_ReturnValue = -101;
826 }
827 } else {
828 /************************/
829 /* Config command error */
830 /************************/
831
832 printk("Command selection error\n");
833 i_ReturnValue = -100;
834 }
835 } else {
836 /*******************/
837 /* Data size error */
838 /*******************/
839
840 printk("Buffer size error\n");
841 i_ReturnValue = -101;
842 }
843
844 /*********************************************************************************/
845 /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
846 /*********************************************************************************/
847
848 if ((i_ReturnValue >= 0)
849 && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
850 /**********************/
851 /* Test the direction */
852 /**********************/
853
854 if ((data[1] == 0) || (data[1] == 0xFF)) {
855 /**************************/
856 /* Save the configuration */
857 /**************************/
858
859 devpriv->ul_TTLPortConfiguration[0] =
860 devpriv->ul_TTLPortConfiguration[0] | data[1];
861 } else {
862 /************************/
863 /* Port direction error */
864 /************************/
865
866 printk("Port 2 direction selection error\n");
867 i_ReturnValue = -1;
868 }
869 }
870
871 /**************************/
872 /* Test if no error occur */
873 /**************************/
874
875 if (i_ReturnValue >= 0) {
876 /***********************************/
877 /* Test if TTL port initilaisation */
878 /***********************************/
879
880 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
881 /*************************/
882 /* Set the configuration */
883 /*************************/
884
885 outl(data[1], devpriv->iobase + 224);
886 }
887 }
888
889 return i_ReturnValue;
890 }
891
892 /*
893 +----------------------------------------------------------------------------+
894 | TTL INPUT FUNCTIONS |
895 +----------------------------------------------------------------------------+
896 */
897
898 /*
899 +----------------------------------------------------------------------------+
900 | Function Name : int i_APCI3XXX_InsnBitsTTLIO |
901 | (struct comedi_device *dev, |
902 | struct comedi_subdevice *s, |
903 | struct comedi_insn *insn, |
904 | unsigned int *data) |
905 +----------------------------------------------------------------------------+
906 | Task : Write the selected output mask and read the status from|
907 | all TTL channles |
908 +----------------------------------------------------------------------------+
909 | Input Parameters : dw_ChannelMask = data [0]; |
910 | dw_BitMask = data [1]; |
911 +----------------------------------------------------------------------------+
912 | Output Parameters : data[1] : All TTL channles states |
913 +----------------------------------------------------------------------------+
914 | Return Value : >0 : No error |
915 | -4 : Channel mask error |
916 | -101 : Data size error |
917 +----------------------------------------------------------------------------+
918 */
919
920 int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev,
921 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
922 {
923 int i_ReturnValue = insn->n;
924 unsigned char b_ChannelCpt = 0;
925 unsigned int dw_ChannelMask = 0;
926 unsigned int dw_BitMask = 0;
927 unsigned int dw_Status = 0;
928
929 /************************/
930 /* Test the buffer size */
931 /************************/
932
933 if (insn->n >= 2) {
934 /*******************************/
935 /* Get the channe and bit mask */
936 /*******************************/
937
938 dw_ChannelMask = data[0];
939 dw_BitMask = data[1];
940
941 /*************************/
942 /* Test the channel mask */
943 /*************************/
944
945 if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
946 (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
947 || (((devpriv->ul_TTLPortConfiguration[0] &
948 0xFF) == 0)
949 && ((dw_ChannelMask & 0XFF0000) ==
950 0)))) {
951 /*********************************/
952 /* Test if set/reset any channel */
953 /*********************************/
954
955 if (dw_ChannelMask) {
956 /****************************************/
957 /* Test if set/rest any port 0 channels */
958 /****************************************/
959
960 if (dw_ChannelMask & 0xFF) {
961 /*******************************************/
962 /* Read port 0 (first digital output port) */
963 /*******************************************/
964
965 dw_Status = inl(devpriv->iobase + 80);
966
967 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
968 b_ChannelCpt++) {
969 if ((dw_ChannelMask >>
970 b_ChannelCpt) &
971 1) {
972 dw_Status =
973 (dw_Status &
974 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
975 }
976 }
977
978 outl(dw_Status, devpriv->iobase + 80);
979 }
980
981 /****************************************/
982 /* Test if set/rest any port 2 channels */
983 /****************************************/
984
985 if (dw_ChannelMask & 0xFF0000) {
986 dw_BitMask = dw_BitMask >> 16;
987 dw_ChannelMask = dw_ChannelMask >> 16;
988
989 /********************************************/
990 /* Read port 2 (second digital output port) */
991 /********************************************/
992
993 dw_Status = inl(devpriv->iobase + 112);
994
995 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
996 b_ChannelCpt++) {
997 if ((dw_ChannelMask >>
998 b_ChannelCpt) &
999 1) {
1000 dw_Status =
1001 (dw_Status &
1002 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
1003 }
1004 }
1005
1006 outl(dw_Status, devpriv->iobase + 112);
1007 }
1008 }
1009
1010 /*******************************************/
1011 /* Read port 0 (first digital output port) */
1012 /*******************************************/
1013
1014 data[1] = inl(devpriv->iobase + 80);
1015
1016 /******************************************/
1017 /* Read port 1 (first digital input port) */
1018 /******************************************/
1019
1020 data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
1021
1022 /************************/
1023 /* Test if port 2 input */
1024 /************************/
1025
1026 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
1027 data[1] =
1028 data[1] | (inl(devpriv->iobase +
1029 96) << 16);
1030 } else {
1031 data[1] =
1032 data[1] | (inl(devpriv->iobase +
1033 112) << 16);
1034 }
1035 } else {
1036 /************************/
1037 /* Config command error */
1038 /************************/
1039
1040 printk("Channel mask error\n");
1041 i_ReturnValue = -4;
1042 }
1043 } else {
1044 /*******************/
1045 /* Data size error */
1046 /*******************/
1047
1048 printk("Buffer size error\n");
1049 i_ReturnValue = -101;
1050 }
1051
1052 return i_ReturnValue;
1053 }
1054
1055 /*
1056 +----------------------------------------------------------------------------+
1057 | Function Name : int i_APCI3XXX_InsnReadTTLIO |
1058 | (struct comedi_device *dev, |
1059 | struct comedi_subdevice *s, |
1060 | struct comedi_insn *insn, |
1061 | unsigned int *data) |
1062 +----------------------------------------------------------------------------+
1063 | Task : Read the status from selected channel |
1064 +----------------------------------------------------------------------------+
1065 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1066 +----------------------------------------------------------------------------+
1067 | Output Parameters : data[0] : Selected TTL channel state |
1068 +----------------------------------------------------------------------------+
1069 | Return Value : 0 : No error |
1070 | -3 : Channel selection error |
1071 | -101 : Data size error |
1072 +----------------------------------------------------------------------------+
1073 */
1074
1075 int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev,
1076 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1077 {
1078 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1079 int i_ReturnValue = insn->n;
1080 unsigned int *pls_ReadData = data;
1081
1082 /************************/
1083 /* Test the buffer size */
1084 /************************/
1085
1086 if (insn->n >= 1) {
1087 /***********************/
1088 /* Test if read port 0 */
1089 /***********************/
1090
1091 if (b_Channel < 8) {
1092 /*******************************************/
1093 /* Read port 0 (first digital output port) */
1094 /*******************************************/
1095
1096 pls_ReadData[0] = inl(devpriv->iobase + 80);
1097 pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
1098 } else {
1099 /***********************/
1100 /* Test if read port 1 */
1101 /***********************/
1102
1103 if ((b_Channel > 7) && (b_Channel < 16)) {
1104 /******************************************/
1105 /* Read port 1 (first digital input port) */
1106 /******************************************/
1107
1108 pls_ReadData[0] = inl(devpriv->iobase + 64);
1109 pls_ReadData[0] =
1110 (pls_ReadData[0] >> (b_Channel -
1111 8)) & 1;
1112 } else {
1113 /***********************/
1114 /* Test if read port 2 */
1115 /***********************/
1116
1117 if ((b_Channel > 15) && (b_Channel < 24)) {
1118 /************************/
1119 /* Test if port 2 input */
1120 /************************/
1121
1122 if ((devpriv->ul_TTLPortConfiguration[0]
1123 & 0xFF) == 0) {
1124 pls_ReadData[0] =
1125 inl(devpriv->iobase +
1126 96);
1127 pls_ReadData[0] =
1128 (pls_ReadData[0] >>
1129 (b_Channel - 16)) & 1;
1130 } else {
1131 pls_ReadData[0] =
1132 inl(devpriv->iobase +
1133 112);
1134 pls_ReadData[0] =
1135 (pls_ReadData[0] >>
1136 (b_Channel - 16)) & 1;
1137 }
1138 } else {
1139 /***************************/
1140 /* Channel selection error */
1141 /***************************/
1142
1143 i_ReturnValue = -3;
1144 printk("Channel %d selection error\n",
1145 b_Channel);
1146 }
1147 }
1148 }
1149 } else {
1150 /*******************/
1151 /* Data size error */
1152 /*******************/
1153
1154 printk("Buffer size error\n");
1155 i_ReturnValue = -101;
1156 }
1157
1158 return i_ReturnValue;
1159 }
1160
1161 /*
1162 +----------------------------------------------------------------------------+
1163 | TTL OUTPUT FUNCTIONS |
1164 +----------------------------------------------------------------------------+
1165 */
1166
1167 /*
1168 +----------------------------------------------------------------------------+
1169 | Function Name : int i_APCI3XXX_InsnWriteTTLIO |
1170 | (struct comedi_device *dev, |
1171 | struct comedi_subdevice *s, |
1172 | struct comedi_insn *insn, |
1173 | unsigned int *data) |
1174 +----------------------------------------------------------------------------+
1175 | Task : Set the state from TTL output channel |
1176 +----------------------------------------------------------------------------+
1177 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1178 | b_State = data [0] |
1179 +----------------------------------------------------------------------------+
1180 | Output Parameters : - |
1181 +----------------------------------------------------------------------------+
1182 | Return Value : 0 : No error |
1183 | -3 : Channel selection error |
1184 | -101 : Data size error |
1185 +----------------------------------------------------------------------------+
1186 */
1187
1188 int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
1189 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1190 {
1191 int i_ReturnValue = insn->n;
1192 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1193 unsigned char b_State = 0;
1194 unsigned int dw_Status = 0;
1195
1196 /************************/
1197 /* Test the buffer size */
1198 /************************/
1199
1200 if (insn->n >= 1) {
1201 b_State = (unsigned char) data[0];
1202
1203 /***********************/
1204 /* Test if read port 0 */
1205 /***********************/
1206
1207 if (b_Channel < 8) {
1208 /*****************************************************************************/
1209 /* Read port 0 (first digital output port) and set/reset the selcted channel */
1210 /*****************************************************************************/
1211
1212 dw_Status = inl(devpriv->iobase + 80);
1213 dw_Status =
1214 (dw_Status & (0xFF -
1215 (1 << b_Channel))) | ((b_State & 1) <<
1216 b_Channel);
1217 outl(dw_Status, devpriv->iobase + 80);
1218 } else {
1219 /***********************/
1220 /* Test if read port 2 */
1221 /***********************/
1222
1223 if ((b_Channel > 15) && (b_Channel < 24)) {
1224 /*************************/
1225 /* Test if port 2 output */
1226 /*************************/
1227
1228 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
1229 == 0xFF) {
1230 /*****************************************************************************/
1231 /* Read port 2 (first digital output port) and set/reset the selcted channel */
1232 /*****************************************************************************/
1233
1234 dw_Status = inl(devpriv->iobase + 112);
1235 dw_Status =
1236 (dw_Status & (0xFF -
1237 (1 << (b_Channel -
1238 16)))) |
1239 ((b_State & 1) << (b_Channel -
1240 16));
1241 outl(dw_Status, devpriv->iobase + 112);
1242 } else {
1243 /***************************/
1244 /* Channel selection error */
1245 /***************************/
1246
1247 i_ReturnValue = -3;
1248 printk("Channel %d selection error\n",
1249 b_Channel);
1250 }
1251 } else {
1252 /***************************/
1253 /* Channel selection error */
1254 /***************************/
1255
1256 i_ReturnValue = -3;
1257 printk("Channel %d selection error\n",
1258 b_Channel);
1259 }
1260 }
1261 } else {
1262 /*******************/
1263 /* Data size error */
1264 /*******************/
1265
1266 printk("Buffer size error\n");
1267 i_ReturnValue = -101;
1268 }
1269
1270 return i_ReturnValue;
1271 }
1272
1273 /*
1274 +----------------------------------------------------------------------------+
1275 | DIGITAL INPUT SUBDEVICE |
1276 +----------------------------------------------------------------------------+
1277 */
1278
1279 /*
1280 +----------------------------------------------------------------------------+
1281 | Function name :int i_APCI3XXX_InsnReadDigitalInput |
1282 | (struct comedi_device *dev, |
1283 | struct comedi_subdevice *s, |
1284 | struct comedi_insn *insn, |
1285 | unsigned int *data) |
1286 +----------------------------------------------------------------------------+
1287 | Task : Reads the value of the specified Digital input channel |
1288 +----------------------------------------------------------------------------+
1289 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) |
1290 +----------------------------------------------------------------------------+
1291 | Output Parameters : data[0] : Channel value |
1292 +----------------------------------------------------------------------------+
1293 | Return Value : 0 : No error |
1294 | -3 : Channel selection error |
1295 | -101 : Data size error |
1296 +----------------------------------------------------------------------------+
1297 */
1298
1299 int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev,
1300 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1301 {
1302 int i_ReturnValue = insn->n;
1303 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1304 unsigned int dw_Temp = 0;
1305
1306 /***************************/
1307 /* Test the channel number */
1308 /***************************/
1309
1310 if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) {
1311 /************************/
1312 /* Test the buffer size */
1313 /************************/
1314
1315 if (insn->n >= 1) {
1316 dw_Temp = inl(devpriv->iobase + 32);
1317 *data = (dw_Temp >> b_Channel) & 1;
1318 } else {
1319 /*******************/
1320 /* Data size error */
1321 /*******************/
1322
1323 printk("Buffer size error\n");
1324 i_ReturnValue = -101;
1325 }
1326 } else {
1327 /***************************/
1328 /* Channel selection error */
1329 /***************************/
1330
1331 printk("Channel selection error\n");
1332 i_ReturnValue = -3;
1333 }
1334
1335 return i_ReturnValue;
1336 }
1337
1338 /*
1339 +----------------------------------------------------------------------------+
1340 | Function name :int i_APCI3XXX_InsnBitsDigitalInput |
1341 | (struct comedi_device *dev, |
1342 | struct comedi_subdevice *s, |
1343 | struct comedi_insn *insn, |
1344 | unsigned int *data) |
1345 +----------------------------------------------------------------------------+
1346 | Task : Reads the value of the Digital input Port i.e.4channels|
1347 +----------------------------------------------------------------------------+
1348 | Input Parameters : - |
1349 +----------------------------------------------------------------------------+
1350 | Output Parameters : data[0] : Port value |
1351 +----------------------------------------------------------------------------+
1352 | Return Value :>0: No error |
1353 | .... |
1354 | -101 : Data size error |
1355 +----------------------------------------------------------------------------+
1356 */
1357 int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev,
1358 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1359 {
1360 int i_ReturnValue = insn->n;
1361 unsigned int dw_Temp = 0;
1362
1363 /************************/
1364 /* Test the buffer size */
1365 /************************/
1366
1367 if (insn->n >= 1) {
1368 dw_Temp = inl(devpriv->iobase + 32);
1369 *data = dw_Temp & 0xf;
1370 } else {
1371 /*******************/
1372 /* Data size error */
1373 /*******************/
1374
1375 printk("Buffer size error\n");
1376 i_ReturnValue = -101;
1377 }
1378
1379 return i_ReturnValue;
1380 }
1381
1382 /*
1383 +----------------------------------------------------------------------------+
1384 | DIGITAL OUTPUT SUBDEVICE |
1385 +----------------------------------------------------------------------------+
1386
1387 */
1388
1389 /*
1390 +----------------------------------------------------------------------------+
1391 | Function name :int i_APCI3XXX_InsnBitsDigitalOutput |
1392 | (struct comedi_device *dev, |
1393 | struct comedi_subdevice *s, |
1394 | struct comedi_insn *insn, |
1395 | unsigned int *data) |
1396 +----------------------------------------------------------------------------+
1397 | Task : Write the selected output mask and read the status from|
1398 | all digital output channles |
1399 +----------------------------------------------------------------------------+
1400 | Input Parameters : dw_ChannelMask = data [0]; |
1401 | dw_BitMask = data [1]; |
1402 +----------------------------------------------------------------------------+
1403 | Output Parameters : data[1] : All digital output channles states |
1404 +----------------------------------------------------------------------------+
1405 | Return Value : >0 : No error |
1406 | -4 : Channel mask error |
1407 | -101 : Data size error |
1408 +----------------------------------------------------------------------------+
1409 */
1410 int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev,
1411 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1412 {
1413 int i_ReturnValue = insn->n;
1414 unsigned char b_ChannelCpt = 0;
1415 unsigned int dw_ChannelMask = 0;
1416 unsigned int dw_BitMask = 0;
1417 unsigned int dw_Status = 0;
1418
1419 /************************/
1420 /* Test the buffer size */
1421 /************************/
1422
1423 if (insn->n >= 2) {
1424 /*******************************/
1425 /* Get the channe and bit mask */
1426 /*******************************/
1427
1428 dw_ChannelMask = data[0];
1429 dw_BitMask = data[1];
1430
1431 /*************************/
1432 /* Test the channel mask */
1433 /*************************/
1434
1435 if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
1436 /*********************************/
1437 /* Test if set/reset any channel */
1438 /*********************************/
1439
1440 if (dw_ChannelMask & 0xF) {
1441 /********************************/
1442 /* Read the digital output port */
1443 /********************************/
1444
1445 dw_Status = inl(devpriv->iobase + 48);
1446
1447 for (b_ChannelCpt = 0; b_ChannelCpt < 4;
1448 b_ChannelCpt++) {
1449 if ((dw_ChannelMask >> b_ChannelCpt) &
1450 1) {
1451 dw_Status =
1452 (dw_Status & (0xF -
1453 (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
1454 }
1455 }
1456
1457 outl(dw_Status, devpriv->iobase + 48);
1458 }
1459
1460 /********************************/
1461 /* Read the digital output port */
1462 /********************************/
1463
1464 data[1] = inl(devpriv->iobase + 48);
1465 } else {
1466 /************************/
1467 /* Config command error */
1468 /************************/
1469
1470 printk("Channel mask error\n");
1471 i_ReturnValue = -4;
1472 }
1473 } else {
1474 /*******************/
1475 /* Data size error */
1476 /*******************/
1477
1478 printk("Buffer size error\n");
1479 i_ReturnValue = -101;
1480 }
1481
1482 return i_ReturnValue;
1483 }
1484
1485 /*
1486 +----------------------------------------------------------------------------+
1487 | Function name :int i_APCI3XXX_InsnWriteDigitalOutput |
1488 | (struct comedi_device *dev, |
1489 | struct comedi_subdevice *s, |
1490 | struct comedi_insn *insn, |
1491 | unsigned int *data) |
1492 +----------------------------------------------------------------------------+
1493 | Task : Set the state from digital output channel |
1494 +----------------------------------------------------------------------------+
1495 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1496 | b_State = data [0] |
1497 +----------------------------------------------------------------------------+
1498 | Output Parameters : - |
1499 +----------------------------------------------------------------------------+
1500 | Return Value : >0 : No error |
1501 | -3 : Channel selection error |
1502 | -101 : Data size error |
1503 +----------------------------------------------------------------------------+
1504 */
1505
1506 int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev,
1507 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1508 {
1509 int i_ReturnValue = insn->n;
1510 unsigned char b_Channel = CR_CHAN(insn->chanspec);
1511 unsigned char b_State = 0;
1512 unsigned int dw_Status = 0;
1513
1514 /************************/
1515 /* Test the buffer size */
1516 /************************/
1517
1518 if (insn->n >= 1) {
1519 /***************************/
1520 /* Test the channel number */
1521 /***************************/
1522
1523 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
1524 /*******************/
1525 /* Get the command */
1526 /*******************/
1527
1528 b_State = (unsigned char) data[0];
1529
1530 /********************************/
1531 /* Read the digital output port */
1532 /********************************/
1533
1534 dw_Status = inl(devpriv->iobase + 48);
1535
1536 dw_Status =
1537 (dw_Status & (0xF -
1538 (1 << b_Channel))) | ((b_State & 1) <<
1539 b_Channel);
1540 outl(dw_Status, devpriv->iobase + 48);
1541 } else {
1542 /***************************/
1543 /* Channel selection error */
1544 /***************************/
1545
1546 printk("Channel selection error\n");
1547 i_ReturnValue = -3;
1548 }
1549 } else {
1550 /*******************/
1551 /* Data size error */
1552 /*******************/
1553
1554 printk("Buffer size error\n");
1555 i_ReturnValue = -101;
1556 }
1557
1558 return i_ReturnValue;
1559 }
1560
1561 /*
1562 +----------------------------------------------------------------------------+
1563 | Function name :int i_APCI3XXX_InsnReadDigitalOutput |
1564 | (struct comedi_device *dev, |
1565 | struct comedi_subdevice *s, |
1566 | struct comedi_insn *insn, |
1567 | unsigned int *data) |
1568 +----------------------------------------------------------------------------+
1569 | Task : Read the state from digital output channel |
1570 +----------------------------------------------------------------------------+
1571 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1572 +----------------------------------------------------------------------------+
1573 | Output Parameters : b_State = data [0] |
1574 +----------------------------------------------------------------------------+
1575 | Return Value : >0 : No error |
1576 | -3 : Channel selection error |
1577 | -101 : Data size error |
1578 +----------------------------------------------------------------------------+
1579 */
1580
1581 int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev,
1582 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1583 {
1584 int i_ReturnValue = insn->n;
1585 unsigned char b_Channel = CR_CHAN(insn->chanspec);
1586 unsigned int dw_Status = 0;
1587
1588 /************************/
1589 /* Test the buffer size */
1590 /************************/
1591
1592 if (insn->n >= 1) {
1593 /***************************/
1594 /* Test the channel number */
1595 /***************************/
1596
1597 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
1598 /********************************/
1599 /* Read the digital output port */
1600 /********************************/
1601
1602 dw_Status = inl(devpriv->iobase + 48);
1603
1604 dw_Status = (dw_Status >> b_Channel) & 1;
1605 *data = dw_Status;
1606 } else {
1607 /***************************/
1608 /* Channel selection error */
1609 /***************************/
1610
1611 printk("Channel selection error\n");
1612 i_ReturnValue = -3;
1613 }
1614 } else {
1615 /*******************/
1616 /* Data size error */
1617 /*******************/
1618
1619 printk("Buffer size error\n");
1620 i_ReturnValue = -101;
1621 }
1622
1623 return i_ReturnValue;
1624 }
1625
1626 /*
1627 +----------------------------------------------------------------------------+
1628 | Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
1629 | Task :resets all the registers |
1630 +----------------------------------------------------------------------------+
1631 | Input Parameters : struct comedi_device *dev |
1632 +----------------------------------------------------------------------------+
1633 | Output Parameters : - |
1634 +----------------------------------------------------------------------------+
1635 | Return Value : - |
1636 +----------------------------------------------------------------------------+
1637 */
1638
1639 int i_APCI3XXX_Reset(struct comedi_device *dev)
1640 {
1641 unsigned char b_Cpt = 0;
1642
1643 /*************************/
1644 /* Disable the interrupt */
1645 /*************************/
1646
1647 disable_irq(dev->irq);
1648
1649 /****************************/
1650 /* Reset the interrupt flag */
1651 /****************************/
1652
1653 devpriv->b_EocEosInterrupt = 0;
1654
1655 /***************************/
1656 /* Clear the start command */
1657 /***************************/
1658
1659 writel(0, (void *)(devpriv->dw_AiBase + 8));
1660
1661 /*****************************/
1662 /* Reset the interrupt flags */
1663 /*****************************/
1664
1665 writel(readl((void *)(devpriv->dw_AiBase + 16)),
1666 (void *)(devpriv->dw_AiBase + 16));
1667
1668 /*****************/
1669 /* clear the EOS */
1670 /*****************/
1671
1672 readl((void *)(devpriv->dw_AiBase + 20));
1673
1674 /******************/
1675 /* Clear the FIFO */
1676 /******************/
1677
1678 for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
1679 readl((void *)(devpriv->dw_AiBase + 28));
1680 }
1681
1682 /************************/
1683 /* Enable the interrupt */
1684 /************************/
1685
1686 enable_irq(dev->irq);
1687
1688 return 0;
1689 }