~ubuntu-branches/ubuntu/saucy/linux-n900/saucy

« back to all changes in this revision

Viewing changes to drivers/staging/comedi/drivers/addi-data/addi_eeprom.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Poirier
  • Date: 2011-02-18 09:43:31 UTC
  • Revision ID: james.westby@ubuntu.com-20110218094331-eyubsja4f9k0yhmq
Tags: 2.6.35-1.1
Initial release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 should also find the complete GPL in the COPYING file accompanying this source code.
 
21
 
 
22
@endverbatim
 
23
*/
 
24
/*
 
25
 
 
26
  +-----------------------------------------------------------------------+
 
27
  | (C) ADDI-DATA GmbH          Dieselstrasse 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   : ADDI DATA         | Compiler : GCC                                    |
 
33
  | Modulname : addi_eeprom.c     | Version  : 2.96                       |
 
34
  +-------------------------------+---------------------------------------+
 
35
  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
 
36
  +-----------------------------------------------------------------------+
 
37
  | Description : ADDI EEPROM  Module                                     |
 
38
  +-----------------------------------------------------------------------+
 
39
  |                             UPDATE'S                                  |
 
40
  +-----------------------------------------------------------------------+
 
41
  |   Date   |   Author  |          Description of updates                |
 
42
  +----------+-----------+------------------------------------------------+
 
43
  |          |           |                                                |
 
44
  |          |           |                                                |
 
45
  +----------+-----------+------------------------------------------------+
 
46
*/
 
47
 
 
48
#define NVCMD_BEGIN_READ        (0x7 << 5)      /*  nvRam begin read command */
 
49
#define NVCMD_LOAD_LOW          (0x4 << 5)      /*  nvRam load low command */
 
50
#define NVCMD_LOAD_HIGH         (0x5 << 5)      /*  nvRam load high command */
 
51
#define EE76_CMD_LEN            13      /*  bits in instructions */
 
52
#define EE_READ                 0x0180  /*  01 1000 0000 read instruction */
 
53
 
 
54
#define EEPROM_DIGITALINPUT                     0
 
55
#define EEPROM_DIGITALOUTPUT                    1
 
56
#define EEPROM_ANALOGINPUT                              2
 
57
#define EEPROM_ANALOGOUTPUT                             3
 
58
#define EEPROM_TIMER                                    4
 
59
#define EEPROM_WATCHDOG                                 5
 
60
#define EEPROM_TIMER_WATCHDOG_COUNTER   10
 
61
 
 
62
struct str_Functionality {
 
63
        unsigned char b_Type;
 
64
        unsigned short w_Address;
 
65
};
 
66
 
 
67
struct str_MainHeader {
 
68
        unsigned short w_HeaderSize;
 
69
        unsigned char b_Nfunctions;
 
70
        struct str_Functionality s_Functions[7];
 
71
};
 
72
 
 
73
struct str_DigitalInputHeader {
 
74
        unsigned short w_Nchannel;
 
75
        unsigned char b_Interruptible;
 
76
        unsigned short w_NinterruptLogic;
 
77
};
 
78
 
 
79
struct str_DigitalOutputHeader {
 
80
 
 
81
        unsigned short w_Nchannel;
 
82
};
 
83
 
 
84
 
 
85
/* used for timer as well as watchdog */
 
86
 
 
87
struct str_TimerDetails {
 
88
 
 
89
        unsigned short w_HeaderSize;
 
90
        unsigned char b_Resolution;
 
91
        unsigned char b_Mode;           /*  in case of Watchdog it is functionality */
 
92
        unsigned short w_MinTiming;
 
93
        unsigned char b_TimeBase;
 
94
};
 
95
 
 
96
struct str_TimerMainHeader {
 
97
 
 
98
 
 
99
        unsigned short w_Ntimer;
 
100
        struct str_TimerDetails s_TimerDetails[4];      /*   supports 4 timers */
 
101
};
 
102
 
 
103
 
 
104
typedef struct {
 
105
        unsigned short w_Nchannel;
 
106
        unsigned char b_Resolution;
 
107
} str_AnalogOutputHeader;
 
108
 
 
109
struct str_AnalogInputHeader {
 
110
        unsigned short w_Nchannel;
 
111
        unsigned short w_MinConvertTiming;
 
112
        unsigned short w_MinDelayTiming;
 
113
        unsigned char b_HasDma;
 
114
        unsigned char b_Resolution;
 
115
};
 
116
 
 
117
 
 
118
                /*****************************************/
 
119
                /*            Read Header Functions              */
 
120
                /*****************************************/
 
121
 
 
122
int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
 
123
        char *pc_PCIChipInformation, struct comedi_device *dev);
 
124
 
 
125
int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress,
 
126
        char *pc_PCIChipInformation, unsigned short w_Address,
 
127
        struct str_DigitalInputHeader *s_Header);
 
128
 
 
129
int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress,
 
130
        char *pc_PCIChipInformation, unsigned short w_Address,
 
131
        struct str_DigitalOutputHeader *s_Header);
 
132
 
 
133
int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
 
134
        char *pc_PCIChipInformation, unsigned short w_Address,
 
135
        struct str_TimerMainHeader *s_Header);
 
136
 
 
137
int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
 
138
        char *pc_PCIChipInformation, unsigned short w_Address,
 
139
        str_AnalogOutputHeader *s_Header);
 
