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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [isdn/] [hisax/] [sedlbauer.c] - Blame information for rev 1772

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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