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

Subversion Repositories or1k

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

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

Line No. Rev Author Line
1 199 simons
/* $Id: teles3.c,v 1.1.1.1 2001-09-10 07:44:19 simons Exp $
2
 
3
 * teles3.c     low level stuff for Teles 16.3 & PNP isdn cards
4
 *
5
 *              based on the teles driver from Jan den Ouden
6
 *
7
 * Author       Karsten Keil (keil@temic-ech.spacenet.de)
8
 *
9
 * Thanks to    Jan den Ouden
10
 *              Fritz Elfert
11
 *              Beat Doebeli
12
 *
13
 * $Log: not supported by cvs2svn $
14
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
15
 * Initial revision
16
 *
17
 * Revision 1.11.2.9  1998/04/08 21:58:52  keil
18
 * New init code
19
 *
20
 * Revision 1.11.2.8  1998/01/27 22:37:46  keil
21
 * fast io
22
 *
23
 * Revision 1.11.2.7  1998/01/11 22:58:01  keil
24
 * make IRQ 9 working again
25
 *
26
 * Revision 1.11.2.6  1997/12/01 22:35:43  keil
27
 * ID Byte for 16.3 version 1.1
28
 *
29
 * Revision 1.11.2.5  1997/11/15 18:51:03  keil
30
 * new common init function
31
 *
32
 * Revision 1.11.2.4  1997/10/17 22:14:30  keil
33
 * update to last hisax version
34
 *
35
 * Revision 2.1  1997/07/27 21:47:12  keil
36
 * new interface structures
37
 *
38
 * Revision 2.0  1997/06/26 11:02:46  keil
39
 * New Layer and card interface
40
 *
41
 * Revision 1.11  1997/04/13 19:54:05  keil
42
 * Change in IRQ check delay for SMP
43
 *
44
 * Revision 1.10  1997/04/06 22:54:05  keil
45
 * Using SKB's
46
 *
47
 * Revision 1.9  1997/03/22 02:01:07  fritz
48
 * -Reworked toplevel Makefile. From now on, no different Makefiles
49
 *  for standalone- and in-kernel-compilation are needed any more.
50
 * -Added local Rules.make for above reason.
51
 * -Experimental changes in teles3.c for enhanced IRQ-checking with
52
 *  2.1.X and SMP kernels.
53
 * -Removed diffstd-script, same functionality is in stddiff -r.
54
 * -Enhanced scripts std2kern and stddiff.
55
 *
56
 * Revision 1.8  1997/02/23 18:43:55  fritz
57
 * Added support for Teles-Vision.
58
 *
59
 * Revision 1.7  1997/01/28 22:48:33  keil
60
 * fixes for Teles PCMCIA (Christof Petig)
61
 *
62
 * Revision 1.6  1997/01/27 15:52:55  keil
63
 * SMP proof,cosmetics, PCMCIA added
64
 *
65
 * removed old log info /KKe
66
 *
67
 */
68
#define __NO_VERSION__
69
#include "hisax.h"
70
#include "isac.h"
71
#include "hscx.h"
72
#include "isdnl1.h"
73
 
74
extern const char *CardType[];
75
const char *teles3_revision = "$Revision: 1.1.1.1 $";
76
 
77
#define byteout(addr,val) outb(val,addr)
78
#define bytein(addr) inb(addr)
79
 
80
static inline u_char
81
readreg(unsigned int adr, u_char off)
82
{
83
        return (bytein(adr + off));
84
}
85
 
86
static inline void
87
writereg(unsigned int adr, u_char off, u_char data)
88
{
89
        byteout(adr + off, data);
90
}
91
 
92
 
93
static inline void
94
read_fifo(unsigned int adr, u_char * data, int size)
95
{
96
        insb(adr, data, size);
97
}
98
 
99
static void
100
write_fifo(unsigned int adr, u_char * data, int size)
101
{
102
        outsb(adr, data, size);
103
}
104
 
105
/* Interface functions */
106
 
107
static u_char
108
ReadISAC(struct IsdnCardState *cs, u_char offset)
109
{
110
        return (readreg(cs->hw.teles3.isac, offset));
111
}
112
 
