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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [isdn/] [hisax/] [sedlbauer.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $Id: sedlbauer.c,v 1.34.2.6 2004/01/24 20:47:24 keil Exp $
2
 *
3
 * 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
 * Author       Marcus Niemann
11
 * Copyright    by Marcus Niemann    <niemann@www-bib.fh-bielefeld.de>
12
 *
13
 * This software may be used and distributed according to the terms
14
 * of the GNU General Public License, incorporated herein by reference.
15
 *
16
 * Thanks to  Karsten Keil
17
 *            Sedlbauer AG for informations
18
 *            Edgar Toernig
19
 *
20
 */
21
 
22
/* Supported cards:
23
 * Card:        Chip:           Configuration:  Comment:
24
 * ---------------------------------------------------------------------
25
 * Speed Card   ISAC_HSCX       DIP-SWITCH
26
 * Speed Win    ISAC_HSCX       ISAPNP
27
 * Speed Fax+   ISAC_ISAR       ISAPNP          Full analog support
28
 * Speed Star   ISAC_HSCX       CARDMGR
29
 * Speed Win2   IPAC            ISAPNP
30
 * ISDN PC/104  IPAC            DIP-SWITCH
31
 * Speed Star2  IPAC            CARDMGR
32
 * Speed PCI    IPAC            PCI PNP
33
 * Speed Fax+   ISAC_ISAR       PCI PNP         Full analog support
34
 *
35
 * Important:
36
 * For the sedlbauer speed fax+ to work properly you have to download
37
 * the firmware onto the card.
38
 * For example: hisaxctrl <DriverID> 9 ISAR.BIN
39
*/
40
 
41
#include <linux/init.h>
42
#include "hisax.h"
43
#include "isac.h"
44
#include "ipac.h"
45
#include "hscx.h"
46
#include "isar.h"
47
#include "isdnl1.h"
48
#include <linux/pci.h>
49
#include <linux/isapnp.h>
50
 
51
extern const char *CardType[];
52
 
53
static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
54
 
55
static const char *Sedlbauer_Types[] =
56
        {"None", "speed card/win", "speed star", "speed fax+",
57
        "speed win II / ISDN PC/104", "speed star II", "speed pci",
58
        "speed fax+ pyramid", "speed fax+ pci", "HST Saphir III"};
59
 
60
#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID  0x51
61
#define PCI_SUBVENDOR_HST_SAPHIR3       0x52
62
#define PCI_SUBVENDOR_SEDLBAUER_PCI     0x53
63
#define PCI_SUBVENDOR_SPEEDFAX_PCI      0x54
64
#define PCI_SUB_ID_SEDLBAUER            0x01
65
 
66
#define SEDL_SPEED_CARD_WIN     1
67
#define SEDL_SPEED_STAR         2
68
#define SEDL_SPEED_FAX          3
69
#define SEDL_SPEED_WIN2_PC104   4
70
#define SEDL_SPEED_STAR2        5
71
#define SEDL_SPEED_PCI          6
72
#define SEDL_SPEEDFAX_PYRAMID   7
73
#define SEDL_SPEEDFAX_PCI       8
74
#define HST_SAPHIR3             9
75
 
76
#define SEDL_CHIP_TEST          0
77
#define SEDL_CHIP_ISAC_HSCX     1
78
#define SEDL_CHIP_ISAC_ISAR     2
79
#define SEDL_CHIP_IPAC          3
80
 
81
#define SEDL_BUS_ISA            1
82
#define SEDL_BUS_PCI            2
83
#define SEDL_BUS_PCMCIA         3
84
 
85
#define byteout(addr,val) outb(val,addr)
86
#define bytein(addr) inb(addr)
87
 
88
#define SEDL_HSCX_ISA_RESET_ON  0
89
#define SEDL_HSCX_ISA_RESET_OFF 1
90
#define SEDL_HSCX_ISA_ISAC      2
91
#define SEDL_HSCX_ISA_HSCX      3
92
#define SEDL_HSCX_ISA_ADR       4
93
 
94
#define SEDL_HSCX_PCMCIA_RESET  0
95
#define SEDL_HSCX_PCMCIA_ISAC   1
96
#define SEDL_HSCX_PCMCIA_HSCX   2
97
#define SEDL_HSCX_PCMCIA_ADR    4
98
 
99
#define SEDL_ISAR_ISA_ISAC              4
100
#define SEDL_ISAR_ISA_ISAR              6
101
#define SEDL_ISAR_ISA_ADR               8
102
#define SEDL_ISAR_ISA_ISAR_RESET_ON     10
103
#define SEDL_ISAR_ISA_ISAR_RESET_OFF    12
104
 
105
#define SEDL_IPAC_ANY_ADR               0
106
#define SEDL_IPAC_ANY_IPAC              2
107
 
108
#define SEDL_IPAC_PCI_BASE              0
109
#define SEDL_IPAC_PCI_ADR               0xc0
110
#define SEDL_IPAC_PCI_IPAC              0xc8
111
#define SEDL_ISAR_PCI_ADR               0xc8
112
#define SEDL_ISAR_PCI_ISAC              0xd0
113
#define SEDL_ISAR_PCI_ISAR              0xe0
114
#define SEDL_ISAR_PCI_ISAR_RESET_ON     0x01
115
#define SEDL_ISAR_PCI_ISAR_RESET_OFF    0x18
116
#define SEDL_ISAR_PCI_LED1              0x08
117
#define SEDL_ISAR_PCI_LED2              0x10
118
 
119
#define SEDL_RESET      0x3     /* same as DOS driver */
120
 
121
static inline u_char
122
readreg(unsigned int ale, unsigned int adr, u_char off)
123
{
124
        register u_char ret;
125
 
126
        byteout(ale, off);
127
        ret = bytein(adr);
128
        return (ret);
129
}
130
 
131
static inline void
132
readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
133
{
134
        byteout(ale, off);
135
        insb(adr, data, size);
136
}
137
 
138
 
139
static inline void
140
writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
141
{
142
        byteout(ale, off);
143
        byteout(adr, data);
144
}
145
 
146
static inline void
147
writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
148
{
149
        byteout(ale, off);
150
        outsb(adr, data, size);
151
}
152
 
153
/* Interface functions */
154
 
155
static u_char
156
ReadISAC(struct IsdnCardState *cs, u_char offset)
157
{
158
        return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset));
