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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $Id: avm_a1.c,v 2.15.2.4 2004/01/13 21:46:03 keil Exp $
2
 *
3
 * low level stuff for AVM A1 (Fritz) isdn cards
4
 *
5
 * Author       Karsten Keil
6
 * Copyright    by Karsten Keil      <keil@isdn4linux.de>
7
 *
8
 * This software may be used and distributed according to the terms
9
 * of the GNU General Public License, incorporated herein by reference.
10
 *
11
 */
12
 
13
#include <linux/init.h>
14
#include "hisax.h"
15
#include "isac.h"
16
#include "hscx.h"
17
#include "isdnl1.h"
18
 
19
extern const char *CardType[];
20
static const char *avm_revision = "$Revision: 2.15.2.4 $";
21
 
22
#define  AVM_A1_STAT_ISAC       0x01
23
#define  AVM_A1_STAT_HSCX       0x02
24
#define  AVM_A1_STAT_TIMER      0x04
25
 
26
#define byteout(addr,val) outb(val,addr)
27
#define bytein(addr) inb(addr)
28
 
29
static inline u_char
30
readreg(unsigned int adr, u_char off)
31
{
32
        return (bytein(adr + off));
33
}
34
 
35
static inline void
36
writereg(unsigned int adr, u_char off, u_char data)
37
{
38
        byteout(adr + off, data);
39
}
40
 
41
 
42
static inline void
43
read_fifo(unsigned int adr, u_char * data, int size)
44
{
45
        insb(adr, data, size);
46
}
47
 
48
static void
49
write_fifo(unsigned int adr, u_char * data, int size)
50
{
51
        outsb(adr, data, size);
52
}
53
 
54
/* Interface functions */
55
 
56
static u_char
57
ReadISAC(struct IsdnCardState *cs, u_char offset)
58
{
59
        return (readreg(cs->hw.avm.isac, offset));
60
}
61
 
62
static void
63
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
64
{
65
        writereg(cs->hw.avm.isac, offset, value);
66
}
67
 
68
static void
69
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
70
{
71
        read_fifo(cs->hw.avm.isacfifo, data, size);
72
}
73
 
74
static void
75
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
76
{
77
        write_fifo(cs->hw.avm.isacfifo, data, size);
78
}
79
 
80
static u_char
81
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
82
{
83
        return (readreg(cs->hw.avm.hscx[hscx], offset));
84
}
85
 
86
static void
87
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
88
{
89
        writereg(cs->hw.avm.hscx[hscx], offset, value);
90
}
91
 
92
/*
93
 * fast interrupt HSCX stuff goes here
94
 */
95
 
96
#define READHSCX(cs, nr, reg) readreg(cs->hw.avm.hscx[nr], reg)
97
#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.avm.hscx[nr], reg, data)
98
#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.avm.hscxfifo[nr], ptr, cnt)
99
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.avm.hscxfifo[nr], ptr, cnt)
100
 
101
#include "hscx_irq.c"
102
 
103
static irqreturn_t
104
avm_a1_interrupt(int intno, void *dev_id)
105
{
106
        struct IsdnCardState *cs = dev_id;
107
        u_char val, sval;
108
        u_long flags;
109
 
110
        spin_lock_irqsave(&cs->lock, flags);
111
        while (((sval = bytein(cs->hw.avm.cfg_reg)) & 0xf) != 0x7) {
112
                if (!(sval & AVM_A1_STAT_TIMER)) {
113
                        byteout(cs->hw.avm.cfg_reg, 0x1E);
114
                        sval = bytein(cs->hw.avm.cfg_reg);
115
                } else if (cs->debug & L1_DEB_INTSTAT)
116
                        debugl1(cs, "avm IntStatus %x", sval);
117
                if (!(sval & AVM_A1_STAT_HSCX)) {
118
                        val = readreg(cs->hw.avm.hscx[1], HSCX_ISTA);
119
                        if (val)
120
                                hscx_int_main(cs, val);
121
                }
122
                if (!(sval & AVM_A1_STAT_ISAC)) {
123
                        val = readreg(cs->hw.avm.isac, ISAC_ISTA);
124
                        if (val)
125
                                isac_interrupt(cs, val);
126
                }
127
        }
128
        writereg(cs->hw.avm.hscx[0], HSCX_MASK, 0xFF);
129
        writereg(cs->hw.avm.hscx[1], HSCX_MASK, 0xFF);
130
        writereg(cs->hw.avm.isac, ISAC_MASK, 0xFF);
131
        writereg(cs->hw.avm.isac, ISAC_MASK, 0x0);
132
        writereg(cs->hw.avm.hscx[0], HSCX_MASK, 0x0);
133
        writereg(cs->hw.avm.hscx[1], HSCX_MASK, 0x0);
134
        spin_unlock_irqrestore(&cs->lock, flags);
135
        return IRQ_HANDLED;
136
}
137
 