113
static void
114
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
115
{
116
        writereg(cs->hw.teles3.isac, offset, value);
117
}
118
 
119
static void
120
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
121
{
122
        read_fifo(cs->hw.teles3.isacfifo, data, size);
123
}
124
 
125
static void
126
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
127
{
128
        write_fifo(cs->hw.teles3.isacfifo, data, size);
129
}
130
 
131
static u_char
132
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
133
{
134
        return (readreg(cs->hw.teles3.hscx[hscx], offset));
135
}
136
 
137
static void
138
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
139
{
140
        writereg(cs->hw.teles3.hscx[hscx], offset, value);
141
}
142
 
143
/*
144
 * fast interrupt HSCX stuff goes here
145
 */
146
 
147
#define READHSCX(cs, nr, reg) readreg(cs->hw.teles3.hscx[nr], reg)
148
#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.teles3.hscx[nr], reg, data)
149
#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.teles3.hscxfifo[nr], ptr, cnt)
150
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.teles3.hscxfifo[nr], ptr, cnt)
151
 
152
#include "hscx_irq.c"
153
 
154
static void
155
teles3_interrupt(int intno, void *dev_id, struct pt_regs *regs)
156
{
157
#define MAXCOUNT 20
158
        struct IsdnCardState *cs = dev_id;
159
        u_char val, stat = 0;
160
        int count = 0;
161
 
162
        if (!cs) {
163
                printk(KERN_WARNING "Teles: Spurious interrupt!\n");
164
                return;
165
        }
166
        val = readreg(cs->hw.teles3.hscx[1], HSCX_ISTA);
167
      Start_HSCX:
168
        if (val) {
169
                hscx_int_main(cs, val);
170
                stat |= 1;
171
        }
172
        val = readreg(cs->hw.teles3.isac, ISAC_ISTA);
173
      Start_ISAC:
174
        if (val) {
175
                isac_interrupt(cs, val);
176
                stat |= 2;
177
        }
178
        count++;
179
        val = readreg(cs->hw.teles3.hscx[1], HSCX_ISTA);
180
        if (val && count < MAXCOUNT) {
181
                if (cs->debug & L1_DEB_HSCX)
182
                        debugl1(cs, "HSCX IntStat after IntRoutine");
183
                goto Start_HSCX;
184
        }
185
        val = readreg(cs->hw.teles3.isac, ISAC_ISTA);
186
        if (val && count < MAXCOUNT) {
187
                if (cs->debug & L1_DEB_ISAC)
188
                        debugl1(cs, "ISAC IntStat after IntRoutine");
189
                goto Start_ISAC;
190
        }
191
        if (count >= MAXCOUNT)
192
                printk(KERN_WARNING "Teles3: more than %d loops in teles3_interrupt\n", count);
193
        if (stat & 1) {
194
                writereg(cs->hw.teles3.hscx[0], HSCX_MASK, 0xFF);
195
                writereg(cs->hw.teles3.hscx[1], HSCX_MASK, 0xFF);
196
                writereg(cs->hw.teles3.hscx[0], HSCX_MASK, 0x0);
197
                writereg(cs->hw.teles3.hscx[1], HSCX_MASK, 0x0);
198
        }
199
        if (stat & 2) {
200
                writereg(cs->hw.teles3.isac, ISAC_MASK, 0xFF);
201
                writereg(cs->hw.teles3.isac, ISAC_MASK, 0x0);
202
        }
203
}
204
 
205
inline static void
206
release_ioregs(struct IsdnCardState *cs, int mask)
207
{
208
        if (mask & 1)
209
                release_region(cs->hw.teles3.isac + 32, 32);
210
        if (mask & 2)
211
                release_region(cs->hw.teles3.hscx[0] + 32, 32);
212
        if (mask & 4)
213
                release_region(cs->hw.teles3.hscx[1] + 32, 32);
214
}
215
 