159
}
160
 
161
static void
162
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
163
{
164
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset, value);
165
}
166
 
167
static void
168
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
169
{
170
        readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size);
171
}
172
 
173
static void
174
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
175
{
176
        writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size);
177
}
178
 
179
static u_char
180
ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
181
{
182
        return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset|0x80));
183
}
184
 
185
static void
186
WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
187
{
188
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset|0x80, value);
189
}
190
 
191
static void
192
ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
193
{
194
        readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size);
195
}
196
 
197
static void
198
WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
199
{
200
        writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size);
201
}
202
 
203
static u_char
204
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
205
{
206
        return (readreg(cs->hw.sedl.adr,
207
                        cs->hw.sedl.hscx, offset + (hscx ? 0x40 : 0)));
208
}
209
 
210
static void
211
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
212
{
213
        writereg(cs->hw.sedl.adr,
214
                 cs->hw.sedl.hscx, offset + (hscx ? 0x40 : 0), value);
215
}
216
 
217
/* ISAR access routines
218
 * mode = 0 access with IRQ on
219
 * mode = 1 access with IRQ off
220
 * mode = 2 access with IRQ off and using last offset
221
 */
222
 
223
static u_char
224
ReadISAR(struct IsdnCardState *cs, int mode, u_char offset)
225
{
226
        if (mode == 0)
227
                return (readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, offset));
228
        else if (mode == 1)
