OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [drivers/] [isdn/] [hisax/] [sedlbauer.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/* $Id: sedlbauer.c,v 1.1.1.1 2001-09-10 07:44:19 simons Exp $
2
 
3
 * sedlbauer.c  low level stuff for Sedlbauer cards
4
 *              includes support for the Sedlbauer speed star (speed star II),
5
 *              support for the Sedlbauer speed fax+,
6
 *              support for the Sedlbauer ISDN-Controller PC/104 and
7
 *              support for the Sedlbauer speed pci
8
 *              derived from the original file asuscom.c from Karsten Keil
9
 *
10
 * Copyright (C) 1997,1998 Marcus Niemann (for the modifications to
11
 *                                         the original file asuscom.c)
12
 *
13
 * Author     Marcus Niemann (niemann@www-bib.fh-bielefeld.de)
14
 *
15
 * Thanks to  Karsten Keil
16
 *            Sedlbauer AG for informations
17
 *            Edgar Toernig
18
 *
19
 * $Log: not supported by cvs2svn $
20
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
21
 * Initial revision
22
 *
23
 * Revision 1.1.2.16  1998/11/08 13:01:01  niemann
24
 * Added doc for Sedlbauer ISDN cards,
25
 * added info for downloading firmware (Sedlbauer speed fax+)
26
 *
27
 * Revision 1.1.2.15  1998/11/03 00:07:32  keil
28
 * certification related changes
29
 * fixed logging for smaller stack use
30
 *
31
 * Revision 1.1.2.14  1998/10/30 22:51:41  niemann
32
 * Added new card, Sedlbauer speed pci works now.
33
 *
34
 * Revision 1.1.2.13  1998/10/16 12:46:06  keil
35
 * fix pci detection for more as one card
36
 *
37
 * Revision 1.1.2.12  1998/10/13 18:38:53  keil
38
 * Fix PCI detection
39
 *
40
 * Revision 1.1.2.11  1998/10/13 10:27:30  keil
41
 * New cards, minor fixes
42
 *
43
 * Revision 1.1.2.10  1998/10/11 19:33:52  niemann
44
 * Added new IPAC based cards.
45
 * Code cleanup and simplified (sedlbauer.c)
46
 *
47
 * Revision 1.1.2.9  1998/10/04 23:05:03  keil
48
 * ISAR works now
49
 *
50
 * Revision 1.1.2.8  1998/09/30 22:28:10  keil
51
 * more work for isar support
52
 *
53
 * Revision 1.1.2.7  1998/09/27 13:07:01  keil
54
 * Apply most changes from 2.1.X (HiSax 3.1)
55
 *
56
 * Revision 1.1.2.6  1998/09/12 18:44:06  niemann
57
 * Added new card: Sedlbauer ISDN-Controller PC/104
58
 *
59
 * Revision 1.1.2.5  1998/04/08 21:58:44  keil
60
 * New init code
61
 *
62
 * Revision 1.1.2.4  1998/02/09 11:21:17  keil
63
 * Sedlbauer PCMCIA support from Marcus Niemann
64
 *
65
 * Revision 1.1.2.3  1998/01/27 22:37:29  keil
66
 * fast io
67
 *
68
 * Revision 1.1.2.2  1997/11/15 18:50:56  keil
69
 * new common init function
70
 *
71
 * Revision 1.1.2.1  1997/10/17 22:10:56  keil
72
 * new files on 2.0
73
 *
74
 * Revision 1.1  1997/09/11 17:32:04  keil
75
 * new
76
 *
77
 *
78
 */
79
 
80
/* Supported cards:
81
 * Card:        Chip:           Configuration:  Comment:
82
 * ---------------------------------------------------------------------
83
 * Speed Card   ISAC_HSCX       DIP-SWITCH
84
 * Speed Win    ISAC_HSCX       ISAPNP
85
 * Speed Fax+   ISAC_ISAR       ISAPNP          #HDLC works#
86
 * Speed Star   ISAC_HSCX       CARDMGR
87
 * Speed Win2   IPAC            ISAPNP
88
 * ISDN PC/104  IPAC            DIP-SWITCH
89
 * Speed Star2  IPAC            CARDMGR
90
 * Speed PCI    IPAC            PNP
91
 *
92
 * Important:
93
 * For the sedlbauer speed fax+ to work properly you have to download
94
 * the firmware onto the card.
95
 * For example: hisaxctrl <DriverID> 9 ISAR.BIN
96
*/
97
 
98
#define SEDLBAUER_PCI 1
99
 
100
#define __NO_VERSION__
101
#include <linux/config.h>
102
#include "hisax.h"
103
#include "isac.h"
104
#include "ipac.h"
105
#include "hscx.h"
106
#include "isar.h"
107
#include "isdnl1.h"
108
#include <linux/pci.h>
109
#include <linux/bios32.h>
110
 
111
extern const char *CardType[];
112
 
113
const char *Sedlbauer_revision = "$Revision: 1.1.1.1 $";
114
 
115
const char *Sedlbauer_Types[] =
116
        {"None", "speed card/win", "speed star", "speed fax+",
117
        "speed win II / ISDN PC/104", "speed star II", "speed pci"};
118
 
119
#ifdef SEDLBAUER_PCI
120
#define PCI_VENDOR_SEDLBAUER    0xe159
121
#define PCI_SPEEDPCI_ID 0x02
122
#endif
123
 
124
#define SEDL_SPEED_CARD_WIN     1
125
#define SEDL_SPEED_STAR         2
126
#define SEDL_SPEED_FAX          3
127
#define SEDL_SPEED_WIN2_PC104   4
128
#define SEDL_SPEED_STAR2        5
129
#define SEDL_SPEED_PCI          6
130
 
131
#define SEDL_CHIP_TEST          0
132
#define SEDL_CHIP_ISAC_HSCX     1
133
#define SEDL_CHIP_ISAC_ISAR     2
134
#define SEDL_CHIP_IPAC          3
135
 
136
#define SEDL_BUS_ISA            1
137
#define SEDL_BUS_PCI            2
138
#define SEDL_BUS_PCMCIA         3
139
 
140
#define byteout(addr,val) outb(val,addr)
141
#define bytein(addr) inb(addr)
142
 
143
#define SEDL_HSCX_ISA_RESET_ON  0
144
#define SEDL_HSCX_ISA_RESET_OFF 1
145
#define SEDL_HSCX_ISA_ISAC      2
146
#define SEDL_HSCX_ISA_HSCX      3
147
#define SEDL_HSCX_ISA_ADR       4
148
 
149
#define SEDL_HSCX_PCMCIA_RESET  0
150
#define SEDL_HSCX_PCMCIA_ISAC   1
151
#define SEDL_HSCX_PCMCIA_HSCX   2
152
#define SEDL_HSCX_PCMCIA_ADR    4
153
 
154
#define SEDL_ISAR_ISA_ISAC              4
155
#define SEDL_ISAR_ISA_ISAR              6
156
#define SEDL_ISAR_ISA_ADR               8
157
#define SEDL_ISAR_ISA_ISAR_RESET_ON     10
158
#define SEDL_ISAR_ISA_ISAR_RESET_OFF    12
159
 
160
#define SEDL_IPAC_ANY_ADR       0
161
#define SEDL_IPAC_ANY_IPAC      2
162
 
163
#define SEDL_IPAC_PCI_BASE      0
164
#define SEDL_IPAC_PCI_ADR       0xc0
165
#define SEDL_IPAC_PCI_IPAC      0xc8
166
 
167
#define SEDL_RESET      0x3     /* same as DOS driver */
168
 
169
static inline u_char
170
readreg(unsigned int ale, unsigned int adr, u_char off)
171
{
172
        register u_char ret;
173
        long flags;
174
 
175
        save_flags(flags);
176
        cli();
177
        byteout(ale, off);
178
        ret = bytein(adr);
179
        restore_flags(flags);
180
        return (ret);
181
}
182
 
183
static inline void
184
readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
185
{
186
        /* fifo read without cli because it's allready done  */
187
 
188
        byteout(ale, off);
189
        insb(adr, data, size);
190
}
191
 
192
 
193
static inline void
194
writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
195
{
196
        long flags;
197
 
198
        save_flags(flags);
199
        cli();
200
        byteout(ale, off);
201
        byteout(adr, data);
202
        restore_flags(flags);
203
}
204
 
205
static inline void
206
writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
207
{
208
        /* fifo write without cli because it's allready done  */
209
        byteout(ale, off);
210
        outsb(adr, data, size);
211
}
212
 
213
/* Interface functions */
214
 
215
static u_char
216
ReadISAC(struct IsdnCardState *cs, u_char offset)
217
{
218
        return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset));