140
 
 
141
int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
 
142
        char *pc_PCIChipInformation, unsigned short w_Address,
 
143
        struct str_AnalogInputHeader *s_Header);
 
144
 
 
145
                /******************************************/
 
146
                /*      Eeprom Specific Functions                         */
 
147
                /******************************************/
 
148
unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
 
149
        unsigned short w_EepromStartAddress);
 
150
void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress);
 
151
void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue);
 
152
void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress);
 
153
void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand,
 
154
        unsigned char b_DataLengthInBits);
 
155
void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value);
 
156
 
 
157
/*
 
158
+----------------------------------------------------------------------------+
 
159
| Function   Name   : unsigned short w_EepromReadWord                                  |
 
160
|                               (unsigned short w_PCIBoardEepromAddress,                         |
 
161
|                                char * pc_PCIChipInformation,                           |
 
162
|                                unsigned short   w_EepromStartAddress)                          |
 
163
+----------------------------------------------------------------------------+
 
164
| Task              : Read from eepromn a word                               |
 
165
+----------------------------------------------------------------------------+
 
166
| Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
 
167
|                                                                                                                                        |
 
168
|                     char *pc_PCIChipInformation  : PCI Chip Type.          |
 
169
|                                                                                                                                        |
 
170
|                     unsigned short w_EepromStartAddress    : Selected eeprom address |
 
171
+----------------------------------------------------------------------------+
 
172
| Output Parameters : -                                                      |
 
173
+----------------------------------------------------------------------------+
 
174
| Return Value      : Read word value from eeprom                            |
 
175
+----------------------------------------------------------------------------+
 
176
*/
 
177
 
 
178
unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
 
179
        unsigned short w_EepromStartAddress)
 
180
{
 
181
 
 
182
        unsigned char b_Counter = 0;
 
183
 
 
184
        unsigned char b_ReadByte = 0;
 
185
 
 
186
        unsigned char b_ReadLowByte = 0;
 
187
 
 
188
        unsigned char b_ReadHighByte = 0;
 
189
 
 
190
        unsigned char b_SelectedAddressLow = 0;
 
191
 
 
192
        unsigned char b_SelectedAddressHigh = 0;
 
193
 
 
194
        unsigned short w_ReadWord = 0;
 
195
 
 
196
        /**************************/
 
197
 
 
198
        /* Test the PCI chip type */
 
199
 
 
200
        /**************************/
 
201
 
 
202
        if ((!strcmp(pc_PCIChipInformation, "S5920")) ||
 
203
                (!strcmp(pc_PCIChipInformation, "S5933")))
 
204
        {
 
205
 
 
206
                for (b_Counter = 0; b_Counter < 2; b_Counter++)
 
207
                {
 
208
 
 
209
                        b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256;        /* Read the low 8 bit part */
 
210
 
 
211
                        b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256;       /* Read the high 8 bit part */
 
212
 
 
213
              /************************************/
 
214
 
 
215
                        /* Select the load low address mode */
 
216
 
 
217
              /************************************/
 
218
 
 
219
                        outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F);
 
220
 
 
221
              /****************/
 
222
 
 
223
                        /* Wait on busy */
 
224
 
 
225
              /****************/
 
226
 
 
227
                        v_EepromWaitBusy(w_PCIBoardEepromAddress);
 
228
 
 
229
              /************************/
 
230
 
 
231
                        /* Load the low address */
 
232
 
 
233
              /************************/
 
234
 
 
235
                        outb(b_SelectedAddressLow,
 
236
                                w_PCIBoardEepromAddress + 0x3E);
 
237
 
 
238
              /****************/
 
239
 
 
240
                        /* Wait on busy */
 
241
 
 
242
              /****************/
 
243
 
 
244
                        v_EepromWaitBusy(w_PCIBoardEepromAddress);
 
245
 
 
246
              /*************************************/
 
247
 
 
248
                        /* Select the load high address mode */
 
249
 
 
250
              /*************************************/
 
251
 
 
252
                        outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F);
 
253
 
 
254
              /****************/
 
255
 
 
256
                        /* Wait on busy */
 
257
 
 
258
              /****************/
 
259
 
 
260
                        v_EepromWaitBusy(w_PCIBoardEepromAddress);
 
261
 
 
262
              /*************************/
 
263
 
 
264
                        /* Load the high address */
 
265
 
 
266
              /*************************/
 
267
 
 
268
                        outb(b_SelectedAddressHigh,
 
269
                                w_PCIBoardEepromAddress + 0x3E);
 
270
 
 
271
              /****************/
 
272
 
 
273
                        /* Wait on busy */
 
274
 
 
275
              /****************/
 
276
 
 
277
                        v_EepromWaitBusy(w_PCIBoardEepromAddress);
 
278
 
 
279
              /************************/
 
280
 
 
281
                        /* Select the READ mode */
 
282
 
 
283
              /************************/
 
284
 
 
285
                        outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F);
 
286
 
 
287
              /****************/
 
288
 
 
289
                        /* Wait on busy */
 
290
 
 
291
              /****************/
 
292
 
 
293
                        v_EepromWaitBusy(w_PCIBoardEepromAddress);
 
294
 
 
295
              /*****************************/
 
296
 
 
297
                        /* Read data into the EEPROM */
 
298
 
 
299
              /*****************************/
 
300
 
 
301
                        b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E);
 