229
                byteout(cs->hw.sedl.adr, offset);
230
        return(bytein(cs->hw.sedl.hscx));
231
}
232
 
233
static void
234
WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value)
235
{
236
        if (mode == 0)
237
                writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, offset, value);
238
        else {
239
                if (mode == 1)
240
                        byteout(cs->hw.sedl.adr, offset);
241
                byteout(cs->hw.sedl.hscx, value);
242
        }
243
}
244
 
245
/*
246
 * fast interrupt HSCX stuff goes here
247
 */
248
 
249
#define READHSCX(cs, nr, reg) readreg(cs->hw.sedl.adr, \
250
                cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0))
251
#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.sedl.adr, \
252
                cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0), data)
253
 
254
#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.sedl.adr, \
255
                cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt)
256
 
257
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.sedl.adr, \
258
                cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt)
259
 
260
#include "hscx_irq.c"
261
 
262
static irqreturn_t
263
sedlbauer_interrupt(int intno, void *dev_id)
264
{
265
        struct IsdnCardState *cs = dev_id;
266
        u_char val;
267
        u_long flags;
268
 
269
        spin_lock_irqsave(&cs->lock, flags);
270
        if ((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) && (*cs->busy_flag == 1)) {
271
                /* The card tends to generate interrupts while being removed
272
                   causing us to just crash the kernel. bad. */
273
                spin_unlock_irqrestore(&cs->lock, flags);
274
                printk(KERN_WARNING "Sedlbauer: card not available!\n");
275
                return IRQ_NONE;
276
        }
277
 
278
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
279
      Start_HSCX:
280
        if (val)
281
                hscx_int_main(cs, val);
282
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
283
      Start_ISAC:
284
        if (val)
285
                isac_interrupt(cs, val);
286
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
287
        if (val) {
288
                if (cs->debug & L1_DEB_HSCX)
289
                        debugl1(cs, "HSCX IntStat after IntRoutine");
290
                goto Start_HSCX;
291
        }
292
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
293
        if (val) {
294
                if (cs->debug & L1_DEB_ISAC)
295
                        debugl1(cs, "ISAC IntStat after IntRoutine");
296
                goto Start_ISAC;
297
        }
298
        writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0xFF);
299
        writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0xFF);
300
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0xFF);
301
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0x0);
302
        writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0x0);
303
        writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0x0);
304
        spin_unlock_irqrestore(&cs->lock, flags);
305
        return IRQ_HANDLED;
306
}
307
 
308
static irqreturn_t
309
sedlbauer_interrupt_ipac(int intno, void *dev_id)
310
{
311
        struct IsdnCardState *cs = dev_id;
312
        u_char ista, val, icnt = 5;
313
        u_long flags;
314
 
315
        spin_lock_irqsave(&cs->lock, flags);
316
        ista = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ISTA);
317
Start_IPAC:
318
        if (cs->debug & L1_DEB_IPAC)
319
                debugl1(cs, "IPAC ISTA %02X", ista);
320
        if (ista & 0x0f) {
321
                val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
322
                if (ista & 0x01)
323
                        val |= 0x01;
324
                if (ista & 0x04)
325
                        val |= 0x02;
326
                if (ista & 0x08)
327
                        val |= 0x04;
328
                if (val)
329
                        hscx_int_main(cs, val);
330
        }
331
        if (ista & 0x20) {
332
                val = 0xfe & readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA | 0x80);
333
                if (val) {
334
                        isac_interrupt(cs, val);
335
                }
336
        }
337
        if (ista & 0x10) {
338
                val = 0x01;
339
                isac_interrupt(cs, val);
340
        }
341
        ista  = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ISTA);
342
        if ((ista & 0x3f) && icnt) {
343
                icnt--;
344
                goto Start_IPAC;
345
        }
346
        if (!icnt)
347
                if (cs->debug & L1_DEB_ISAC)