219
}
220
 
221
static void
222
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
223
{
224
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset, value);
225
}
226
 
227
static void
228
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
229
{
230
        readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size);
231
}
232
 
233
static void
234
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
235
{
236
        writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size);
237
}
238
 
239
static u_char
240
ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
241
{
242
        return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset|0x80));}
243
 
244
static void
245
WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
246
{
247
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset|0x80, value);
248
}
249
 
250
static void
251
ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
252
{
253
        readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size);
254
}
255
 
256
static void
257
WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
258
{
259
        writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size);
260
}
261
 
262
static u_char
263
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
264
{
265
        return (readreg(cs->hw.sedl.adr,
266
                        cs->hw.sedl.hscx, offset + (hscx ? 0x40 : 0)));
267
}
268
 
269
static void
270
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
271
{
272
        writereg(cs->hw.sedl.adr,
273
                 cs->hw.sedl.hscx, offset + (hscx ? 0x40 : 0), value);
274
}
275
 
276
/* ISAR access routines
277
 * mode = 0 access with IRQ on
278
 * mode = 1 access with IRQ off
279
 * mode = 2 access with IRQ off and using last offset
280
 */
281
 
282
static u_char
283
ReadISAR(struct IsdnCardState *cs, int mode, u_char offset)
284
{
285
        if (mode == 0)
286
                return (readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, offset));