302
 
 
303
              /****************/
 
304
 
 
305
                        /* Wait on busy */
 
306
 
 
307
              /****************/
 
308
 
 
309
                        v_EepromWaitBusy(w_PCIBoardEepromAddress);
 
310
 
 
311
              /*********************************/
 
312
 
 
313
                        /* Select the upper address part */
 
314
 
 
315
              /*********************************/
 
316
 
 
317
                        if (b_Counter == 0)
 
318
                        {
 
319
 
 
320
                                b_ReadLowByte = b_ReadByte;
 
321
 
 
322
                        }       /*  if(b_Counter==0) */
 
323
 
 
324
                        else
 
325
                        {
 
326
 
 
327
                                b_ReadHighByte = b_ReadByte;
 
328
 
 
329
                        }       /*  if(b_Counter==0) */
 
330
 
 
331
                }               /*  for (b_Counter=0; b_Counter<2; b_Counter++) */
 
332
 
 
333
                w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256));
 
334
 
 
335
        }                       /*  end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) */
 
336
 
 
337
        if (!strcmp(pc_PCIChipInformation, "93C76"))
 
338
        {
 
339
 
 
340
           /*************************************/
 
341
 
 
342
                /* Read 16 bit from the EEPROM 93C76 */
 
343
 
 
344
           /*************************************/
 
345
 
 
346
                v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress,
 
347
                        &w_ReadWord);
 
348
 
 
349
        }
 
350
 
 
351
        return w_ReadWord;
 
352
 
 
353
}
 
354
 
 
355
/*
 
356
 
 
357
+----------------------------------------------------------------------------+
 
358
 
 
359
| Function   Name   : void v_EepromWaitBusy                                  |
 
360
 
 
361
|                       (unsigned short w_PCIBoardEepromAddress)                         |
 
362
 
 
363
+----------------------------------------------------------------------------+
 
364
 
 
365
| Task              : Wait the busy flag from PCI controller                 |
 
366
 
 
367
+----------------------------------------------------------------------------+
 
368
 
 
369
| Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom base address |
 
370
 
 
371
+----------------------------------------------------------------------------+
 
372
 
 
373
| Output Parameters : -                                                      |
 
374
 
 
375
+----------------------------------------------------------------------------+
 
376
 
 
377
| Return Value      : -                                                      |
 
378
 
 
379
+----------------------------------------------------------------------------+
 
380
 
 
381
*/
 
382
 
 
383
void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress)
 
384
{
 
385
 
 
386
        unsigned char b_EepromBusy = 0;
 
387
 
 
388
        do
 
389
        {
 
390
 
 
391
           /*************/
 
392
 
 
393
                /* IMPORTANT */
 
394
 
 
395
           /*************/
 
396
 
 
397
           /************************************************************************/
 
398
 
 
399
                /* An error has been written in the AMCC 5933 book at the page B-13 */
 
400
 
 
401
                /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and   */
 
402
 
 
403
                /*      the operator register is AMCC_OP_REG_MCSR+3 */
 
404
 
 
405
                /*      unsigned short read  EEPROM=0x8000 andAMCC_OP_REG_MCSR+2                  */
 
406
 
 
407
                /*      unsigned int read  EEPROM=0x80000000 and AMCC_OP_REG_MCSR */
 
408
 
 
409
           /************************************************************************/
 
410
 
 
411
                b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F);
 
412
                b_EepromBusy = b_EepromBusy & 0x80;
 
413
 
 
414
        } while (b_EepromBusy == 0x80);
 
415
 
 
416
}
 
417
 
 
418
/*
 
419
 
 
420
+---------------------------------------------------------------------------------+
 
421
 
 
422
| Function   Name   : void v_EepromClock76(unsigned int dw_Address,                      |
 
423
 
 
424
|                                          unsigned int dw_RegisterValue)                                         |
 
425
 
 
426
+---------------------------------------------------------------------------------+
 
427
 
 
428
| Task              : This function sends the clocking sequence to the EEPROM.    |
 
429
 
 
430
+---------------------------------------------------------------------------------+
 
431
 
 
432
| Input Parameters  : unsigned int dw_Address : PCI eeprom base address                  |
 
433
 
 
434
|                     unsigned int dw_RegisterValue : PCI eeprom register value to write.|
 
435
 
 
436
+---------------------------------------------------------------------------------+
 
437
 
 
438
| Output Parameters : -                                                           |
 
439
 
 
440
+---------------------------------------------------------------------------------+
 
441
 
 
442
| Return Value      : -                                                           |
 
443
 
 
444
+---------------------------------------------------------------------------------+
 
445
 
 
446
*/
 
447
 
 
448
void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue)
 
449
{
 
450
 
 
451
   /************************/
 
452
 
 
453
        /* Set EEPROM clock Low */
 
454
 
 
455
   /************************/
 
456
 
 
457
        outl(dw_RegisterValue & 0x6, dw_Address);
 
458
 
 
459
   /***************/
 
460
 
 
461
        /* Wait 0.1 ms */
 
462
 
 
463
   /***************/
 
464
 
 
465
        udelay(100);
 
466
 
 
467
   /*************************/
 
468
 
 
469
        /* Set EEPROM clock High */
 
470
 
 
471
   /*************************/
 
472
 
 
473
        outl(dw_RegisterValue | 0x1, dw_Address);
 
474
 
 
475
   /***************/
 
476
 
 
477
        /* Wait 0.1 ms */
 
478
 
 
479
   /***************/
 
480
 
 
481
        udelay(100);
 
482
 
 
483
}
 