348
                        debugl1(cs, "Sedlbauer IRQ LOOP");
349
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xFF);
350
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xC0);
351
        spin_unlock_irqrestore(&cs->lock, flags);
352
        return IRQ_HANDLED;
353
}
354
 
355
static irqreturn_t
356
sedlbauer_interrupt_isar(int intno, void *dev_id)
357
{
358
        struct IsdnCardState *cs = dev_id;
359
        u_char val;
360
        int cnt = 5;
361
        u_long flags;
362
 
363
        spin_lock_irqsave(&cs->lock, flags);
364
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT);
365
      Start_ISAR:
366
        if (val & ISAR_IRQSTA)
367
                isar_int_main(cs);
368
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
369
      Start_ISAC:
370
        if (val)
371
                isac_interrupt(cs, val);
372
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT);
373
        if ((val & ISAR_IRQSTA) && --cnt) {
374
                if (cs->debug & L1_DEB_HSCX)
375
                        debugl1(cs, "ISAR IntStat after IntRoutine");
376
                goto Start_ISAR;
377
        }
378
        val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
379
        if (val && --cnt) {
380
                if (cs->debug & L1_DEB_ISAC)
381
                        debugl1(cs, "ISAC IntStat after IntRoutine");
382
                goto Start_ISAC;
383
        }
384
        if (!cnt)
385
                if (cs->debug & L1_DEB_ISAC)
386
                        debugl1(cs, "Sedlbauer IRQ LOOP");
387
 
388
        writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT, 0);
389
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0xFF);
390
        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0x0);
391
        writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT, ISAR_IRQMSK);
392
        spin_unlock_irqrestore(&cs->lock, flags);
393
        return IRQ_HANDLED;
394
}
395
 
396
static void
397
release_io_sedlbauer(struct IsdnCardState *cs)
398
{
399
        int bytecnt = 8;
400
 
401
        if (cs->subtyp == SEDL_SPEED_FAX) {
402
                bytecnt = 16;
403
        } else if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
404
                bytecnt = 256;
405
        }
406
        if (cs->hw.sedl.cfg_reg)
407
                release_region(cs->hw.sedl.cfg_reg, bytecnt);
408
}
409
 
410
static void
411
reset_sedlbauer(struct IsdnCardState *cs)
412
{
413
        printk(KERN_INFO "Sedlbauer: resetting card\n");
414
 
415
        if (!((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) &&
416
           (cs->hw.sedl.chip == SEDL_CHIP_ISAC_HSCX))) {
417
                if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
418
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x20);
419
                        mdelay(2);
420
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x0);
421
                        mdelay(10);
422
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_CONF, 0x0);
423
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ACFG, 0xff);
424
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_AOE, 0x0);
425
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xc0);
426
                        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_PCFG, 0x12);
427
                } else if ((cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) &&
428
                        (cs->hw.sedl.bus == SEDL_BUS_PCI)) {
429
                        byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
430
                        mdelay(2);
431
                        byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
432
                        mdelay(10);
433
                } else {
434
                        byteout(cs->hw.sedl.reset_on, SEDL_RESET);      /* Reset On */
435
                        mdelay(2);
436
                        byteout(cs->hw.sedl.reset_off, 0);       /* Reset Off */
437
                        mdelay(10);
438
                }
439
        }
440
}
441
 
442
static int
443
Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg)
444
{
445
        u_long flags;
446
 
447
        switch (mt) {
448
                case CARD_RESET:
449
                        spin_lock_irqsave(&cs->lock, flags);
450
                        reset_sedlbauer(cs);
451
                        spin_unlock_irqrestore(&cs->lock, flags);
452
                        return(0);
453
                case CARD_RELEASE:
454
                        if (cs->hw.sedl.bus == SEDL_BUS_PCI)
455
                                /* disable all IRQ */
456
                                byteout(cs->hw.sedl.cfg_reg+ 5, 0);
457
                        if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
458
                                spin_lock_irqsave(&cs->lock, flags);
459
                                writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
460
                                        ISAR_IRQBIT, 0);
461
                                writereg(cs->hw.sedl.adr, cs->hw.sedl.isac,
462
                                        ISAC_MASK, 0xFF);
463
                                reset_sedlbauer(cs);
464
                                writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
465
                                        ISAR_IRQBIT, 0);