287
        else if (mode == 1)
288
                byteout(cs->hw.sedl.adr, offset);
289
        return(bytein(cs->hw.sedl.hscx));
290
}
291
 
292
static void
293
WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value)
294
{
295
        if (mode == 0)
296
                writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, offset, value);
297
        else {
298
                if (mode == 1)
299
                        byteout(cs->hw.sedl.adr, offset);
300
                byteout(cs->hw.sedl.hscx, value);
301
        }
302
}
303
 
304
/*
305
 * fast interrupt HSCX stuff goes here
306
 */
307
 
308
#define READHSCX(cs, nr, reg) readreg(cs->hw.sedl.adr, \
309
                cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0))
310
#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.sedl.adr, \
311
                cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0), data)
312
 
313
#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.sedl.adr, \
314
                cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt)
315
 
316
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.sedl.adr, \
317
                cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt)
318
 
319
#include "hscx_irq.c"
320
 
321
static void
322
sedlbauer_interrupt(int intno, void *dev_id, struct pt_regs *regs)
323
{
324
        struct IsdnCardState *cs = dev_id;
325
        u_char val, stat = 0;
326
 
327
        if (!cs) {
328
                printk(KERN_WARNING "Sedlbauer: Spurious interrupt!\n");
329
                return;
330
        }
331
 
332
        if ((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) && (*cs->busy_flag == 1)) {
333
          /* The card tends to generate interrupts while being removed
334
             causing us to just crash the kernel. bad. */
335
          printk(KERN_WARNING "Sedlbauer: card not available!\n");
336
          return;
337
        }
338
 
339
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
340
      Start_HSCX:
341
        if (val) {
342
                hscx_int_main(cs, val);
343
                stat |= 1;
344
        }
345
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
346
      Start_ISAC:
347
        if (val) {
348
                isac_interrupt(cs, val);
349
                stat |= 2;
350
        }
351
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
352
        if (val) {
353
                if (cs->debug & L1_DEB_HSCX)
354
                        debugl1(cs, "HSCX IntStat after IntRoutine");
355
                goto Start_HSCX;
356
        }
357
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
358
        if (val) {
359
                if (cs->debug & L1_DEB_ISAC)
360
                        debugl1(cs, "ISAC IntStat after IntRoutine");
361
                goto Start_ISAC;
362
        }
363
        if (stat & 1) {
364
                writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0xFF);
365
                writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0xFF);
