update atp870u driver to 0.78 from D-Link source
[linux-2.4.git] / drivers / isdn / eicon / lincfg.c
1 /*
2  * Copyright (C) Eicon Technology Corporation, 2000.
3  *
4  * Eicon File Revision :    1.9  
5  *
6  * This software may be used and distributed according to the terms
7  * of the GNU General Public License, incorporated herein by reference.
8  *
9  */
10
11 #include <linux/fs.h>
12 #undef N_DATA   /* Because we have our own definition */
13
14 #include <asm/segment.h>
15 #include <asm/io.h>
16
17 #include "sys.h"
18 #include "idi.h"
19 #include "constant.h"
20 #include "divas.h"
21 #undef ID_MASK
22 #include "pc.h"
23 #include "pr_pc.h"
24
25 #include "adapter.h"
26 #include "uxio.h"
27
28 #include <linux/pci.h>
29 #include <linux/kernel.h>
30 #include <linux/ioport.h>
31
32 struct file_operations Divas_fops;
33 int Divas_major;
34
35 extern int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile, 
36                          unsigned int command, unsigned long arg);
37 extern unsigned int do_poll(struct file *pFile, struct poll_table_struct *pPollTable);
38 extern ssize_t do_read(struct file *pFile, char *pUserBuffer, size_t BufferSize, loff_t *pOffset);
39 extern int do_open(struct inode *, struct file *);
40 extern int do_release(struct inode *, struct file *);
41
42 int FPGA_Done=0;
43
44 int DivasCardsDiscover(void)
45 {
46         word wNumCards = 0, wDeviceIndex = 0;
47         byte byBus, byFunc;
48         word wPCIConsultation, PCItmp;
49         dword j, i;
50         unsigned int PCIserial;
51         dia_card_t Card;
52         byte *b;
53         
54         while (wDeviceIndex < 10)
55         {
56                 wPCIConsultation = pcibios_find_device(PCI_VENDOR_ID_EICON, 
57                                 PCI_DEVICE_ID_EICON_MAESTRAQ, 
58                                 wDeviceIndex, 
59                                 &byBus, &byFunc);
60
61                 if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
62                 {
63
64                         dword dwRAM, dwDivasIOBase, dwCFG, dwCTL;                       
65                         byte byIRQ;
66                         
67                         printk(KERN_DEBUG "Divas: DIVA Server 4BRI Found\n");
68                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2,(unsigned int *) &dwRAM);
69                         dwRAM &= 0xFFC00000;
70                         
71                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1,(unsigned int *) &dwDivasIOBase);
72                         dwDivasIOBase &= 0xFFFFFF00;
73                         
74                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_0,(unsigned int *) &dwCFG);
75                         dwCFG &= 0xFFFFFF00;
76                         
77                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_3,(unsigned int *) &dwCTL);
78                         dwCTL &= 0xFFFFE000;
79                         
80
81                         pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
82                         /* Retrieve the serial number */
83
84                         pcibios_write_config_word(byBus,byFunc,0x4E,0x00FC);
85
86                         for (j=0, PCItmp=0; j<10000 && !PCItmp; j++)
87                         {
88                                 pcibios_read_config_word(byBus,byFunc,0x4E, &PCItmp);
89                                 PCItmp &= 0x8000;  // extract done flag
90                         }
91
92                         pcibios_read_config_dword(byBus,byFunc,0x50, &PCIserial);
93
94                 
95                         Card.memory[DIVAS_RAM_MEMORY] = ioremap(dwRAM, 0x400000);
96                         Card.memory[DIVAS_CTL_MEMORY] = ioremap(dwCTL, 0x2000);
97                         Card.memory[DIVAS_CFG_MEMORY] = ioremap(dwCFG, 0x100);
98                         Card.io_base=dwDivasIOBase;
99
100                         Card.irq = byIRQ;
101                         
102                         Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_Q;
103                         Card.bus_type = DIA_BUS_TYPE_PCI;
104         
105                         FPGA_Done = 0;
106
107                         /* Create four virtual card structures as we want to treat 
108                            the 4Bri card as 4 Bri cards*/
109                         for(i=0;i<4;i++)
110                         {
111
112                                 b=Card.memory[DIVAS_RAM_MEMORY];
113                                 b+=(MQ_PROTCODE_OFFSET) * (i==0?0:1); 
114                                 DPRINTF(("divas: offset = 0x%x", i* MQ_PROTCODE_OFFSET));
115                                 Card.memory[DIVAS_RAM_MEMORY]=b;
116  
117                                 b = Card.memory[DIVAS_RAM_MEMORY];
118                                 b += MQ_SM_OFFSET;
119                                 Card.memory[DIVAS_SHARED_MEMORY] = b;
120
121                                 Card.bus_num = byBus;
122                                 Card.func_num = byFunc;
123                                 Card.slot = -1;
124
125                         
126                                 /* Fill in Name */
127                                 Card.name[0] = 'D';
128                                 Card.name[1] = 'I';
129                                 Card.name[2] = 'V';
130                                 Card.name[3] = 'A';
131                                 Card.name[4] = 'S';
132                                 Card.name[5] = 'Q';
133                                 Card.name[6] = '0' + i;
134                                 Card.name[7] = '\0';
135
136                                 Card.serial = PCIserial;
137
138                                 Card.card_id = wNumCards;
139
140                                 if (DivasCardNew(&Card) != 0)
141                                 {
142                                         // Force for loop to terminate
143                                         i = 4;
144                                         continue;
145                                 }
146                                 wNumCards++;
147
148                         }//for
149                 }
150                 wDeviceIndex++;
151         }
152
153         wDeviceIndex = 0;
154
155         while (wDeviceIndex < 10)
156         {
157                 wPCIConsultation = pcibios_find_device(PCI_VENDOR_ID_EICON, 
158                                 PCI_DEVICE_ID_EICON_MAESTRA, 
159                                 wDeviceIndex, 
160                                 &byBus, &byFunc);
161
162                 if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
163                 {
164                         dword dwPLXIOBase, dwDivasIOBase;
165                         byte byIRQ;
166
167                         printk(KERN_DEBUG "Divas: DIVA Server BRI (S/T) Found\n");
168                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
169                         dwPLXIOBase &= 0xFFFFFF80;
170
171                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
172                         dwDivasIOBase &= 0xFFFFFFFC;
173
174                         pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
175
176                         Card.card_id = wNumCards;
177                         Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_B;
178                         Card.bus_type = DIA_BUS_TYPE_PCI;
179                         Card.irq = byIRQ;
180                         Card.reset_base = dwPLXIOBase;
181                         Card.io_base = dwDivasIOBase;
182                         Card.bus_num = byBus;
183                         Card.func_num = byFunc;
184                         Card.slot = -1;
185                         Card.name[0] = 'D';
186                         Card.name[1] = 'I';
187                         Card.name[2] = 'V';
188                         Card.name[3] = 'A';
189                         Card.name[4] = 'S';
190                         Card.name[5] = 'B';
191                         Card.name[6] = '\0';
192
193                         if (check_region(Card.io_base, 0x20))
194                         {
195                                 printk(KERN_WARNING "Divas: DIVA I/O Base already in use 0x%x-0x%x\n", Card.io_base, Card.io_base + 0x1F);
196                                 wDeviceIndex++;
197                                 continue;
198                         }
199
200                         if (check_region(Card.reset_base, 0x80))
201                         {
202                                 printk(KERN_WARNING "Divas: PLX I/O Base already in use 0x%x-0x%x\n", Card.reset_base, Card.reset_base + 0x7F);
203                                 wDeviceIndex++;
204                                 continue;
205                         }
206
207                         if (DivasCardNew(&Card) != 0)
208                         {
209                                 wDeviceIndex++;
210                                 continue;
211                         }
212                         wNumCards++;
213                 }
214
215                 wPCIConsultation = pcibios_find_device(PCI_VENDOR_ID_EICON, 
216                                 PCI_DEVICE_ID_EICON_MAESTRAQ_U, 
217                                 wDeviceIndex, 
218                                 &byBus, &byFunc);
219
220                 if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
221                 {
222                         dword dwPLXIOBase, dwDivasIOBase;
223                         byte byIRQ;
224
225                         printk(KERN_DEBUG "Divas: DIVA Server BRI (U) Found\n");
226
227                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
228                         dwPLXIOBase &= 0xFFFFFF80;
229
230                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
231                         dwDivasIOBase &= 0xFFFFFFFC;
232
233                         pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
234
235                         Card.card_id = wNumCards;
236                         Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_B;
237                         Card.bus_type = DIA_BUS_TYPE_PCI;
238                         Card.irq = byIRQ;
239                         Card.reset_base = dwPLXIOBase;
240                         Card.io_base = dwDivasIOBase;
241                         Card.bus_num = byBus;
242                         Card.func_num = byFunc;
243                         Card.slot = -1;
244                         Card.name[0] = 'D';
245                         Card.name[1] = 'I';
246                         Card.name[2] = 'V';
247                         Card.name[3] = 'A';
248                         Card.name[4] = 'S';
249                         Card.name[5] = 'B';
250                         Card.name[6] = '\0';
251
252                         if (check_region(Card.io_base, 0x20))
253                         {
254                                 printk(KERN_WARNING "Divas: DIVA I/O Base already in use 0x%x-0x%x\n", Card.io_base, Card.io_base + 0x1F);      
255                                 wDeviceIndex++;
256                                 continue;
257                         }
258
259                         if (check_region(Card.reset_base, 0x80))
260                         {
261                                 printk(KERN_WARNING "Divas: PLX I/O Base already in use 0x%x-0x%x\n", Card.reset_base, Card.reset_base + 0x7F);
262                                 wDeviceIndex++;
263                                 continue;
264                         }
265
266                         if (DivasCardNew(&Card) != 0)
267                         {
268                                 wDeviceIndex++;
269                                 continue;
270                         }
271                         wNumCards++;
272                 }
273
274                 wDeviceIndex++;
275         }
276
277         wDeviceIndex = 0;
278
279         while (wDeviceIndex < 10)
280         {
281                 wPCIConsultation = pcibios_find_device(PCI_VENDOR_ID_EICON, 
282                                 PCI_DEVICE_ID_EICON_MAESTRAP, 
283                                 wDeviceIndex, 
284                                 &byBus, &byFunc);
285
286                 if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
287                 {
288                         dword dwRAM, dwREG, dwCFG;
289                         byte byIRQ;
290
291                         printk(KERN_DEBUG "Divas: DIVA Server PRI Found\n");
292
293                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_0, (unsigned int *) &dwRAM);
294                         dwRAM &= 0xFFFFF000;
295
296                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwREG);
297                         dwREG &= 0xFFFFF000;
298                         
299                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_4, (unsigned int *) &dwCFG);
300                         dwCFG &= 0xFFFFF000;
301
302                         pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
303
304                         Card.memory[DIVAS_RAM_MEMORY] = ioremap(dwRAM, 0x10000);
305                         Card.memory[DIVAS_REG_MEMORY] = ioremap(dwREG, 0x4000);
306                         Card.memory[DIVAS_CFG_MEMORY] = ioremap(dwCFG, 0x1000);
307                         Card.memory[DIVAS_SHARED_MEMORY] = Card.memory[DIVAS_RAM_MEMORY] + DIVAS_SHARED_OFFSET;
308
309 /*                      pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
310                         dwPLXIOBase &= 0xFFFFFFFc;
311
312                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
313                         dwDivasIOBase &= 0xFFFFFF80;
314
315                         pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
316 */
317                         Card.card_id = wNumCards;
318                         Card.card_type = DIA_CARD_TYPE_DIVA_SERVER;
319                         Card.bus_type = DIA_BUS_TYPE_PCI;
320                         Card.irq = byIRQ;
321 /*                      Card.reset_base = dwPLXIOBase;
322                         Card.io_base = dwDivasIOBase;*/
323                         Card.bus_num = byBus;
324                         Card.func_num = byFunc;
325                         Card.slot = -1;
326                         Card.name[0] = 'D';
327                         Card.name[1] = 'I';
328                         Card.name[2] = 'V';
329                         Card.name[3] = 'A';
330                         Card.name[4] = 'S';
331                         Card.name[5] = 'P';
332                         Card.name[6] = '\0';
333
334                         if (DivasCardNew(&Card) != 0)
335                         {
336                                 wDeviceIndex++;
337                                 continue;
338                         }
339                         wNumCards++;
340                 }
341
342                 wDeviceIndex++;
343         }
344
345
346         printk(KERN_INFO "Divas: %d cards detected\n", wNumCards);
347
348         if(wNumCards == 0)
349         {
350                 return -1;
351         }
352
353         Divas_fops.ioctl = do_ioctl;
354         Divas_fops.poll = do_poll;
355         Divas_fops.read = do_read;
356         Divas_fops.open = do_open;
357         Divas_fops.release = do_release;
358
359         Divas_major = register_chrdev(0, "Divas", &Divas_fops);
360
361         if (Divas_major < 0)
362         {
363                 printk(KERN_WARNING "Divas: Unable to register character driver\n");
364                 return -1;
365         }
366
367         return 0;
368 }
369
370 /* Error return -1 */
371 int DivasConfigGet(dia_card_t *card)
372 {
373         /* Retrieve Config from O/S? Not in Linux */
374         return 0;
375 }
376
377 dia_config_t *DivasConfig(card_t *card, dia_config_t *config)
378 {
379         /*      If config retrieved from OS then copy the data into a dia_config_t structure here
380                 and return the pointer here. If the config 'came from above' then just 
381
382                         return config;
383         */
384
385         return config;
386 }
387