drivers: power: report battery voltage in AOSP compatible format
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / comedi / drivers / addi-data / APCI1710_Ssi.c
CommitLineData
c995fe94
ADG
1/**
2@verbatim
3
4Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
5
356cdbcb
BP
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
25417922 11 http://www.addi-data.com
356cdbcb 12 info@addi-data.com
c995fe94
ADG
13
14This 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
16This 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
18You 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
39cfb97b 20You should also find the complete GPL in the COPYING file accompanying this source code.
c995fe94
ADG
21
22@endverbatim
23*/
24/*
25
26 +-----------------------------------------------------------------------+
27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28 +-----------------------------------------------------------------------+
29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
31 +-----------------------------------------------------------------------+
32 | Project : API APCI1710 | Compiler : gcc |
33 | Module name : SSI.C | Version : 2.96 |
34 +-------------------------------+---------------------------------------+
35 | Project manager: Eric Stolz | Date : 02/12/2002 |
36 +-----------------------------------------------------------------------+
37 | Description : APCI-1710 SSI counter module |
c995fe94 38 +-----------------------------------------------------------------------+
7aead6d7 39 | several changes done by S. Weber in 1998 and C. Guinot in 2000 |
c995fe94
ADG
40 +-----------------------------------------------------------------------+
41*/
42
e595e926
HS
43#define APCI1710_30MHZ 30
44#define APCI1710_33MHZ 33
45#define APCI1710_40MHZ 40
46
47#define APCI1710_BINARY_MODE 0x1
48#define APCI1710_GRAY_MODE 0x0
49
50#define APCI1710_SSI_READ1VALUE 1
51#define APCI1710_SSI_READALLVALUE 2
c995fe94 52
e595e926
HS
53#define APCI1710_SSI_SET_CHANNELON 0
54#define APCI1710_SSI_SET_CHANNELOFF 1
55#define APCI1710_SSI_READ_1CHANNEL 2
56#define APCI1710_SSI_READ_ALLCHANNEL 3
c995fe94
ADG
57
58/*
59+----------------------------------------------------------------------------+
60| Function Name : _INT_ i_APCI1710_InitSSI |
1783fbfe
BP
61| (unsigned char_ b_BoardHandle, |
62| unsigned char_ b_ModulNbr, |
63| unsigned char_ b_SSIProfile, |
64| unsigned char_ b_PositionTurnLength, |
65| unsigned char_ b_TurnCptLength, |
66| unsigned char_ b_PCIInputClock, |
c995fe94 67| ULONG_ ul_SSIOutputClock, |
1783fbfe 68| unsigned char_ b_SSICountingMode) |
c995fe94
ADG
69+----------------------------------------------------------------------------+
70| Task : Configure the SSI operating mode from selected module |
71| (b_ModulNbr). You must calling this function be for you|
72| call any other function witch access of SSI. |
73+----------------------------------------------------------------------------+
1783fbfe
BP
74| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
75| unsigned char_ b_ModulNbr : Module number to |
c995fe94 76| configure (0 to 3) |
1783fbfe 77| unsigned char_ b_SSIProfile : Selection from SSI |
c995fe94 78| profile length (2 to 32).|
1783fbfe 79| unsigned char_ b_PositionTurnLength : Selection from SSI |
c995fe94
ADG
80| position data length |
81| (1 to 31). |
1783fbfe 82| unsigned char_ b_TurnCptLength : Selection from SSI turn |
c995fe94
ADG
83| counter data length |
84| (1 to 31). |
1783fbfe 85| unsigned char b_PCIInputClock : Selection from PCI bus |
c995fe94
ADG
86| clock |
87| - APCI1710_30MHZ : |
88| The PC have a PCI bus |
89| clock from 30 MHz |
90| - APCI1710_33MHZ : |
91| The PC have a PCI bus |
92| clock from 33 MHz |
93| ULONG_ ul_SSIOutputClock : Selection from SSI output|
94| clock. |
95| From 229 to 5 000 000 Hz|
96| for 30 MHz selection. |
97| From 252 to 5 000 000 Hz|
98| for 33 MHz selection. |
1783fbfe 99| unsigned char b_SSICountingMode : SSI counting mode |
c995fe94
ADG
100| selection |
101| - APCI1710_BINARY_MODE : |
102| Binary counting mode. |
103| - APCI1710_GRAY_MODE : |
104| Gray counting mode.
105
106 b_ModulNbr = CR_AREF(insn->chanspec);
1783fbfe
BP
107 b_SSIProfile = (unsigned char) data[0];
108 b_PositionTurnLength= (unsigned char) data[1];
109 b_TurnCptLength = (unsigned char) data[2];
110 b_PCIInputClock = (unsigned char) data[3];
82a6e2e7 111 ul_SSIOutputClock = (unsigned int) data[4];
1783fbfe 112 b_SSICountingMode = (unsigned char) data[5]; |
c995fe94
ADG
113+----------------------------------------------------------------------------+
114| Output Parameters : - |
115+----------------------------------------------------------------------------+
116| Return Value : 0: No error |
117| -1: The handle parameter of the board is wrong |
118| -2: The module parameter is wrong |
119| -3: The module is not a SSI module |
120| -4: The selected SSI profile length is wrong |
121| -5: The selected SSI position data length is wrong |
122| -6: The selected SSI turn counter data length is wrong |
123| -7: The selected PCI input clock is wrong |
124| -8: The selected SSI output clock is wrong |
125| -9: The selected SSI counting mode parameter is wrong |
126+----------------------------------------------------------------------------+
127*/
128
f459d3ef
HS
129static int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev,
130 struct comedi_subdevice *s,
131 struct comedi_insn *insn,
132 unsigned int *data)
c995fe94 133{
843690b7 134 struct addi_private *devpriv = dev->private;
74b894e5 135 int i_ReturnValue = 0;
117102b0 136 unsigned int ui_TimerValue;
1783fbfe 137 unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
c995fe94 138 b_PCIInputClock, b_SSICountingMode;
82a6e2e7 139 unsigned int ul_SSIOutputClock;
c995fe94
ADG
140
141 b_ModulNbr = CR_AREF(insn->chanspec);
1783fbfe
BP
142 b_SSIProfile = (unsigned char) data[0];
143 b_PositionTurnLength = (unsigned char) data[1];
144 b_TurnCptLength = (unsigned char) data[2];
145 b_PCIInputClock = (unsigned char) data[3];
82a6e2e7 146 ul_SSIOutputClock = (unsigned int) data[4];
1783fbfe 147 b_SSICountingMode = (unsigned char) data[5];
c995fe94
ADG
148
149 i_ReturnValue = insn->n;
150 /**************************/
151 /* Test the module number */
152 /**************************/
153
154 if (b_ModulNbr < 4) {
155 /***********************/
156 /* Test if SSI counter */
157 /***********************/
158
159 if ((devpriv->s_BoardInfos.
160 dw_MolduleConfiguration[b_ModulNbr] &
161 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
162 /*******************************/
163 /* Test the SSI profile length */
164 /*******************************/
165
2696fb57 166 /* CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2 */
c995fe94
ADG
167 if (b_SSIProfile >= 2 && b_SSIProfile < 33) {
168 /*************************************/
169 /* Test the SSI position data length */
170 /*************************************/
171
172 if (b_PositionTurnLength > 0
173 && b_PositionTurnLength < 32) {
174 /*****************************************/
175 /* Test the SSI turn counter data length */
176 /*****************************************/
177
178 if (b_TurnCptLength > 0
179 && b_TurnCptLength < 32) {
180 /***************************/
181 /* Test the profile length */
182 /***************************/
183
184 if ((b_TurnCptLength +
185 b_PositionTurnLength)
186 <= b_SSIProfile) {
187 /****************************/
188 /* Test the PCI input clock */
189 /****************************/
190
191 if (b_PCIInputClock ==
192 APCI1710_30MHZ
193 ||
194 b_PCIInputClock
195 ==
196 APCI1710_33MHZ)
197 {
198 /*************************/
199 /* Test the output clock */
200 /*************************/
201
202 if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) {
203 if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) {
204 /**********************/
205 /* Save configuration */
206 /**********************/
207 devpriv->
208 s_ModuleInfo
209 [b_ModulNbr].
210 s_SSICounterInfo.
211 b_SSIProfile
212 =
213 b_SSIProfile;
214
215 devpriv->
216 s_ModuleInfo
217 [b_ModulNbr].
218 s_SSICounterInfo.
219 b_PositionTurnLength
220 =
221 b_PositionTurnLength;
222
223 devpriv->
224 s_ModuleInfo
225 [b_ModulNbr].
226 s_SSICounterInfo.
227 b_TurnCptLength
228 =
229 b_TurnCptLength;
230
231 /*********************************/
232 /* Initialise the profile length */
233 /*********************************/
234
235 if (b_SSICountingMode == APCI1710_BINARY_MODE) {
236
237 outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
238 } else {
239
240 outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
241 }
242
243 /******************************/
244 /* Calculate the output clock */
245 /******************************/
246
247 ui_TimerValue
248 =
117102b0 249 (unsigned int)
c995fe94 250 (
82a6e2e7 251 ((unsigned int) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);
c995fe94
ADG
252
253 /************************/
254 /* Initialise the timer */
255 /************************/
256
257 outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
258
259 /********************************/
260 /* Initialise the counting mode */
261 /********************************/
262
263 outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
264
265 devpriv->
266 s_ModuleInfo
267 [b_ModulNbr].
268 s_SSICounterInfo.
269 b_SSIInit
270 =
271 1;
272 } else {
273 /*****************************************************/
274 /* The selected SSI counting mode parameter is wrong */
275 /*****************************************************/
276
277 DPRINTK("The selected SSI counting mode parameter is wrong\n");
278 i_ReturnValue
279 =
280 -9;
281 }
282 } else {
283 /******************************************/
284 /* The selected SSI output clock is wrong */
285 /******************************************/
286
287 DPRINTK("The selected SSI output clock is wrong\n");
288 i_ReturnValue
289 =
290 -8;
291 }
292 } else {
293 /*****************************************/
294 /* The selected PCI input clock is wrong */
295 /*****************************************/
296
297 DPRINTK("The selected PCI input clock is wrong\n");
298 i_ReturnValue =
299 -7;
300 }
301 } else {
302 /********************************************/
303 /* The selected SSI profile length is wrong */
304 /********************************************/
305
306 DPRINTK("The selected SSI profile length is wrong\n");
307 i_ReturnValue = -4;
308 }
309 } else {
310 /******************************************************/
311 /* The selected SSI turn counter data length is wrong */
312 /******************************************************/
313
314 DPRINTK("The selected SSI turn counter data length is wrong\n");
315 i_ReturnValue = -6;
316 }
317 } else {
318 /**************************************************/
319 /* The selected SSI position data length is wrong */
320 /**************************************************/
321
322 DPRINTK("The selected SSI position data length is wrong\n");
323 i_ReturnValue = -5;
324 }
325 } else {
326 /********************************************/
327 /* The selected SSI profile length is wrong */
328 /********************************************/
329
330 DPRINTK("The selected SSI profile length is wrong\n");
331 i_ReturnValue = -4;
332 }
333 } else {
334 /**********************************/
335 /* The module is not a SSI module */
336 /**********************************/
337
338 DPRINTK("The module is not a SSI module\n");
339 i_ReturnValue = -3;
340 }
341 } else {
342 /***********************/
343 /* Module number error */
344 /***********************/
345
346 DPRINTK("Module number error\n");
347 i_ReturnValue = -2;
348 }
349
dae0dc30 350 return i_ReturnValue;
c995fe94
ADG
351}
352
353/*
354+----------------------------------------------------------------------------+
355| Function Name : _INT_ i_APCI1710_Read1SSIValue |
1783fbfe
BP
356| (unsigned char_ b_BoardHandle, |
357| unsigned char_ b_ModulNbr, |
358| unsigned char_ b_SelectedSSI, |
c995fe94
ADG
359| PULONG_ pul_Position, |
360| PULONG_ pul_TurnCpt)
74b894e5 361 int i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s,
90035c08 362 struct comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
363+----------------------------------------------------------------------------+
364| Task :
365
366
367 Read the selected SSI counter (b_SelectedSSI) from |
368| selected module (b_ModulNbr).
369 or Read all SSI counter (b_SelectedSSI) from |
370| selected module (b_ModulNbr). |
371+----------------------------------------------------------------------------+
1783fbfe
BP
372| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
373| unsigned char_ b_ModulNbr : Module number to |
c995fe94 374| configure (0 to 3) |
1783fbfe 375| unsigned char_ b_SelectedSSI : Selection from SSI |
c995fe94
ADG
376| counter (0 to 2)
377
1783fbfe
BP
378 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
379 b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec); (in case of single ssi)
380 b_ReadType = (unsigned char) CR_RANGE(insn->chanspec);
c995fe94
ADG
381|
382+----------------------------------------------------------------------------+
383| Output Parameters : PULONG_ pul_Position : SSI position in the turn |
384| PULONG_ pul_TurnCpt : Number of turns
385
82a6e2e7
BP
386pul_Position = (unsigned int *) &data[0];
387 pul_TurnCpt = (unsigned int *) &data[1]; |
c995fe94
ADG
388+----------------------------------------------------------------------------+
389| Return Value : 0: No error |
390| -1: The handle parameter of the board is wrong |
391| -2: The module parameter is wrong |
392| -3: The module is not a SSI module |
393| -4: SSI not initialised see function |
394| "i_APCI1710_InitSSI" |
395| -5: The selected SSI is wrong |
396+----------------------------------------------------------------------------+
397*/
398
f459d3ef
HS
399static int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev,
400 struct comedi_subdevice *s,
401 struct comedi_insn *insn,
402 unsigned int *data)
c995fe94 403{
843690b7 404 struct addi_private *devpriv = dev->private;
74b894e5 405 int i_ReturnValue = 0;
1783fbfe
BP
406 unsigned char b_Cpt;
407 unsigned char b_Length;
408 unsigned char b_Schift;
409 unsigned char b_SSICpt;
756e9d7c
BP
410 unsigned int dw_And;
411 unsigned int dw_And1;
412 unsigned int dw_And2;
413 unsigned int dw_StatusReg;
414 unsigned int dw_CounterValue;
1783fbfe
BP
415 unsigned char b_ModulNbr;
416 unsigned char b_SelectedSSI;
417 unsigned char b_ReadType;
da91b269
BP
418 unsigned int *pul_Position;
419 unsigned int *pul_TurnCpt;
420 unsigned int *pul_Position1;
421 unsigned int *pul_TurnCpt1;
c995fe94
ADG
422
423 i_ReturnValue = insn->n;
9b9bcba0 424 pul_Position1 = (unsigned int *) &data[0];
2696fb57 425/* For Read1 */
9b9bcba0 426 pul_TurnCpt1 = (unsigned int *) &data[1];
2696fb57 427/* For Read all */
9b9bcba0
BP
428 pul_Position = (unsigned int *) &data[0]; /* 0-2 */
429 pul_TurnCpt = (unsigned int *) &data[3]; /* 3-5 */
1783fbfe
BP
430 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
431 b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec);
432 b_ReadType = (unsigned char) CR_RANGE(insn->chanspec);
c995fe94
ADG
433
434 /**************************/
435 /* Test the module number */
436 /**************************/
437
438 if (b_ModulNbr < 4) {
439 /***********************/
440 /* Test if SSI counter */
441 /***********************/
442
443 if ((devpriv->s_BoardInfos.
444 dw_MolduleConfiguration[b_ModulNbr] &
445 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
446 /***************************/
447 /* Test if SSI initialised */
448 /***************************/
449
450 if (devpriv->s_ModuleInfo[b_ModulNbr].
451 s_SSICounterInfo.b_SSIInit == 1) {
452
453 switch (b_ReadType) {
454
455 case APCI1710_SSI_READ1VALUE:
456 /****************************************/
457 /* Test the selected SSI counter number */
458 /****************************************/
459
460 if (b_SelectedSSI < 3) {
461 /************************/
462 /* Start the conversion */
463 /************************/
464
465 outl(0, devpriv->s_BoardInfos.
466 ui_Address + 8 +
467 (64 * b_ModulNbr));
468
469 do {
470 /*******************/
471 /* Read the status */
472 /*******************/
473
474 dw_StatusReg =
475 inl(devpriv->
476 s_BoardInfos.
477 ui_Address +
478 (64 * b_ModulNbr));
ff89514f
BP
479 } while ((dw_StatusReg & 0x1)
480 != 0);
c995fe94
ADG
481
482 /******************************/
483 /* Read the SSI counter value */
484 /******************************/
485
486 dw_CounterValue =
487 inl(devpriv->
488 s_BoardInfos.
489 ui_Address + 4 +
490 (b_SelectedSSI * 4) +
491 (64 * b_ModulNbr));
492
493 b_Length =
494 devpriv->
495 s_ModuleInfo
496 [b_ModulNbr].
497 s_SSICounterInfo.
498 b_SSIProfile / 2;
499
500 if ((b_Length * 2) !=
501 devpriv->
502 s_ModuleInfo
503 [b_ModulNbr].
504 s_SSICounterInfo.
505 b_SSIProfile) {
506 b_Length++;
507 }
508
509 b_Schift =
510 b_Length -
511 devpriv->
512 s_ModuleInfo
513 [b_ModulNbr].
514 s_SSICounterInfo.
515 b_PositionTurnLength;
516
517 *pul_Position1 =
518 dw_CounterValue >>
519 b_Schift;
520
521 dw_And = 1;
522
523 for (b_Cpt = 0;
524 b_Cpt <
525 devpriv->
526 s_ModuleInfo
527 [b_ModulNbr].
528 s_SSICounterInfo.
529 b_PositionTurnLength;
530 b_Cpt++) {
531 dw_And = dw_And * 2;
532 }
533
534 *pul_Position1 =
535 *pul_Position1 &
536 ((dw_And) - 1);
537
538 *pul_TurnCpt1 =
539 dw_CounterValue >>
540 b_Length;
541
542 dw_And = 1;
543
544 for (b_Cpt = 0;
545 b_Cpt <
546 devpriv->
547 s_ModuleInfo
548 [b_ModulNbr].
549 s_SSICounterInfo.
550 b_TurnCptLength;
551 b_Cpt++) {
552 dw_And = dw_And * 2;
553 }
554
555 *pul_TurnCpt1 =
556 *pul_TurnCpt1 &
557 ((dw_And) - 1);
558 } else {
559 /*****************************/
560 /* The selected SSI is wrong */
561 /*****************************/
562
563 DPRINTK("The selected SSI is wrong\n");
564 i_ReturnValue = -5;
565 }
566 break;
567
568 case APCI1710_SSI_READALLVALUE:
569 dw_And1 = 1;
570
571 for (b_Cpt = 0;
572 b_Cpt <
573 devpriv->
574 s_ModuleInfo[b_ModulNbr].
575 s_SSICounterInfo.
576 b_PositionTurnLength; b_Cpt++) {
577 dw_And1 = dw_And1 * 2;
578 }
579
580 dw_And2 = 1;
581
582 for (b_Cpt = 0;
583 b_Cpt <
584 devpriv->
585 s_ModuleInfo[b_ModulNbr].
586 s_SSICounterInfo.
587 b_TurnCptLength; b_Cpt++) {
588 dw_And2 = dw_And2 * 2;
589 }
590
591 /************************/
592 /* Start the conversion */
593 /************************/
594
595 outl(0, devpriv->s_BoardInfos.
596 ui_Address + 8 +
597 (64 * b_ModulNbr));
598
599 do {
600 /*******************/
601 /* Read the status */
602 /*******************/
603
604 dw_StatusReg =
605 inl(devpriv->
606 s_BoardInfos.
607 ui_Address +
608 (64 * b_ModulNbr));
ff89514f 609 } while ((dw_StatusReg & 0x1) != 0);
c995fe94
ADG
610
611 for (b_SSICpt = 0; b_SSICpt < 3;
612 b_SSICpt++) {
613 /******************************/
614 /* Read the SSI counter value */
615 /******************************/
616
617 dw_CounterValue =
618 inl(devpriv->
619 s_BoardInfos.
620 ui_Address + 4 +
621 (b_SSICpt * 4) +
622 (64 * b_ModulNbr));
623
624 b_Length =
625 devpriv->
626 s_ModuleInfo
627 [b_ModulNbr].
628 s_SSICounterInfo.
629 b_SSIProfile / 2;
630
631 if ((b_Length * 2) !=
632 devpriv->
633 s_ModuleInfo
634 [b_ModulNbr].
635 s_SSICounterInfo.
636 b_SSIProfile) {
637 b_Length++;
638 }
639
640 b_Schift =
641 b_Length -
642 devpriv->
643 s_ModuleInfo
644 [b_ModulNbr].
645 s_SSICounterInfo.
646 b_PositionTurnLength;
647
648 pul_Position[b_SSICpt] =
649 dw_CounterValue >>
650 b_Schift;
651 pul_Position[b_SSICpt] =
652 pul_Position[b_SSICpt] &
653 ((dw_And1) - 1);
654
655 pul_TurnCpt[b_SSICpt] =
656 dw_CounterValue >>
657 b_Length;
658 pul_TurnCpt[b_SSICpt] =
659 pul_TurnCpt[b_SSICpt] &
660 ((dw_And2) - 1);
661 }
662 break;
663
664 default:
665 printk("Read Type Inputs Wrong\n");
666
2696fb57 667 } /* switch ending */
c995fe94
ADG
668
669 } else {
670 /***********************/
671 /* SSI not initialised */
672 /***********************/
673
674 DPRINTK("SSI not initialised\n");
675 i_ReturnValue = -4;
676 }
677 } else {
678 /**********************************/
679 /* The module is not a SSI module */
680 /**********************************/
681
682 DPRINTK("The module is not a SSI module\n");
683 i_ReturnValue = -3;
684
685 }
686 } else {
687 /***********************/
688 /* Module number error */
689 /***********************/
690
691 DPRINTK("Module number error\n");
692 i_ReturnValue = -2;
693 }
694
dae0dc30 695 return i_ReturnValue;
c995fe94
ADG
696}
697
698/*
699+----------------------------------------------------------------------------+
700| Function Name : _INT_ i_APCI1710_ReadSSI1DigitalInput |
1783fbfe
BP
701| (unsigned char_ b_BoardHandle, |
702| unsigned char_ b_ModulNbr, |
703| unsigned char_ b_InputChannel, |
704| unsigned char *_ pb_ChannelStatus) |
c995fe94
ADG
705+----------------------------------------------------------------------------+
706| Task :
20ce161d 707 (0) Set the digital output from selected SSI module |
c995fe94 708| (b_ModuleNbr) ON
20ce161d 709 (1) Set the digital output from selected SSI module |
c995fe94
ADG
710| (b_ModuleNbr) OFF
711 (2)Read the status from selected SSI digital input |
712| (b_InputChannel)
713 (3)Read the status from all SSI digital inputs from |
714| selected SSI module (b_ModulNbr) |
715+----------------------------------------------------------------------------+
1783fbfe
BP
716| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
717| unsigned char_ b_ModulNbr CR_AREF : Module number to |
c995fe94 718| configure (0 to 3) |
1783fbfe 719| unsigned char_ b_InputChannel CR_CHAN : Selection from digital |
c995fe94
ADG
720| data[0] which IOTYPE input ( 0 to 2) |
721+----------------------------------------------------------------------------+
1783fbfe 722| Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel |
c995fe94
ADG
723| data[0] status |
724| 0 : Channle is not active|
725| 1 : Channle is active |
726+----------------------------------------------------------------------------+
727| Return Value : 0: No error |
728| -1: The handle parameter of the board is wrong |
729| -2: The module parameter is wrong |
730| -3: The module is not a SSI module |
731| -4: The selected SSI digital input is wrong |
732+----------------------------------------------------------------------------+
733*/
734
f459d3ef
HS
735static int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev,
736 struct comedi_subdevice *s,
737 struct comedi_insn *insn,
738 unsigned int *data)
c995fe94 739{
843690b7 740 struct addi_private *devpriv = dev->private;
74b894e5 741 int i_ReturnValue = 0;
756e9d7c 742 unsigned int dw_StatusReg;
1783fbfe
BP
743 unsigned char b_ModulNbr;
744 unsigned char b_InputChannel;
da91b269
BP
745 unsigned char *pb_ChannelStatus;
746 unsigned char *pb_InputStatus;
1783fbfe 747 unsigned char b_IOType;
843690b7 748
c995fe94 749 i_ReturnValue = insn->n;
1783fbfe
BP
750 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
751 b_IOType = (unsigned char) data[0];
c995fe94
ADG
752
753 /**************************/
754 /* Test the module number */
755 /**************************/
756
757 if (b_ModulNbr < 4) {
758 /***********************/
759 /* Test if SSI counter */
760 /***********************/
761
762 if ((devpriv->s_BoardInfos.
763 dw_MolduleConfiguration[b_ModulNbr] &
764 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
765 switch (b_IOType) {
766 case APCI1710_SSI_SET_CHANNELON:
767 /*****************************/
768 /* Set the digital output ON */
769 /*****************************/
770
771 outl(1, devpriv->s_BoardInfos.ui_Address + 16 +
772 (64 * b_ModulNbr));
773 break;
774
775 case APCI1710_SSI_SET_CHANNELOFF:
776 /******************************/
777 /* Set the digital output OFF */
778 /******************************/
779
780 outl(0, devpriv->s_BoardInfos.ui_Address + 16 +
781 (64 * b_ModulNbr));
782 break;
783
784 case APCI1710_SSI_READ_1CHANNEL:
785 /******************************************/
786 /* Test the digital imnput channel number */
787 /******************************************/
788
1783fbfe 789 b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec);
9b9bcba0 790 pb_ChannelStatus = (unsigned char *) &data[0];
c995fe94
ADG
791
792 if (b_InputChannel <= 2) {
793 /**************************/
794 /* Read all digital input */
795 /**************************/
796
797 dw_StatusReg =
798 inl(devpriv->s_BoardInfos.
799 ui_Address + (64 * b_ModulNbr));
800 *pb_ChannelStatus =
1783fbfe 801 (unsigned char) (((~dw_StatusReg) >> (4 +
c995fe94
ADG
802 b_InputChannel))
803 & 1);
804 } else {
805 /********************************/
806 /* Selected digital input error */
807 /********************************/
808
809 DPRINTK("Selected digital input error\n");
810 i_ReturnValue = -4;
811 }
812 break;
813
814 case APCI1710_SSI_READ_ALLCHANNEL:
815 /**************************/
816 /* Read all digital input */
817 /**************************/
9b9bcba0 818 pb_InputStatus = (unsigned char *) &data[0];
c995fe94
ADG
819
820 dw_StatusReg =
821 inl(devpriv->s_BoardInfos.ui_Address +
822 (64 * b_ModulNbr));
823 *pb_InputStatus =
1783fbfe 824 (unsigned char) (((~dw_StatusReg) >> 4) & 7);
c995fe94
ADG
825 break;
826
827 default:
828 printk("IO type wrong\n");
829
2696fb57 830 } /* switch end */
c995fe94
ADG
831 } else {
832 /**********************************/
833 /* The module is not a SSI module */
834 /**********************************/
835
836 DPRINTK("The module is not a SSI module\n");
837 i_ReturnValue = -3;
838 }
839 } else {
840 /***********************/
841 /* Module number error */
842 /***********************/
843
844 DPRINTK("Module number error\n");
845 i_ReturnValue = -2;
846 }
847
dae0dc30 848 return i_ReturnValue;
c995fe94 849}