484
 
 
485
/*
 
486
 
 
487
+---------------------------------------------------------------------------------+
 
488
 
 
489
| Function   Name   : void v_EepromSendCommand76(unsigned int dw_Address,                |
 
490
 
 
491
|                                          unsigned int   dw_EepromCommand,                               |
 
492
 
 
493
|                                          unsigned char    b_DataLengthInBits)                        |
 
494
 
 
495
+---------------------------------------------------------------------------------+
 
496
 
 
497
| Task              : This function sends a Command to the EEPROM 93C76.          |
 
498
 
 
499
+---------------------------------------------------------------------------------+
 
500
 
 
501
| Input Parameters  : unsigned int dw_Address : PCI eeprom base address                  |
 
502
 
 
503
|                     unsigned int dw_EepromCommand : PCI eeprom command to write.       |
 
504
 
 
505
|                     unsigned char  b_DataLengthInBits : PCI eeprom command data length.  |
 
506
 
 
507
+---------------------------------------------------------------------------------+
 
508
 
 
509
| Output Parameters : -                                                           |
 
510
 
 
511
+---------------------------------------------------------------------------------+
 
512
 
 
513
| Return Value      : -                                                           |
 
514
 
 
515
+---------------------------------------------------------------------------------+
 
516
 
 
517
*/
 
518
 
 
519
void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand,
 
520
        unsigned char b_DataLengthInBits)
 
521
{
 
522
 
 
523
        char c_BitPos = 0;
 
524
 
 
525
        unsigned int dw_RegisterValue = 0;
 
526
 
 
527
   /*****************************/
 
528
 
 
529
        /* Enable EEPROM Chip Select */
 
530
 
 
531
   /*****************************/
 
532
 
 
533
        dw_RegisterValue = 0x2;
 
534
 
 
535
   /********************************************************************/
 
536
 
 
537
        /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
 
538
 
 
539
   /********************************************************************/
 
540
 
 
541
        outl(dw_RegisterValue, dw_Address);
 
542
 
 
543
   /***************/
 
544
 
 
545
        /* Wait 0.1 ms */
 
546
 
 
547
   /***************/
 
548
 
 
549
        udelay(100);
 
550
 
 
551
   /*******************************************/
 
552
 
 
553
        /* Send EEPROM command - one bit at a time */
 
554
 
 
555
   /*******************************************/
 
556
 
 
557
        for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--)
 
558
        {
 
559
 
 
560
      /**********************************/
 
561
 
 
562
                /* Check if current bit is 0 or 1 */
 
563
 
 
564
      /**********************************/
 
565
 
 
566
                if (dw_EepromCommand & (1 << c_BitPos))
 
567
                {
 
568
 
 
569
         /***********/
 
570
 
 
571
                        /* Write 1 */
 
572
 
 
573
         /***********/
 
574
 
 
575
                        dw_RegisterValue = dw_RegisterValue | 0x4;
 
576
 
 
577
                }
 
578
 
 
579
                else
 
580
                {
 
581
 
 
582
         /***********/
 
583
 
 
584
                        /* Write 0 */
 
585
 
 
586
         /***********/
 
587
 
 
588
                        dw_RegisterValue = dw_RegisterValue & 0x3;
 
589
 
 
590
                }
 
591
 
 
592
      /*********************/
 
593
 
 
594
                /* Write the command */
 
595
 
 
596
      /*********************/
 
597
 
 
598
                outl(dw_RegisterValue, dw_Address);
 
599
 
 
600
      /***************/
 
601
 
 
602
                /* Wait 0.1 ms */
 
603
 
 
604
      /***************/
 
605
 
 
606
                udelay(100);
 
607
 
 
608
      /****************************/
 
609
 
 
610
                /* Trigger the EEPROM clock */
 
611
 
 
612
      /****************************/
 
613
 
 
614
                v_EepromClock76(dw_Address, dw_RegisterValue);
 
615
 
 
616
        }
 
617
 
 
618
}
 
619
 
 
620
/*
 
621
 
 
622
+---------------------------------------------------------------------------------+
 
623
 
 
624
| Function   Name   : void v_EepromCs76Read(unsigned int dw_Address,                     |
 
625
 
 
626
|                                          unsigned short    w_offset,                                            |
 
627
 
 
628
|                                          unsigned short *   pw_Value)                                           |
 
629
 
 
630
+---------------------------------------------------------------------------------+
 
631
 
 
632
| Task              : This function read a value from the EEPROM 93C76.           |
 
633
 
 
634
+---------------------------------------------------------------------------------+
 
635
 
 
636
| Input Parameters  : unsigned int dw_Address : PCI eeprom base address                  |
 
637
 
 
638
|                     unsigned short    w_offset : Offset of the adress to read             |
 
639
 
 
640
|                     unsigned short *   pw_Value : PCI eeprom 16 bit read value.            |
 
641
 
 
642
+---------------------------------------------------------------------------------+
 
643
 
 
644
| Output Parameters : -                                                           |
 
645
 
 
646
+---------------------------------------------------------------------------------+
 
647
 
 
648
| Return Value      : -                                                           |
 
649
 
 
650
+---------------------------------------------------------------------------------+
 
651
 
 
652
*/
 