138
static inline void
139
release_ioregs(struct IsdnCardState *cs, int mask)
140
{
141
        release_region(cs->hw.avm.cfg_reg, 8);
142
        if (mask & 1)
143
                release_region(cs->hw.avm.isac + 32, 32);
144
        if (mask & 2)
145
                release_region(cs->hw.avm.isacfifo, 1);
146
        if (mask & 4)
147
                release_region(cs->hw.avm.hscx[0] + 32, 32);
148
        if (mask & 8)
149
                release_region(cs->hw.avm.hscxfifo[0], 1);
150
        if (mask & 0x10)
151
                release_region(cs->hw.avm.hscx[1] + 32, 32);
152
        if (mask & 0x20)
153
                release_region(cs->hw.avm.hscxfifo[1], 1);
154
}
155
 
156
static int
157
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
158
{
159
        u_long flags;
160
 
161
        switch (mt) {
162
                case CARD_RESET:
163
                        return(0);
164
                case CARD_RELEASE:
165
                        release_ioregs(cs, 0x3f);
166
                        return(0);
167
                case CARD_INIT:
168
                        spin_lock_irqsave(&cs->lock, flags);
169
                        inithscxisac(cs, 1);
170
                        byteout(cs->hw.avm.cfg_reg, 0x16);
171
                        byteout(cs->hw.avm.cfg_reg, 0x1E);
172
                        inithscxisac(cs, 2);
173
                        spin_unlock_irqrestore(&cs->lock, flags);
174
                        return(0);
175
                case CARD_TEST:
176
                        return(0);
177
        }
178
        return(0);
179
}
180
 
181
int __devinit
182
setup_avm_a1(struct IsdnCard *card)
183
{
184
        u_char val;
185
        struct IsdnCardState *cs = card->cs;
186
        char tmp[64];
187
 
188
        strcpy(tmp, avm_revision);
189
        printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp));
190
        if (cs->typ != ISDN_CTYPE_A1)
191
                return (0);
192
 
193
        cs->hw.avm.cfg_reg = card->para[1] + 0x1800;
194
        cs->hw.avm.isac = card->para[1] + 0x1400 - 0x20;
195
        cs->hw.avm.hscx[0] = card->para[1] + 0x400 - 0x20;
196
        cs->hw.avm.hscx[1] = card->para[1] + 0xc00 - 0x20;
197
        cs->hw.avm.isacfifo = card->para[1] + 0x1000;
198
        cs->hw.avm.hscxfifo[0] = card->para[1];
199
        cs->hw.avm.hscxfifo[1] = card->para[1] + 0x800;
200
        cs->irq = card->para[0];
201
        if (!request_region(cs->hw.avm.cfg_reg, 8, "avm cfg")) {
202
                printk(KERN_WARNING
203
                       "HiSax: %s config port %x-%x already in use\n",
204
                       CardType[card->typ],
205
                       cs->hw.avm.cfg_reg,
206
                       cs->hw.avm.cfg_reg + 8);
207
                return (0);
208
        }
209
        if (!request_region(cs->hw.avm.isac + 32, 32, "HiSax isac")) {
210
                printk(KERN_WARNING
211
                       "HiSax: %s isac ports %x-%x already in use\n",
212
                       CardType[cs->typ],
213
                       cs->hw.avm.isac + 32,
214
                       cs->hw.avm.isac + 64);
215
                release_ioregs(cs, 0);
216
                return (0);
217
        }
218
        if (!request_region(cs->hw.avm.isacfifo, 1, "HiSax isac fifo")) {
219
                printk(KERN_WARNING
220
                       "HiSax: %s isac fifo port %x already in use\n",
221
                       CardType[cs->typ],
222
                       cs->hw.avm.isacfifo);
223
                release_ioregs(cs, 1);
224
                return (0);
225
        }
226
        if (!request_region(cs->hw.avm.hscx[0] + 32, 32, "HiSax hscx A")) {
227
                printk(KERN_WARNING
228
                       "HiSax: %s hscx A ports %x-%x already in use\n",
229
                       CardType[cs->typ],
230
                       cs->hw.avm.hscx[0] + 32,
231
                       cs->hw.avm.hscx[0] + 64);
232
                release_ioregs(cs, 3);
233
                return (0);
234
        }