466
                                writereg(cs->hw.sedl.adr, cs->hw.sedl.isac,
467
                                        ISAC_MASK, 0xFF);
468
                                spin_unlock_irqrestore(&cs->lock, flags);
469
                        }
470
                        release_io_sedlbauer(cs);
471
                        return(0);
472
                case CARD_INIT:
473
                        spin_lock_irqsave(&cs->lock, flags);
474
                        if (cs->hw.sedl.bus == SEDL_BUS_PCI)
475
                                /* enable all IRQ */
476
                                byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
477
                        reset_sedlbauer(cs);
478
                        if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
479
                                clear_pending_isac_ints(cs);
480
                                writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
481
                                        ISAR_IRQBIT, 0);
482
                                initisac(cs);
483
                                initisar(cs);
484
                                /* Reenable all IRQ */
485
                                cs->writeisac(cs, ISAC_MASK, 0);
486
                                /* RESET Receiver and Transmitter */
487
                                cs->writeisac(cs, ISAC_CMDR, 0x41);
488
                        } else {
489
                                inithscxisac(cs, 3);
490
                        }
491
                        spin_unlock_irqrestore(&cs->lock, flags);
492
                        return(0);
493
                case CARD_TEST:
494
                        return(0);
495
                case MDL_INFO_CONN:
496
                        if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
497
                                return(0);
498
                        spin_lock_irqsave(&cs->lock, flags);
499
                        if ((long) arg)
500
                                cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED2;
501
                        else
502
                                cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED1;
503
                        byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
504
                        spin_unlock_irqrestore(&cs->lock, flags);
505
                        break;
506
                case MDL_INFO_REL:
507
                        if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
508
                                return(0);
509
                        spin_lock_irqsave(&cs->lock, flags);
510
                        if ((long) arg)
511
                                cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED2;
512
                        else
513
                                cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED1;
514
                        byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
515
                        spin_unlock_irqrestore(&cs->lock, flags);
516
                        break;
517
        }
518
        return(0);
519
}
520
 
521
#ifdef __ISAPNP__
522
static struct isapnp_device_id sedl_ids[] __devinitdata = {
523
        { ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01),
524
          ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01),
525
          (unsigned long) "Speed win" },
526
        { ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02),
527
          ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02),
528
          (unsigned long) "Speed Fax+" },
529
        { 0, }
530
};
531
 
532
static struct isapnp_device_id *ipid __devinitdata = &sedl_ids[0];
533
static struct pnp_card *pnp_c __devinitdata = NULL;
534
 