653
 
 
654
void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value)
 
655
{
 
656
 
 
657
        char c_BitPos = 0;
 
658
 
 
659
        unsigned int dw_RegisterValue = 0;
 
660
 
 
661
        unsigned int dw_RegisterValueRead = 0;
 
662
 
 
663
   /*************************************************/
 
664
 
 
665
        /* Send EEPROM read command and offset to EEPROM */
 
666
 
 
667
   /*************************************************/
 
668
 
 
669
        v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2),
 
670
                EE76_CMD_LEN);
 
671
 
 
672
   /*******************************/
 
673
 
 
674
        /* Get the last register value */
 
675
 
 
676
   /*******************************/
 
677
 
 
678
        dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2;
 
679
 
 
680
   /*****************************/
 
681
 
 
682
        /* Set the 16-bit value of 0 */
 
683
 
 
684
   /*****************************/
 
685
 
 
686
        *pw_Value = 0;
 
687
 
 
688
   /************************/
 
689
 
 
690
        /* Get the 16-bit value */
 
691
 
 
692
   /************************/
 
693
 
 
694
        for (c_BitPos = 0; c_BitPos < 16; c_BitPos++)
 
695
        {
 
696
 
 
697
      /****************************/
 
698
 
 
699
                /* Trigger the EEPROM clock */
 
700
 
 
701
      /****************************/
 
702
 
 
703
                v_EepromClock76(dw_Address, dw_RegisterValue);
 
704
 
 
705
      /**********************/
 
706
 
 
707
                /* Get the result bit */
 
708
 
 
709
      /**********************/
 
710
 
 
711
                dw_RegisterValueRead = inl(dw_Address);
 
712
 
 
713
      /***************/
 
714
 
 
715
                /* Wait 0.1 ms */
 
716
 
 
717
      /***************/
 
718
 
 
719
                udelay(100);
 
720
 
 
721
      /***************************************/
 
722
 
 
723
                /* Get bit value and shift into result */
 
724
 
 
725
      /***************************************/
 
726
 
 
727
                if (dw_RegisterValueRead & 0x8)
 
728
                {
 
729
 
 
730
         /**********/
 
731
 
 
732
                        /* Read 1 */
 
733
 
 
734
         /**********/
 
735
 
 
736
                        *pw_Value = (*pw_Value << 1) | 0x1;
 
737
 
 
738
                }
 
739
 
 
740
                else
 
741
                {
 
742
 
 
743
         /**********/
 
744
 
 
745
                        /* Read 0 */
 
746
 
 
747
         /**********/
 
748
 
 
749
                        *pw_Value = (*pw_Value << 1);
 
750
 
 
751
                }
 
752
 
 
753
        }
 
754
 
 
755
   /*************************/
 
756
 
 
757
        /* Clear all EEPROM bits */
 
758
 
 
759
   /*************************/
 
760
 
 
761
        dw_RegisterValue = 0x0;
 
762
 
 
763
   /********************************************************************/
 
764
 
 
765
        /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
 
766
 
 
767
   /********************************************************************/
 
768
 
 
769
        outl(dw_RegisterValue, dw_Address);
 
770
 
 
771
   /***************/
 
772
 
 
773
        /* Wait 0.1 ms */
 
774
 
 
775
   /***************/
 
776
 
 
777
        udelay(100);
 
778
 
 
779
}
 
780
 
 
781
        /******************************************/
 
782
        /*      EEPROM HEADER READ FUNCTIONS      */
 
783
        /******************************************/
 
784
 
 
785
/*
 
786
+----------------------------------------------------------------------------+
 
787
| Function Name  : int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,  |
 
788
|                               char *  pc_PCIChipInformation,struct comedi_device *dev)    |
 
789
+----------------------------------------------------------------------------+
 
790
| Task              : Read from eeprom Main Header                           |
 
791
+----------------------------------------------------------------------------+
 
792
| Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
 
793
|                                                                                                                                        |
 
794
|                     char *pc_PCIChipInformation  : PCI Chip Type.          |
 
795
|                                                                                                                                        |
 
796
|                         struct comedi_device *dev                : comedi device structure |
 
797
|                                                                                        pointer                                 |
 
798
+----------------------------------------------------------------------------+
 
799
| Output Parameters : -                                                      |
 
800
+----------------------------------------------------------------------------+
 
801
| Return Value      : 0                                                                              |
 
802
+----------------------------------------------------------------------------+
 
803
*/
 
804
 
 
805
int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
 
806
        char *pc_PCIChipInformation, struct comedi_device *dev)
 
807
{
 
808
        unsigned short w_Temp, i, w_Count = 0;
 
809
        unsigned int ui_Temp;
 
810
        struct str_MainHeader s_MainHeader;
 
811
        struct str_DigitalInputHeader s_DigitalInputHeader;
 
812
        struct str_DigitalOutputHeader s_DigitalOutputHeader;
 
813
        /* struct str_TimerMainHeader     s_TimerMainHeader,s_WatchdogMainHeader; */
 
814
        str_AnalogOutputHeader s_AnalogOutputHeader;
 
815
        struct str_AnalogInputHeader s_AnalogInputHeader;
 
816
 
 
817
        /* Read size */
 
818
        s_MainHeader.w_HeaderSize =
 
819
                w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
 
820
                0x100 + 8);
 