216
void
217
release_io_teles3(struct IsdnCardState *cs)
218
{
219
        if (cs->typ == ISDN_CTYPE_TELESPCMCIA)
220
                release_region(cs->hw.teles3.cfg_reg, 97);
221
        else {
222
                if (cs->hw.teles3.cfg_reg)
223
                        if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
224
                                release_region(cs->hw.teles3.cfg_reg, 1);
225
                        } else {
226
                                release_region(cs->hw.teles3.cfg_reg, 8);
227
                        }
228
                release_ioregs(cs, 0x7);
229
        }
230
}
231
 
232
static int
233
reset_teles3(struct IsdnCardState *cs)
234
{
235
        long flags;
236
        u_char irqcfg;
237
 
238
        if (cs->typ != ISDN_CTYPE_TELESPCMCIA) {
239
                if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) {
240
                        switch (cs->irq) {
241
                                case 2:
242
                                case 9:
243
                                        irqcfg = 0x00;
244
                                        break;
245
                                case 3:
246
                                        irqcfg = 0x02;
247
                                        break;
248
                                case 4:
249
                                        irqcfg = 0x04;
250
                                        break;
251
                                case 5:
252
                                        irqcfg = 0x06;
253
                                        break;
254
                                case 10:
255
                                        irqcfg = 0x08;
256
                                        break;
257
                                case 11:
258
                                        irqcfg = 0x0A;
259
                                        break;
260
                                case 12:
261
                                        irqcfg = 0x0C;
262
                                        break;
263
                                case 15:
264
                                        irqcfg = 0x0E;
265
                                        break;
266
                                default:
267
                                        return(1);
268
                        }
269
                        save_flags(flags);
270
                        byteout(cs->hw.teles3.cfg_reg + 4, irqcfg);
271
                        sti();
272
                        HZDELAY(HZ / 10 + 1);
273
                        byteout(cs->hw.teles3.cfg_reg + 4, irqcfg | 1);
274
                        HZDELAY(HZ / 10 + 1);
275
                        restore_flags(flags);
276
                } else if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
277
                        save_flags(flags);
278
                        byteout(cs->hw.teles3.cfg_reg, 0xff);
279
                        HZDELAY(2);
280
                        byteout(cs->hw.teles3.cfg_reg, 0x00);
281
                        HZDELAY(2);
282
                        restore_flags(flags);
283
                } else {
284
                        /* Reset off for 16.3 PnP , thanks to Georg Acher */
285
                        save_flags(flags);
286
                        byteout(cs->hw.teles3.isac + 0x3c, 0);
287
                        HZDELAY(2);
288
                        byteout(cs->hw.teles3.isac + 0x3c, 1);
289
                        HZDELAY(2);
290
                        restore_flags(flags);
291
                }
292
        }
293
        return(0);
294
}
295
 
296
static int
297
Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg)
298
{
299
        switch (mt) {
300
                case CARD_RESET:
301
                        reset_teles3(cs);
302
                        return(0);
303
                case CARD_RELEASE:
304
                        release_io_teles3(cs);
305
                        return(0);
306
                case CARD_SETIRQ:
307
                        return(request_irq(cs->irq, &teles3_interrupt,
308
                                        I4L_IRQ_FLAG, "HiSax", cs));
309
                case CARD_INIT:
310
                        inithscxisac(cs, 3);
311
                        return(0);
312
                case CARD_TEST:
313
                        return(0);
314
        }
315
        return(0);
316
}
317
 
318
__initfunc(int
319
setup_teles3(struct IsdnCard *card))
320
{
321
        u_char val;
322
        struct IsdnCardState *cs = card->cs;
323
        char tmp[64];
324
 
325
        strcpy(tmp, teles3_revision);
326
        printk(KERN_INFO "HiSax: Teles IO driver Rev. %s\n", HiSax_getrev(tmp));
327
        if ((cs->typ != ISDN_CTYPE_16_3) && (cs->typ != ISDN_CTYPE_PNP)
328
            && (cs->typ != ISDN_CTYPE_TELESPCMCIA) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA))
329
                return (0);
330
 