535
static int __devinit
536
setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt)
537
{
538
        struct IsdnCardState *cs = card->cs;
539
        struct pnp_dev *pnp_d;
540
 
541
        if (!isapnp_present())
542
                return -1;
543
 
544
        while(ipid->card_vendor) {
545
                if ((pnp_c = pnp_find_card(ipid->card_vendor,
546
                        ipid->card_device, pnp_c))) {
547
                        pnp_d = NULL;
548
                        if ((pnp_d = pnp_find_dev(pnp_c,
549
                                ipid->vendor, ipid->function, pnp_d))) {
550
                                int err;
551
 
552
                                printk(KERN_INFO "HiSax: %s detected\n",
553
                                        (char *)ipid->driver_data);
554
                                pnp_disable_dev(pnp_d);
555
                                err = pnp_activate_dev(pnp_d);
556
                                if (err<0) {
557
                                        printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
558
                                                __FUNCTION__, err);
559
                                        return(0);
560
                                }
561
                                card->para[1] = pnp_port_start(pnp_d, 0);
562
                                card->para[0] = pnp_irq(pnp_d, 0);
563
 
564
                                if (!card->para[0] || !card->para[1]) {
565
                                        printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n",
566
                                                card->para[0], card->para[1]);
567
                                        pnp_disable_dev(pnp_d);
568
                                        return(0);
569
                                }
570
                                cs->hw.sedl.cfg_reg = card->para[1];
571
                                cs->irq = card->para[0];
572
                                if (ipid->function == ISAPNP_FUNCTION(0x2)) {
573
                                        cs->subtyp = SEDL_SPEED_FAX;
574
                                        cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
575
                                        *bytecnt = 16;
576
                                } else {
577
                                        cs->subtyp = SEDL_SPEED_CARD_WIN;
578
                                        cs->hw.sedl.chip = SEDL_CHIP_TEST;
579
                                }
580
 
581
                                return (1);
582
                        } else {
583
                                printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n");
584
                                return(0);
585
                        }
586
                }
587
                ipid++;
588
                pnp_c = NULL;
589
        }
590
 
591
        printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n");
592
        return -1;
593
}
594
#else
595
 
596
static int __devinit
597
setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt)
598
{
599
        return -1;
600
}
601
#endif /* __ISAPNP__ */
602
 
603
#ifdef CONFIG_PCI_LEGACY
604
static struct pci_dev *dev_sedl __devinitdata = NULL;
605
 
606
static int __devinit
607
setup_sedlbauer_pci(struct IsdnCard *card)
608
{
609
        struct IsdnCardState *cs = card->cs;
610
        u16 sub_vendor_id, sub_id;
611
 
612
        if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET,
613
                        PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) {
614
                if (pci_enable_device(dev_sedl))
615
                        return(0);
616
                cs->irq = dev_sedl->irq;
617
                if (!cs->irq) {
618
                        printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
619
                        return(0);
620
                }
621
                cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0);
622
        } else {
623
                printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
624
                return(0);
625
        }
626
        cs->irq_flags |= IRQF_SHARED;
627
        cs->hw.sedl.bus = SEDL_BUS_PCI;
628
        sub_vendor_id = dev_sedl->subsystem_vendor;
629
        sub_id = dev_sedl->subsystem_device;
630
        printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n",
631
                sub_vendor_id, sub_id);
632
        printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n",
633
                cs->hw.sedl.cfg_reg);
634
        if (sub_id != PCI_SUB_ID_SEDLBAUER) {
635
                printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id);
636
                return(0);
637
        }
638
        if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) {
639
                cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
640
                cs->subtyp = SEDL_SPEEDFAX_PYRAMID;
641
        } else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) {
642
                cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
643
                cs->subtyp = SEDL_SPEEDFAX_PCI;
644
        } else if (sub_vendor_id == PCI_SUBVENDOR_HST_SAPHIR3) {
645
                cs->hw.sedl.chip = SEDL_CHIP_IPAC;
646
                cs->subtyp = HST_SAPHIR3;
647
        } else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) {
648
                cs->hw.sedl.chip = SEDL_CHIP_IPAC;
649
                cs->subtyp = SEDL_SPEED_PCI;
650
        } else {
651
                printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n",
652
                        sub_vendor_id);
653
                return(0);
654
        }
655
 
656
        cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
657
        cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF;
658
        byteout(cs->hw.sedl.cfg_reg, 0xff);
659
        byteout(cs->hw.sedl.cfg_reg, 0x00);
660
        byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
661
        byteout(cs->hw.sedl.cfg_reg+ 5, 0); /* disable all IRQ */
662
        byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
663
        mdelay(2);
664
        byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
665
        mdelay(10);
666
 
667
        return (1);
668
}
669
 
670
#else
671
 
672
static int __devinit
673
setup_sedlbauer_pci(struct IsdnCard *card)
674
{
675
        return (1);
676
}
677
 