366
                writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0x0);
367
                writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0x0);
368
        }
369
        if (stat & 2) {
370
                writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0xFF);
371
                writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0x0);
372
        }
373
}
374
 
375
static void
376
sedlbauer_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
377
{
378
        struct IsdnCardState *cs = dev_id;
379
        u_char ista, val, icnt = 20;
380
 
381
        if (!cs) {
382
                printk(KERN_WARNING "Sedlbauer: Spurious interrupt!\n");
383
                return;
384
        }
385
        ista = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ISTA);
386
Start_IPAC:
387
        if (cs->debug & L1_DEB_IPAC)
388
                debugl1(cs, "IPAC ISTA %02X", ista);
389
        if (ista & 0x0f) {
390
                val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
391
                if (ista & 0x01)
392
                        val |= 0x01;
393
                if (ista & 0x04)
394
                        val |= 0x02;
395
                if (ista & 0x08)
396
                        val |= 0x04;
397
                if (val)
398
                        hscx_int_main(cs, val);
399
        }
400
        if (ista & 0x20) {
401
                val = 0xfe & readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA | 0x80);
402
                if (val) {
403
                        isac_interrupt(cs, val);
404
                }
405
        }
406
        if (ista & 0x10) {
407
                val = 0x01;
408
                isac_interrupt(cs, val);
409
        }
410
        ista  = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ISTA);
411
        if ((ista & 0x3f) && icnt) {
412
                icnt--;
413
                goto Start_IPAC;
414
        }
415
        if (!icnt)
416
                printk(KERN_WARNING "Sedlbauer IRQ LOOP\n");
417
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xFF);
418
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xC0);
419
}
420
 
421
static void
422
sedlbauer_interrupt_isar(int intno, void *dev_id, struct pt_regs *regs)
423
{
424
        struct IsdnCardState *cs = dev_id;
425
        u_char val;
426
        int cnt = 20;
427
 
428
        if (!cs) {
429
                printk(KERN_WARNING "Sedlbauer: Spurious interrupt!\n");
430
                return;
431
        }
432
 
433
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT);
434
      Start_ISAR:
435
        if (val & ISAR_IRQSTA)
436
                isar_int_main(cs);
437
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
438
      Start_ISAC:
439
        if (val)
440
                isac_interrupt(cs, val);
441
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT);
442
        if ((val & ISAR_IRQSTA) && --cnt) {
443
                if (cs->debug & L1_DEB_HSCX)
444
                        debugl1(cs, "ISAR IntStat after IntRoutine");
445
                goto Start_ISAR;
446
        }
447
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
448
        if (val && --cnt) {
449
                if (cs->debug & L1_DEB_ISAC)
450
                        debugl1(cs, "ISAC IntStat after IntRoutine");
451
                goto Start_ISAC;
452
        }
453
        if (!cnt)
454
                printk(KERN_WARNING "Sedlbauer IRQ LOOP\n");
455
 
456
        writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT, 0);
457
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0xFF);
458
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0x0);
459
        writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT, ISAR_IRQMSK);
460
}
461
 
462
void
463
release_io_sedlbauer(struct IsdnCardState *cs)
464
{
465
        int bytecnt = (cs->subtyp == SEDL_SPEED_FAX) ? 16 : 8;
466
 
467
        if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
468
                bytecnt = 256;
469
        }