821
 
 
822
        /* Read nbr of functionality */
 
823
        w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
 
824
                pc_PCIChipInformation, 0x100 + 10);
 
825
        s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF;
 
826
 
 
827
        /* Read functionality details */
 
828
        for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
 
829
                /* Read Type */
 
830
                w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
 
831
                        pc_PCIChipInformation, 0x100 + 12 + w_Count);
 
832
                s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F;
 
833
                w_Count = w_Count + 2;
 
834
                /* Read Address */
 
835
                s_MainHeader.s_Functions[i].w_Address =
 
836
                        w_EepromReadWord(w_PCIBoardEepromAddress,
 
837
                        pc_PCIChipInformation, 0x100 + 12 + w_Count);
 
838
                w_Count = w_Count + 2;
 
839
        }
 
840
 
 
841
        /* Display main header info */
 
842
        for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
 
843
 
 
844
                switch (s_MainHeader.s_Functions[i].b_Type) {
 
845
                case EEPROM_DIGITALINPUT:
 
846
                        i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress,
 
847
                                pc_PCIChipInformation,
 
848
                                s_MainHeader.s_Functions[i].w_Address,
 
849
                                &s_DigitalInputHeader);
 
850
                        this_board->i_NbrDiChannel =
 
851
                                s_DigitalInputHeader.w_Nchannel;
 
852
                        break;
 
853
 
 
854
                case EEPROM_DIGITALOUTPUT:
 
855
                        i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress,
 
856
                                pc_PCIChipInformation,
 
857
                                s_MainHeader.s_Functions[i].w_Address,
 
858
                                &s_DigitalOutputHeader);
 
859
                        this_board->i_NbrDoChannel =
 
860
                                s_DigitalOutputHeader.w_Nchannel;
 
861
                        ui_Temp = 0xffffffff;
 
862
                        this_board->i_DoMaxdata =
 
863
                                ui_Temp >> (32 - this_board->i_NbrDoChannel);
 
864
                        break;
 
865
 
 
866
                case EEPROM_ANALOGINPUT:
 
867
                        i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress,
 
868
                                pc_PCIChipInformation,
 
869
                                s_MainHeader.s_Functions[i].w_Address,
 
870
                                &s_AnalogInputHeader);
 
871
                        if (!(strcmp(this_board->pc_DriverName, "apci3200")))
 
872
                                this_board->i_NbrAiChannel =
 
873
                                        s_AnalogInputHeader.w_Nchannel * 4;
 
874
                        else
 
875
                                this_board->i_NbrAiChannel =
 
876
                                        s_AnalogInputHeader.w_Nchannel;
 
877
                        this_board->i_Dma = s_AnalogInputHeader.b_HasDma;
 
878
                        this_board->ui_MinAcquisitiontimeNs =
 
879
                                (unsigned int) s_AnalogInputHeader.w_MinConvertTiming *
 
880
                                1000;
 
881
                        this_board->ui_MinDelaytimeNs =
 
882
                                (unsigned int) s_AnalogInputHeader.w_MinDelayTiming *
 
883
                                1000;
 
884
                        ui_Temp = 0xffff;
 
885
                        this_board->i_AiMaxdata =
 
886
                                ui_Temp >> (16 -
 
887
                                s_AnalogInputHeader.b_Resolution);
 
888
                        break;
 
889
 
 
890
                case EEPROM_ANALOGOUTPUT:
 
891
                        i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress,
 
892
                                pc_PCIChipInformation,
 
893
                                s_MainHeader.s_Functions[i].w_Address,
 
894
                                &s_AnalogOutputHeader);
 
895
                        this_board->i_NbrAoChannel =
 
896
                                s_AnalogOutputHeader.w_Nchannel;
 
897
                        ui_Temp = 0xffff;
 
898
                        this_board->i_AoMaxdata =
 
899
                                ui_Temp >> (16 -
 
900
                                s_AnalogOutputHeader.b_Resolution);
 
901
                        break;
 
902
 
 
903
                case EEPROM_TIMER:
 
904
                        this_board->i_Timer = 1;        /* Timer subdevice present */
 
905
                        break;
 
906
 
 
907
                case EEPROM_WATCHDOG:
 
908
                        this_board->i_Timer = 1;        /* Timer subdevice present */
 
909
                        break;
 
910
 
 
911
                case EEPROM_TIMER_WATCHDOG_COUNTER:
 
912
                        this_board->i_Timer = 1;        /* Timer subdevice present */
 
913
                }
 
914
        }
 
915
 
 
916
        return 0;
 
917
}
 
918
 
 
919
/*
 
920
+----------------------------------------------------------------------------+
 
921
| Function Name  : int i_EepromReadDigitalInputHeader(unsigned short                                     |
 
922
|                       w_PCIBoardEepromAddress,char *pc_PCIChipInformation,     |
 
923
|                       unsigned short w_Address,struct str_DigitalInputHeader *s_Header)                |
 
924
|                                                                                                                                        |
 
925
+----------------------------------------------------------------------------+
 
926
| Task              : Read Digital Input Header                              |
 
927
+----------------------------------------------------------------------------+
 
928
| Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
 
929
|                                                                                                                                        |
 
930
|                     char *pc_PCIChipInformation  : PCI Chip Type.          |
 
931
|                                                                                                                                        |
 
932
|                        struct str_DigitalInputHeader *s_Header: Digita Input Header   |
 
933
|                                                                                                  Pointer                       |
 
934
+----------------------------------------------------------------------------+
 
935
| Output Parameters : -                                                      |
 
936
+----------------------------------------------------------------------------+
 
937
| Return Value      : 0                                                                              |
 
938
+----------------------------------------------------------------------------+
 
939
*/
 