678
#endif /* CONFIG_PCI_LEGACY */
679
 
680
int __devinit
681
setup_sedlbauer(struct IsdnCard *card)
682
{
683
        int bytecnt = 8, ver, val, rc;
684
        struct IsdnCardState *cs = card->cs;
685
        char tmp[64];
686
 
687
        strcpy(tmp, Sedlbauer_revision);
688
        printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp));
689
 
690
        if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
691
                cs->subtyp = SEDL_SPEED_CARD_WIN;
692
                cs->hw.sedl.bus = SEDL_BUS_ISA;
693
                cs->hw.sedl.chip = SEDL_CHIP_TEST;
694
        } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {
695
                cs->subtyp = SEDL_SPEED_STAR;
696
                cs->hw.sedl.bus = SEDL_BUS_PCMCIA;
697
                cs->hw.sedl.chip = SEDL_CHIP_TEST;
698
        } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {
699
                cs->subtyp = SEDL_SPEED_FAX;
700
                cs->hw.sedl.bus = SEDL_BUS_ISA;
701
                cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
702
        } else
703
                return (0);
704
 
705
        bytecnt = 8;
706
        if (card->para[1]) {
707
                cs->hw.sedl.cfg_reg = card->para[1];
708
                cs->irq = card->para[0];
709
                if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
710
                        bytecnt = 16;
711
                }
712
        } else {
713
                rc = setup_sedlbauer_isapnp(card, &bytecnt);
714
                if (!rc)
715
                        return (0);
716
                if (rc > 0)
717
                        goto ready;
718
 
719
                /* Probe for Sedlbauer speed pci */
720
                rc = setup_sedlbauer_pci(card);
721
                if (!rc)
722
                        return (0);
723
 
724
                bytecnt = 256;
725
        }
726
 
727
ready:
728
 
729
        /* In case of the sedlbauer pcmcia card, this region is in use,
730
         * reserved for us by the card manager. So we do not check it
731
         * here, it would fail.
732
         */
733
        if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA &&
734
                !request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn")) {
735
                printk(KERN_WARNING
736
                        "HiSax: %s config port %x-%x already in use\n",
737
                        CardType[card->typ],
738
                        cs->hw.sedl.cfg_reg,
739
                        cs->hw.sedl.cfg_reg + bytecnt);
740
                        return (0);
741
        }
742
 
743
        printk(KERN_INFO
744
               "Sedlbauer: defined at 0x%x-0x%x IRQ %d\n",
745
               cs->hw.sedl.cfg_reg,
746
               cs->hw.sedl.cfg_reg + bytecnt,
747
               cs->irq);
748
 
749
        cs->BC_Read_Reg = &ReadHSCX;
750
        cs->BC_Write_Reg = &WriteHSCX;
751
        cs->BC_Send_Data = &hscx_fill_fifo;
752
        cs->cardmsg = &Sedl_card_msg;
753
 
754
/*
755
 * testing ISA and PCMCIA Cards for IPAC, default is ISAC
756
 * do not test for PCI card, because ports are different
757
 * and PCI card uses only IPAC (for the moment)
758
 */
759
        if (cs->hw.sedl.bus != SEDL_BUS_PCI) {
760
                val = readreg(cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR,
761
                        cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID);
762
                printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val);
763
                if ((val == 1) || (val == 2)) {
764
                        /* IPAC */
765
                        cs->subtyp = SEDL_SPEED_WIN2_PC104;
766
                        if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
767
                                cs->subtyp = SEDL_SPEED_STAR2;
768
                        }
769
                        cs->hw.sedl.chip = SEDL_CHIP_IPAC;
770
                } else {
771
                        /* ISAC_HSCX oder ISAC_ISAR */
772
                        if (cs->hw.sedl.chip == SEDL_CHIP_TEST) {
773
                                cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX;
774
                        }
775
                }
776
        }
777
 