470
        if (cs->hw.sedl.cfg_reg)
471
                release_region(cs->hw.sedl.cfg_reg, bytecnt);
472
}
473
 
474
static void
475
reset_sedlbauer(struct IsdnCardState *cs)
476
{
477
        long flags;
478
 
479
        printk(KERN_INFO "Sedlbauer: resetting card\n");
480
 
481
        if (!((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) &&
482
           (cs->hw.sedl.chip == SEDL_CHIP_ISAC_HSCX))) {
483
                if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
484
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x20);
485
                        save_flags(flags);
486
                        sti();
487
                        current->state = TASK_INTERRUPTIBLE;
488
                        current->timeout = jiffies + 1;
489
                        schedule();
490
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x0);
491
                        current->state = TASK_INTERRUPTIBLE;
492
                        current->timeout = jiffies + 1;
493
                        schedule();
494
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_CONF, 0x0);
495
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ACFG, 0xff);
496
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_AOE, 0x0);
497
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xc0);
498
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_PCFG, 0x12);
499
                        restore_flags(flags);
500
                } else {
501
                        byteout(cs->hw.sedl.reset_on, SEDL_RESET);      /* Reset On */
502
                        save_flags(flags);
503
                        sti();
504
                        current->state = TASK_INTERRUPTIBLE;
505
                        current->timeout = jiffies + 1;
506
                        schedule();
507
                        byteout(cs->hw.sedl.reset_off, 0);       /* Reset Off */
508
                        current->state = TASK_INTERRUPTIBLE;
509
                        current->timeout = jiffies + 1;
510
                        schedule();
511
                        restore_flags(flags);
512
                }
513
        }
514
}
515
 
516
static int
517
Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg)
518
{
519
        switch (mt) {
520
                case CARD_RESET:
521
                        reset_sedlbauer(cs);
522
                        return(0);
523
                case CARD_RELEASE:
524
                        release_io_sedlbauer(cs);
525
                        return(0);
526
                case CARD_SETIRQ:
527
                        if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
528
                                return(request_irq(cs->irq, &sedlbauer_interrupt_isar,
529
                                        I4L_IRQ_FLAG, "HiSax", cs));
530
                        } else if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
531
                                return(request_irq(cs->irq, &sedlbauer_interrupt_ipac,
532
                                        I4L_IRQ_FLAG, "HiSax", cs));
533
                        } else {
534
                                return(request_irq(cs->irq, &sedlbauer_interrupt,
535
                                        I4L_IRQ_FLAG, "HiSax", cs));
536
                        }
537
                case CARD_INIT:
538
                        if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
539
                                clear_pending_isac_ints(cs);
540
                                writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
541
                                        ISAR_IRQBIT, 0);
542
                                initisac(cs);
543
                                initisar(cs);
544
                                /* Reenable all IRQ */
545
                                cs->writeisac(cs, ISAC_MASK, 0);
546
                                /* RESET Receiver and Transmitter */
547
                                cs->writeisac(cs, ISAC_CMDR, 0x41);
548
                        } else {
549
                                inithscxisac(cs, 3);
550
                        }
551
                        return(0);
552
                case CARD_TEST:
553
                        return(0);
554
                case CARD_LOAD_FIRM:
555
                        if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
556
                                if (isar_load_firmware(cs, arg))
557
                                        return(1);
558
                                else
559
                                        ll_run(cs);
560
                        }
561
                        return(0);
562
        }
563
        return(0);
564
}
565
 
566
 
567
#ifdef SEDLBAUER_PCI
568
static  int pci_index __initdata = 0;
569
#endif
570
 
571
__initfunc(int
572
setup_sedlbauer(struct IsdnCard *card))
573
{
574
        int bytecnt, ver, val;
575
        struct IsdnCardState *cs = card->cs;
576
        char tmp[64];
577
 
578
        strcpy(tmp, Sedlbauer_revision);
579
        printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp));
580
 
581
        if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
582
                cs->subtyp = SEDL_SPEED_CARD_WIN;