940
int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress,
 
941
        char *pc_PCIChipInformation, unsigned short w_Address,
 
942
        struct str_DigitalInputHeader *s_Header)
 
943
{
 
944
        unsigned short w_Temp;
 
945
 
 
946
        /*  read nbr of channels */
 
947
        s_Header->w_Nchannel =
 
948
                w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
 
949
                0x100 + w_Address + 6);
 
950
 
 
951
        /*  interruptible or not */
 
952
        w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
 
953
                pc_PCIChipInformation, 0x100 + w_Address + 8);
 
954
        s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01;
 
955
 
 
956
/* How many interruptible logic */
 
957
        s_Header->w_NinterruptLogic =
 
958
                w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
 
959
                0x100 + w_Address + 10);
 
960
 
 
961
        return 0;
 
962
}
 
963
 
 
964
/*
 
965
+----------------------------------------------------------------------------+
 
966
| Function Name  : int i_EepromReadDigitalOutputHeader(unsigned short                            |
 
967
|                       w_PCIBoardEepromAddress,char *pc_PCIChipInformation,     |
 
968
|                       unsigned short w_Address,struct str_DigitalOutputHeader *s_Header)           |
 
969
|                                                                                                                                        |
 
970
+----------------------------------------------------------------------------+
 
971
| Task              : Read Digital Output Header                             |
 
972
+----------------------------------------------------------------------------+
 
973
| Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
 
974
|                                                                                                                                        |
 
975
|                     char *pc_PCIChipInformation  : PCI Chip Type.          |
 
976
|                                                                                                                                        |
 
977
|                        struct str_DigitalOutputHeader *s_Header: Digital Output Header|
 
978
|                                                                                          Pointer                               |
 
979
+----------------------------------------------------------------------------+
 
980
| Output Parameters : -                                                      |
 
981
+----------------------------------------------------------------------------+
 
982
| Return Value      : 0                                                                              |
 
983
+----------------------------------------------------------------------------+
 
984
*/
 
985
int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress,
 
986
        char *pc_PCIChipInformation, unsigned short w_Address,
 
987
        struct str_DigitalOutputHeader *s_Header)
 
988
{
 
989
/* Read Nbr channels */
 
990
        s_Header->w_Nchannel =
 
991
                w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
 
992
                0x100 + w_Address + 6);
 
993
        return 0;
 
994
}
 
995
 
 
996
/*
 
997
+----------------------------------------------------------------------------+
 
998
| Function Name  : int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, |
 
999
|                       char *pc_PCIChipInformation,WORD w_Address,                              |
 
1000
|                       struct str_TimerMainHeader *s_Header)                                                    |
 
1001
+----------------------------------------------------------------------------+
 
1002
| Task              : Read Timer or Watchdog Header                          |
 
1003
+----------------------------------------------------------------------------+
 
1004
| Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
 
1005
|                                                                                                                                        |
 
1006
|                     char *pc_PCIChipInformation  : PCI Chip Type.          |
 
1007
|                                                                                                                                        |
 
1008
|                        struct str_TimerMainHeader *s_Header: Timer Header                      |
 
1009
|                                                                                          Pointer                               |
 
1010
+----------------------------------------------------------------------------+
 
1011
| Output Parameters : -                                                      |
 
1012
+----------------------------------------------------------------------------+
 
1013
| Return Value      : 0                                                                              |
 
1014
+----------------------------------------------------------------------------+
 
1015
*/
 
1016
int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
 
1017
        char *pc_PCIChipInformation, unsigned short w_Address,
 
1018
        struct str_TimerMainHeader *s_Header)
 
1019
{
 
1020
 
 
1021
        unsigned short i, w_Size = 0, w_Temp;
 
1022
 
 
1023
/* Read No of Timer */
 
1024
        s_Header->w_Ntimer =
 
1025
                w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
 
1026
                0x100 + w_Address + 6);
 
1027
/* Read header size */
 
1028
 
 
1029
        for (i = 0; i < s_Header->w_Ntimer; i++) {
 
1030
                s_Header->s_TimerDetails[i].w_HeaderSize =
 
1031
                        w_EepromReadWord(w_PCIBoardEepromAddress,
 
1032
                        pc_PCIChipInformation,
 
1033
                        0x100 + w_Address + 8 + w_Size + 0);
 
1034
                w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
 
1035
                        pc_PCIChipInformation,
 
1036
                        0x100 + w_Address + 8 + w_Size + 2);
 
1037
 
 
1038
                /* Read Resolution */
 
1039
                s_Header->s_TimerDetails[i].b_Resolution =
 
1040
                        (unsigned char) (w_Temp >> 10) & 0x3F;
 
1041
 
 
1042
                /* Read Mode */
 
1043
                s_Header->s_TimerDetails[i].b_Mode =
 
1044
                        (unsigned char) (w_Temp >> 4) & 0x3F;
 
1045
 
 
1046
                w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
 
1047
                        pc_PCIChipInformation,
 