778
/*
779
 * hw.sedl.chip is now properly set
780
 */
781
        printk(KERN_INFO "Sedlbauer: %s detected\n",
782
                Sedlbauer_Types[cs->subtyp]);
783
 
784
        setup_isac(cs);
785
        if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
786
                if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
787
                        cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
788
                        cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
789
                        cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
790
                } else {
791
                        cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
792
                        cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
793
                        cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
794
                }
795
                test_and_set_bit(HW_IPAC, &cs->HW_Flags);
796
                cs->readisac = &ReadISAC_IPAC;
797
                cs->writeisac = &WriteISAC_IPAC;
798
                cs->readisacfifo = &ReadISACfifo_IPAC;
799
                cs->writeisacfifo = &WriteISACfifo_IPAC;
800
                cs->irq_func = &sedlbauer_interrupt_ipac;
801
                val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ID);
802
                printk(KERN_INFO "Sedlbauer: IPAC version %x\n", val);
803
        } else {
804
                /* ISAC_HSCX oder ISAC_ISAR */
805
                cs->readisac = &ReadISAC;
806
                cs->writeisac = &WriteISAC;
807
                cs->readisacfifo = &ReadISACfifo;
808
                cs->writeisacfifo = &WriteISACfifo;
809
                if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
810
                        if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
811
                                cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
812
                                                        SEDL_ISAR_PCI_ADR;
813
                                cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
814
                                                        SEDL_ISAR_PCI_ISAC;
815
                                cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
816
                                                        SEDL_ISAR_PCI_ISAR;
817
                        } else {
818
                                cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
819
                                                        SEDL_ISAR_ISA_ADR;
820
                                cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
821
                                                        SEDL_ISAR_ISA_ISAC;
822
                                cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
823
                                                        SEDL_ISAR_ISA_ISAR;
824
                                cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg +
825
                                                        SEDL_ISAR_ISA_ISAR_RESET_ON;
826
                                cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg +
827
                                                        SEDL_ISAR_ISA_ISAR_RESET_OFF;
828
                        }
829
                        cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar;
830
                        cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar;
831
                        test_and_set_bit(HW_ISAR, &cs->HW_Flags);
832
                        cs->irq_func = &sedlbauer_interrupt_isar;
833
                        cs->auxcmd = &isar_auxcmd;
834
                        ISACVersion(cs, "Sedlbauer:");
835
                        cs->BC_Read_Reg = &ReadISAR;
836
                        cs->BC_Write_Reg = &WriteISAR;
837
                        cs->BC_Send_Data = &isar_fill_fifo;
838
                        bytecnt = 3;
839
                        while (bytecnt) {
840
                                ver = ISARVersion(cs, "Sedlbauer:");
841
                                if (ver < 0)
842
                                        printk(KERN_WARNING
843
                                                "Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
844
                                else
845
                                        break;
846
                                reset_sedlbauer(cs);
847
                                bytecnt--;
848
                        }
849
                        if (!bytecnt) {
850
                                release_io_sedlbauer(cs);
851
                                return (0);
852
                        }
853
                } else {
854
                        if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
855
                                cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR;
856
                                cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC;
857
                                cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX;
858
                                cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
859
                                cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
860
                                cs->irq_flags |= IRQF_SHARED;
861
                        } else {
862
                                cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR;
863
                                cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC;
864
                                cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX;
865
                                cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON;
866
                                cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF;
867
                        }
868
                        cs->irq_func = &sedlbauer_interrupt;
869
                        ISACVersion(cs, "Sedlbauer:");
870
 
871
                        if (HscxVersion(cs, "Sedlbauer:")) {
872
                                printk(KERN_WARNING
873
                                        "Sedlbauer: wrong HSCX versions check IO address\n");
874
                                release_io_sedlbauer(cs);
875
                                return (0);
876
                        }
877
                }
878
        }
879
        return (1);
880
}

powered by: WebSVN 2.1.0

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