583
                cs->hw.sedl.bus = SEDL_BUS_ISA;
584
                cs->hw.sedl.chip = SEDL_CHIP_TEST;
585
        } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {
586
                cs->subtyp = SEDL_SPEED_STAR;
587
                cs->hw.sedl.bus = SEDL_BUS_PCMCIA;
588
                cs->hw.sedl.chip = SEDL_CHIP_TEST;
589
        } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {
590
                cs->subtyp = SEDL_SPEED_FAX;
591
                cs->hw.sedl.bus = SEDL_BUS_ISA;
592
                cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
593
        } else
594
                return (0);
595
 
596
        bytecnt = 8;
597
        if (card->para[1]) {
598
                cs->hw.sedl.cfg_reg = card->para[1];
599
                cs->irq = card->para[0];
600
                if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
601
                        bytecnt = 16;
602
                }
603
        } else {
604
/* Probe for Sedlbauer speed pci */
605
#if SEDLBAUER_PCI
606
#if CONFIG_PCI
607
                for (; pci_index < 255; pci_index++) {
608
                        unsigned char pci_bus, pci_device_fn;
609
                        unsigned int ioaddr;
610
                        unsigned char irq;
611
 
612
                        if (pcibios_find_device (PCI_VENDOR_SEDLBAUER,
613
                                                PCI_SPEEDPCI_ID, pci_index,
614
                                                &pci_bus, &pci_device_fn) != 0) {
615
                                continue;
616
                        }
617
                        pcibios_read_config_byte(pci_bus, pci_device_fn,
618
                                        PCI_INTERRUPT_LINE, &irq);
619
                        pcibios_read_config_dword(pci_bus, pci_device_fn,
620
                                        PCI_BASE_ADDRESS_0, &ioaddr);
621
                        cs->irq = irq;
622
                        cs->hw.sedl.cfg_reg = ioaddr & PCI_BASE_ADDRESS_IO_MASK;
623
                        if (!cs->hw.sedl.cfg_reg) {
624
                                printk(KERN_WARNING "Sedlbauer: No IO-Adr for PCI card found\n");
625
                                return(0);
626
                        }
627
                        cs->hw.sedl.bus = SEDL_BUS_PCI;
628
                        cs->hw.sedl.chip = SEDL_CHIP_IPAC;
629
                        cs->subtyp = SEDL_SPEED_PCI;
630
                        bytecnt = 256;
631
                        byteout(cs->hw.sedl.cfg_reg, 0xff);
632
                        byteout(cs->hw.sedl.cfg_reg, 0x00);
633
                        byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
634
                        byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
635
                        break;
636
                }
637
                if (pci_index == 255) {
638
                        printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
639
                        return(0);
640
                }
641
                pci_index++;
642
#else
643
                printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n");
644
                return (0);
645
#endif /* CONFIG_PCI */
646
#endif /* SEDLBAUER_PCI */
647
        }
648
 
649
        /* In case of the sedlbauer pcmcia card, this region is in use,
650
           reserved for us by the card manager. So we do not check it
651
           here, it would fail. */
652
        if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA &&
653
                check_region((cs->hw.sedl.cfg_reg), bytecnt)) {
654
                printk(KERN_WARNING
655
                        "HiSax: %s config port %x-%x already in use\n",
656
                        CardType[card->typ],
657
                        cs->hw.sedl.cfg_reg,
658
                        cs->hw.sedl.cfg_reg + bytecnt);
659
                        return (0);
660
        } else {
661
                request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn");
662
        }
663
 
664
        printk(KERN_INFO
665
               "Sedlbauer: defined at 0x%x-0x%x IRQ %d\n",
666
               cs->hw.sedl.cfg_reg,
667
               cs->hw.sedl.cfg_reg + bytecnt,
668
               cs->irq);
669
 
670
        cs->BC_Read_Reg = &ReadHSCX;
671
        cs->BC_Write_Reg = &WriteHSCX;