235
        if (!request_region(cs->hw.avm.hscxfifo[0], 1, "HiSax hscx A fifo")) {
236
                printk(KERN_WARNING
237
                       "HiSax: %s hscx A fifo port %x already in use\n",
238
                       CardType[cs->typ],
239
                       cs->hw.avm.hscxfifo[0]);
240
                release_ioregs(cs, 7);
241
                return (0);
242
        }
243
        if (!request_region(cs->hw.avm.hscx[1] + 32, 32, "HiSax hscx B")) {
244
                printk(KERN_WARNING
245
                       "HiSax: %s hscx B ports %x-%x already in use\n",
246
                       CardType[cs->typ],
247
                       cs->hw.avm.hscx[1] + 32,
248
                       cs->hw.avm.hscx[1] + 64);
249
                release_ioregs(cs, 0xf);
250
                return (0);
251
        }
252
        if (!request_region(cs->hw.avm.hscxfifo[1], 1, "HiSax hscx B fifo")) {
253
                printk(KERN_WARNING
254
                       "HiSax: %s hscx B fifo port %x already in use\n",
255
                       CardType[cs->typ],
256
                       cs->hw.avm.hscxfifo[1]);
257
                release_ioregs(cs, 0x1f);
258
                return (0);
259
        }
260
        byteout(cs->hw.avm.cfg_reg, 0x0);
261
        HZDELAY(HZ / 5 + 1);
262
        byteout(cs->hw.avm.cfg_reg, 0x1);
263
        HZDELAY(HZ / 5 + 1);
264
        byteout(cs->hw.avm.cfg_reg, 0x0);
265
        HZDELAY(HZ / 5 + 1);
266
        val = cs->irq;
267
        if (val == 9)
268
                val = 2;
269
        byteout(cs->hw.avm.cfg_reg + 1, val);
270
        HZDELAY(HZ / 5 + 1);
271
        byteout(cs->hw.avm.cfg_reg, 0x0);
272
        HZDELAY(HZ / 5 + 1);
273
 
274
        val = bytein(cs->hw.avm.cfg_reg);
275
        printk(KERN_INFO "AVM A1: Byte at %x is %x\n",
276
               cs->hw.avm.cfg_reg, val);
277
        val = bytein(cs->hw.avm.cfg_reg + 3);
278
        printk(KERN_INFO "AVM A1: Byte at %x is %x\n",
279
               cs->hw.avm.cfg_reg + 3, val);
280
        val = bytein(cs->hw.avm.cfg_reg + 2);
281
        printk(KERN_INFO "AVM A1: Byte at %x is %x\n",
282
               cs->hw.avm.cfg_reg + 2, val);
283
        val = bytein(cs->hw.avm.cfg_reg);
284
        printk(KERN_INFO "AVM A1: Byte at %x is %x\n",
285
               cs->hw.avm.cfg_reg, val);
286
 
287
        printk(KERN_INFO
288
               "HiSax: %s config irq:%d cfg:0x%X\n",
289
               CardType[cs->typ], cs->irq,
290
               cs->hw.avm.cfg_reg);
291
        printk(KERN_INFO
292
               "HiSax: isac:0x%X/0x%X\n",
293
               cs->hw.avm.isac + 32, cs->hw.avm.isacfifo);
294
        printk(KERN_INFO
295
               "HiSax: hscx A:0x%X/0x%X  hscx B:0x%X/0x%X\n",
296
               cs->hw.avm.hscx[0] + 32, cs->hw.avm.hscxfifo[0],
297
               cs->hw.avm.hscx[1] + 32, cs->hw.avm.hscxfifo[1]);
298
 
299
        cs->readisac = &ReadISAC;
300
        cs->writeisac = &WriteISAC;
301
        cs->readisacfifo = &ReadISACfifo;
302
        cs->writeisacfifo = &WriteISACfifo;
303
        cs->BC_Read_Reg = &ReadHSCX;
304
        cs->BC_Write_Reg = &WriteHSCX;
305
        cs->BC_Send_Data = &hscx_fill_fifo;
306
        setup_isac(cs);
307
        cs->cardmsg = &AVM_card_msg;
308
        cs->irq_func = &avm_a1_interrupt;
309
        ISACVersion(cs, "AVM A1:");
310
        if (HscxVersion(cs, "AVM A1:")) {
311
                printk(KERN_WARNING
312
                       "AVM A1: wrong HSCX versions check IO address\n");
313
                release_ioregs(cs, 0x3f);
314
                return (0);
315
        }
316
        return (1);
317
}

powered by: WebSVN 2.1.0

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