File: /usr/src/linux/drivers/isdn/eicon/fpga.c
1
2 /*
3 *
4 * Copyright (C) Eicon Technology Corporation, 2000.
5 *
6 * Eicon File Revision : 1.2
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
15 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24
25 #include "sys.h"
26 #include "idi.h"
27 #include "uxio.h"
28
29 #define FPGA_PORT 0x6E
30 #define FPGA_DLOAD_BUFLEN 256
31 #define NAME_OFFSET 0x10
32 #define NAME_MAXLEN 12
33 #define DATE_OFFSET 0x2c
34 #define DATE_MAXLEN 10
35
36 word UxCardPortIoInW(ux_diva_card_t *card, byte *base, int offset);
37 void UxCardPortIoOutW(ux_diva_card_t *card, byte *base, int offset, word);
38 void UxPause(long int);
39
40 /*-------------------------------------------------------------------------*/
41 /* Loads the FPGA configuration file onto the hardware. */
42 /* Function returns 0 on success, else an error number. */
43 /* On success, an identifier string is returned in the buffer */
44 /* */
45 /* A buffer of FPGA_BUFSIZE, a handle to the already opened bitstream */
46 /* file and a file read function has to be provided by the operating */
47 /* system part. */
48 /* ----------------------------------------------------------------------- */
49 int FPGA_Download( word cardtype,
50 dword RegBase,
51 byte *strbuf,
52 byte FPGA_SRC[],
53 int FPGA_LEN
54 )
55 {
56 word i, j, k;
57 word baseval, Mask_PROGRAM, Mask_DONE, Mask_CCLK, Mask_DIN;
58 dword addr;
59 byte *pFPGA;
60
61 //--- check for legal cardtype
62 switch (cardtype)
63 {
64 case IDI_ADAPTER_MAESTRAQ:
65 addr = RegBase ; // address where to access FPGA
66 Mask_PROGRAM = 0x0001; // FPGA pins at address
67 Mask_DONE = 0x0002;
68 Mask_CCLK = 0x0100;
69 Mask_DIN = 0x0400;
70 baseval = 0x000d; // PROGRAM hi, CCLK lo, DIN lo by default
71 break;
72
73 default:
74
75 DPRINTF(("divas: FPGA Download ,Illegal Card"));
76 return -1; // illegal card
77 }
78
79 //--- generate id string from file content
80 for (j=NAME_OFFSET, k=0; j<(NAME_OFFSET+NAME_MAXLEN); j++, k++) //name
81 {
82 if (!FPGA_SRC[j]) break;
83 strbuf[k] = FPGA_SRC[j];
84 }
85 strbuf[k++] = ' ';
86 for (j=DATE_OFFSET; j<(DATE_OFFSET+DATE_MAXLEN); j++, k++) // date
87 {
88 if (!FPGA_SRC[j]) break;
89 strbuf[k] = FPGA_SRC[j];
90 }
91 strbuf[k] = 0;
92
93 DPRINTF(("divas: FPGA Download - %s", strbuf));
94
95 //--- prepare download, Pulse PROGRAM pin down.
96 UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval &~Mask_PROGRAM); // PROGRAM low pulse
97 UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval); // release
98 UxPause(50); // wait until FPGA finised internal memory clear
99
100 //--- check done pin, must be low
101 if (UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT) &Mask_DONE)
102 {
103 DPRINTF(("divas: FPGA_ERR_DONE_WRONG_LEVEL"));
104 return -1;
105 }
106
107 pFPGA = FPGA_SRC;
108
109 i = 0;
110 /* Move past the header */
111 while ((FPGA_SRC[i] != 0xFF) && (i < FPGA_LEN))
112 {
113 i++;
114 }
115
116 // We've hit the 0xFF so move on to the next byte
117 // i++;
118 DPRINTF(("divas: FPGA Code starts at offset %d", i));
119
120 //--- put data onto the FPGA
121 for (;i<FPGA_LEN; i++)
122 {
123 //--- put byte onto FPGA
124 for (j=0; j<8; j++)
125 {
126 if (FPGA_SRC[i] &(0x80>>j)) baseval |= Mask_DIN; // write a hi
127 else baseval &=~Mask_DIN; // write a lo
128 UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval);
129 UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval | Mask_CCLK); // set CCLK hi
130 UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval); // set CCLK lo
131 }
132 }
133
134 //--- add some additional startup clock cycles and check done pin
135 for (i=0; i<5; i++)
136 {
137 UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval | Mask_CCLK); // set CCLK hi
138 UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval); // set CCLK lo
139 }
140
141 UxPause(100);
142
143 if (UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT) &Mask_DONE)
144 {
145 DPRINTF(("divas: FPGA download successful"));
146 }
147 else
148 {
149 DPRINTF(("divas: FPGA download failed - 0x%x", UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT)));
150 return -1;
151 }
152
153 return 0;
154 }
155
156