672
        cs->BC_Send_Data = &hscx_fill_fifo;
673
        cs->cardmsg = &Sedl_card_msg;
674
 
675
/*
676
 * testing ISA and PCMCIA Cards for IPAC, default is ISAC
677
 * do not test for PCI card, because ports are different
678
 * and PCI card uses only IPAC (for the moment)
679
 */
680
        if (cs->hw.sedl.bus != SEDL_BUS_PCI) {
681
                val = readreg(cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR,
682
                        cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID);
683
                if (val == 1) {
684
                /* IPAC */
685
                        cs->subtyp = SEDL_SPEED_WIN2_PC104;
686
                        if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
687
                                cs->subtyp = SEDL_SPEED_STAR2;
688
                        }
689
                        cs->hw.sedl.chip = SEDL_CHIP_IPAC;
690
                } else {
691
                /* ISAC_HSCX oder ISAC_ISAR */
692
                        if (cs->hw.sedl.chip == SEDL_CHIP_TEST) {
693
                                cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX;
694
                        }
695
                }
696
        }
697
 
698
/*
699
 * hw.sedl.chip is now properly set
700
 */
701
        printk(KERN_INFO "Sedlbauer: %s detected\n",
702
                Sedlbauer_Types[cs->subtyp]);
703
 
704
 
705
        if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
706
        /* IPAC */
707
                if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
708
                        cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
709
                        cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
710
                        cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
711
                } else {
712
                        cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
713
                        cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
714
                        cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
715
                }
716
                test_and_set_bit(HW_IPAC, &cs->HW_Flags);
717
                cs->readisac = &ReadISAC_IPAC;
718
                cs->writeisac = &WriteISAC_IPAC;
719
                cs->readisacfifo = &ReadISACfifo_IPAC;
720
                cs->writeisacfifo = &WriteISACfifo_IPAC;
721
 
722
                val = readreg(cs->hw.sedl.adr,cs->hw.sedl.isac, IPAC_ID);
723
                printk(KERN_INFO "Sedlbauer: IPAC version %x\n", val);
724
                reset_sedlbauer(cs);
725
        } else {
726
        /* ISAC_HSCX oder ISAC_ISAR */
727
                cs->readisac = &ReadISAC;
728
                cs->writeisac = &WriteISAC;
729
                cs->readisacfifo = &ReadISACfifo;
730
                cs->writeisacfifo = &WriteISACfifo;
731
                if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
732
                        cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ADR;
733
                        cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAC;
734
                        cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR;
735
                        cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR_RESET_ON;
736
                        cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR_RESET_OFF;
737
                        cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar;
738
                        cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar;
739
                        test_and_set_bit(HW_ISAR, &cs->HW_Flags);
740
 
741
                        ISACVersion(cs, "Sedlbauer:");
742
 
743
                        cs->BC_Read_Reg = &ReadISAR;
744
                        cs->BC_Write_Reg = &WriteISAR;
745
                        cs->BC_Send_Data = &isar_fill_fifo;
746
                        ver = ISARVersion(cs, "Sedlbauer:");
747
                        if (ver < 0) {
748
                                printk(KERN_WARNING
749
                                        "Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
750
                                release_io_sedlbauer(cs);
751
                                return (0);
752
                        }
753
                } else {
754
                        if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
755
                                cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR;
756
                                cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC;
757
                                cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX;
758
                                cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
759
                                cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
760
                        } else {
761
                                cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR;
762
                                cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC;
763
                                cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX;
764
                                cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON;
765
                                cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF;
766
                        }
767
                        ISACVersion(cs, "Sedlbauer:");
768
 
769
                        if (HscxVersion(cs, "Sedlbauer:")) {
770
                                printk(KERN_WARNING
771
                                        "Sedlbauer: wrong HSCX versions check IO address\n");
772
                                release_io_sedlbauer(cs);
773
                                return (0);
774
                        }
775
                        reset_sedlbauer(cs);
776
                }
777
        }
778
        return (1);
779
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.