331
        if (cs->typ == ISDN_CTYPE_16_3) {
332
                cs->hw.teles3.cfg_reg = card->para[1];
333
                switch (cs->hw.teles3.cfg_reg) {
334
                        case 0x180:
335
                        case 0x280:
336
                        case 0x380:
337
                                cs->hw.teles3.cfg_reg |= 0xc00;
338
                                break;
339
                }
340
                cs->hw.teles3.isac = cs->hw.teles3.cfg_reg - 0x420;
341
                cs->hw.teles3.hscx[0] = cs->hw.teles3.cfg_reg - 0xc20;
342
                cs->hw.teles3.hscx[1] = cs->hw.teles3.cfg_reg - 0x820;
343
        } else if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
344
                cs->hw.teles3.cfg_reg = card->para[1];
345
                cs->hw.teles3.hscx[0] = card->para[1] - 0x20;
346
                cs->hw.teles3.hscx[1] = card->para[1];
347
                cs->hw.teles3.isac = card->para[1] + 0x20;
348
        } else if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
349
                cs->hw.teles3.cfg_reg = card->para[3];
350
                cs->hw.teles3.isac = card->para[2] - 32;
351
                cs->hw.teles3.hscx[0] = card->para[1] - 32;
352
                cs->hw.teles3.hscx[1] = card->para[1];
353
        } else {        /* PNP */
354
                cs->hw.teles3.cfg_reg = 0;
355
                cs->hw.teles3.isac = card->para[1] - 32;
356
                cs->hw.teles3.hscx[0] = card->para[2] - 32;
357
                cs->hw.teles3.hscx[1] = card->para[2];
358
        }
359
        cs->irq = card->para[0];
360
        cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e;
361
        cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
362
        cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
363
        if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
364
                if (check_region((cs->hw.teles3.cfg_reg), 97)) {
365
                        printk(KERN_WARNING
366
                               "HiSax: %s ports %x-%x already in use\n",
367
                               CardType[cs->typ],
368
                               cs->hw.teles3.cfg_reg,
369
                               cs->hw.teles3.cfg_reg + 96);
370
                        return (0);
371
                } else
372
                        request_region(cs->hw.teles3.hscx[0], 97, "HiSax Teles PCMCIA");
373
        } else {
374
                if (cs->hw.teles3.cfg_reg) {
375
                        if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
376
                                if (check_region((cs->hw.teles3.cfg_reg), 1)) {
377
                                        printk(KERN_WARNING
378
                                                "HiSax: %s config port %x already in use\n",
379
                                                CardType[card->typ],
380
                                                cs->hw.teles3.cfg_reg);
381
                                        return (0);
382
                                } else
383
                                        request_region(cs->hw.teles3.cfg_reg, 1, "teles3 cfg");
384
                        } else {
385
                                if (check_region((cs->hw.teles3.cfg_reg), 8)) {
386
                                        printk(KERN_WARNING
387
                                               "HiSax: %s config port %x-%x already in use\n",
388
                                               CardType[card->typ],
389
                                               cs->hw.teles3.cfg_reg,
390
                                                cs->hw.teles3.cfg_reg + 8);
391
                                        return (0);
392
                                } else
393
                                        request_region(cs->hw.teles3.cfg_reg, 8, "teles3 cfg");
394
                        }
395
                }
396
                if (check_region((cs->hw.teles3.isac + 32), 32)) {
397
                        printk(KERN_WARNING
398
                           "HiSax: %s isac ports %x-%x already in use\n",
399
                               CardType[cs->typ],
400
                               cs->hw.teles3.isac + 32,
401
                               cs->hw.teles3.isac + 64);
402
                        if (cs->hw.teles3.cfg_reg)
403
                                if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
404
                                        release_region(cs->hw.teles3.cfg_reg, 1);
405
                                } else {
406
                                        release_region(cs->hw.teles3.cfg_reg, 8);
407
                                }
408
                        return (0);
409
                } else
410
                        request_region(cs->hw.teles3.isac + 32, 32, "HiSax isac");