1048
                        0x100 + w_Address + 8 + w_Size + 4);
 
1049
 
 
1050
                /* Read MinTiming */
 
1051
                s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF;
 
1052
 
 
1053
                /* Read Timebase */
 
1054
                s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F;
 
1055
                w_Size += s_Header->s_TimerDetails[i].w_HeaderSize;
 
1056
        }
 
1057
 
 
1058
        return 0;
 
1059
}
 
1060
 
 
1061
/*
 
1062
+----------------------------------------------------------------------------+
 
1063
| Function Name  : int i_EepromReadAnlogOutputHeader(unsigned short                                      |
 
1064
|                       w_PCIBoardEepromAddress,char *pc_PCIChipInformation,     |
 
1065
|                       unsigned short w_Address,str_AnalogOutputHeader *s_Header)         |
 
1066
+----------------------------------------------------------------------------+
 
1067
| Task              : Read Nalog Output  Header                              |
 
1068
+----------------------------------------------------------------------------+
 
1069
| Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
 
1070
|                                                                                                                                        |
 
1071
|                     char *pc_PCIChipInformation  : PCI Chip Type.          |
 
1072
|                                                                                                                                        |
 
1073
|                        str_AnalogOutputHeader *s_Header:Anlog Output Header    |
 
1074
|                                                                                          Pointer                               |
 
1075
+----------------------------------------------------------------------------+
 
1076
| Output Parameters : -                                                      |
 
1077
+----------------------------------------------------------------------------+
 
1078
| Return Value      : 0                                                                              |
 
1079
+----------------------------------------------------------------------------+
 
1080
*/
 
1081
 
 
1082
int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
 
1083
        char *pc_PCIChipInformation, unsigned short w_Address,
 
1084
        str_AnalogOutputHeader *s_Header)
 
1085
{
 
1086
        unsigned short w_Temp;
 
1087
        /*  No of channels for 1st hard component */
 
1088
        w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
 
1089
                pc_PCIChipInformation, 0x100 + w_Address + 10);
 
1090
        s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
 
1091
        /*  Resolution for 1st hard component */
 
1092
        w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
 
1093
                pc_PCIChipInformation, 0x100 + w_Address + 16);
 
1094
        s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF;
 
1095
        return 0;
 
1096
}
 
1097
 
 
1098
/*
 
1099
+----------------------------------------------------------------------------+
 
1100
| Function Name  : int i_EepromReadAnlogInputHeader(unsigned short                                       |
 
1101
|                       w_PCIBoardEepromAddress,char *pc_PCIChipInformation,     |
 
1102
|                       unsigned short w_Address,struct str_AnalogInputHeader *s_Header)          |
 
1103
+----------------------------------------------------------------------------+
 
1104
| Task              : Read Nalog Output  Header                              |
 
1105
+----------------------------------------------------------------------------+
 
1106
| Input Parameters  : unsigned short w_PCIBoardEepromAddress : PCI eeprom address      |
 
1107
|                                                                                                                                        |
 
1108
|                     char *pc_PCIChipInformation  : PCI Chip Type.          |
 
1109
|                                                                                                                                        |
 
1110
|                        struct str_AnalogInputHeader *s_Header:Anlog Input Header      |
 
1111
|                                                                                          Pointer                               |
 
1112
+----------------------------------------------------------------------------+
 
1113
| Output Parameters : -                                                      |
 
1114
+----------------------------------------------------------------------------+
 
1115
| Return Value      : 0                                                                              |
 
1116
+----------------------------------------------------------------------------+
 
1117
*/
 
1118
 
 
1119
/* Reads only for ONE  hardware component */
 
1120
int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
 
1121
        char *pc_PCIChipInformation, unsigned short w_Address,
 
1122
        struct str_AnalogInputHeader *s_Header)
 
1123
{
 
1124
        unsigned short w_Temp, w_Offset;
 
1125
        w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
 
1126
                pc_PCIChipInformation, 0x100 + w_Address + 10);
 
1127
        s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
 
1128
        s_Header->w_MinConvertTiming =
 
1129
                w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
 
1130
                0x100 + w_Address + 16);
 
1131
        s_Header->w_MinDelayTiming =
 
1132
                w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
 
1133
                0x100 + w_Address + 30);
 
1134
        w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
 
1135
                pc_PCIChipInformation, 0x100 + w_Address + 20);
 
1136
        s_Header->b_HasDma = (w_Temp >> 13) & 0x01;     /*  whether dma present or not */
 
1137
 
 
1138
        w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72);      /*  reading Y */
 
1139
        w_Temp = w_Temp & 0x00FF;
 
1140
        if (w_Temp)             /* Y>0 */
 
1141
        {
 
1142
                w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16)));      /*  offset of first analog input single header */
 
1143
                w_Offset = w_Offset + 2;        /*  resolution */
 
1144
        } else                  /* Y=0 */
 
1145
        {
 
1146
                w_Offset = 74;
 
1147
                w_Offset = w_Offset + 2;        /*  resolution */
 
1148
        }
 
1149
 
 
1150
/* read Resolution */
 
1151
        w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
 
1152
                pc_PCIChipInformation, 0x100 + w_Address + w_Offset);
 
1153
        s_Header->b_Resolution = w_Temp & 0x001F;       /*  last 5 bits */
 
1154
 
 
1155
        return 0;
 
1156
}