411
                if (check_region((cs->hw.teles3.hscx[0] + 32), 32)) {
412
                        printk(KERN_WARNING
413
                         "HiSax: %s hscx A ports %x-%x already in use\n",
414
                               CardType[cs->typ],
415
                               cs->hw.teles3.hscx[0] + 32,
416
                               cs->hw.teles3.hscx[0] + 64);
417
                        if (cs->hw.teles3.cfg_reg)
418
                                if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
419
                                        release_region(cs->hw.teles3.cfg_reg, 1);
420
                                } else {
421
                                        release_region(cs->hw.teles3.cfg_reg, 8);
422
                                }
423
                        release_ioregs(cs, 1);
424
                        return (0);
425
                } else
426
                        request_region(cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A");
427
                if (check_region((cs->hw.teles3.hscx[1] + 32), 32)) {
428
                        printk(KERN_WARNING
429
                         "HiSax: %s hscx B ports %x-%x already in use\n",
430
                               CardType[cs->typ],
431
                               cs->hw.teles3.hscx[1] + 32,
432
                               cs->hw.teles3.hscx[1] + 64);
433
                        if (cs->hw.teles3.cfg_reg)
434
                                if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
435
                                        release_region(cs->hw.teles3.cfg_reg, 1);
436
                                } else {
437
                                        release_region(cs->hw.teles3.cfg_reg, 8);
438
                                }
439
                        release_ioregs(cs, 3);
440
                        return (0);
441
                } else
442
                        request_region(cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B");
443
        }
444
        if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) {
445
                if ((val = bytein(cs->hw.teles3.cfg_reg + 0)) != 0x51) {
446
                        printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
447
                               cs->hw.teles3.cfg_reg + 0, val);
448
                        release_io_teles3(cs);
449
                        return (0);
450
                }
451
                if ((val = bytein(cs->hw.teles3.cfg_reg + 1)) != 0x93) {
452
                        printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
453
                               cs->hw.teles3.cfg_reg + 1, val);
454
                        release_io_teles3(cs);
455
                        return (0);
456
                }
457
                val = bytein(cs->hw.teles3.cfg_reg + 2);/* 0x1e=without AB
458
                                                         * 0x1f=with AB
459
                                                         * 0x1c 16.3 ???
460
                                                         * 0x39 16.3 1.1
461
                                                         * 0x46 16.3 with AB + Video (Teles-Vision)
462
                                                         */
463
                if (val != 0x46 && val != 0x39 && val != 0x1c && val != 0x1e && val != 0x1f) {
464
                        printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
465
                               cs->hw.teles3.cfg_reg + 2, val);
466
                        release_io_teles3(cs);
467
                        return (0);
468
                }
469
        }
470
        printk(KERN_INFO
471
               "HiSax: %s config irq:%d isac:0x%X  cfg:0x%X\n",
472
               CardType[cs->typ], cs->irq,
473
               cs->hw.teles3.isac + 32, cs->hw.teles3.cfg_reg);
474
        printk(KERN_INFO
475
               "HiSax: hscx A:0x%X  hscx B:0x%X\n",
476
               cs->hw.teles3.hscx[0] + 32, cs->hw.teles3.hscx[1] + 32);
477
 
478
        if (reset_teles3(cs)) {
479
                printk(KERN_WARNING "Teles3: wrong IRQ\n");
480
                release_io_teles3(cs);
481
                return (0);
482
        }
483
        cs->readisac = &ReadISAC;
484
        cs->writeisac = &WriteISAC;
485
        cs->readisacfifo = &ReadISACfifo;
486
        cs->writeisacfifo = &WriteISACfifo;
487
        cs->BC_Read_Reg = &ReadHSCX;
488
        cs->BC_Write_Reg = &WriteHSCX;
489
        cs->BC_Send_Data = &hscx_fill_fifo;
490
        cs->cardmsg = &Teles_card_msg;
491
        ISACVersion(cs, "Teles3:");
492
        if (HscxVersion(cs, "Teles3:")) {
493
                printk(KERN_WARNING
494
                       "Teles3: wrong HSCX versions check IO address\n");
495
                release_io_teles3(cs);
496
                return (0);
497
        }
498
        return (1);
499
}

powered by: WebSVN 2.1.0

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