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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [isdn/] [hisax/] [teleint.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: teleint.c,v 1.1.1.1 2001-09-10 07:44:19 simons Exp $
2
 
3
 * teleint.c     low level stuff for TeleInt isdn cards
4
 *
5
 * Author     Karsten Keil (keil@isdn4linux.de)
6
 *
7
 *
8
 * $Log: not supported by cvs2svn $
9
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
10
 * Initial revision
11
 *
12
 * Revision 1.1.2.7  1998/11/03 00:07:39  keil
13
 * certification related changes
14
 * fixed logging for smaller stack use
15
 *
16
 * Revision 1.1.2.6  1998/05/27 18:06:24  keil
17
 * HiSax 3.0
18
 *
19
 * Revision 1.1.2.5  1998/04/08 21:58:48  keil
20
 * New init code
21
 *
22
 * Revision 1.1.2.4  1998/04/04 21:58:27  keil
23
 * fix HFC BUSY on ISAC fifos
24
 *
25
 * Revision 1.1.2.3  1998/01/27 22:37:41  keil
26
 * fast io
27
 *
28
 * Revision 1.1.2.2  1997/11/15 18:50:58  keil
29
 * new common init function
30
 *
31
 * Revision 1.1.2.1  1997/10/17 22:11:00  keil
32
 * new files on 2.0
33
 *
34
 * Revision 1.1  1997/09/11 17:32:32  keil
35
 * new
36
 *
37
 *
38
 */
39
 
40
#define __NO_VERSION__
41
#include "hisax.h"
42
#include "isac.h"
43
#include "hfc_2bs0.h"
44
#include "isdnl1.h"
45
 
46
extern const char *CardType[];
47
 
48
const char *TeleInt_revision = "$Revision: 1.1.1.1 $";
49
 
50
#define byteout(addr,val) outb(val,addr)
51
#define bytein(addr) inb(addr)
52
 
53
static inline u_char
54
readreg(unsigned int ale, unsigned int adr, u_char off)
55
{
56
        register u_char ret;
57
        int max_delay = 2000;
58
        long flags;
59
 
60
        save_flags(flags);
61
        cli();
62
        byteout(ale, off);
63
        ret = HFC_BUSY & bytein(ale);
64
        while (ret && --max_delay)
65
                ret = HFC_BUSY & bytein(ale);
66
        if (!max_delay) {
67
                printk(KERN_WARNING "TeleInt Busy not inaktive\n");
68
                restore_flags(flags);
69
                return (0);
70
        }
71
        ret = bytein(adr);
72
        restore_flags(flags);
73
        return (ret);
74
}
75
 
76
static inline void
77
readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
78
{
79
        register u_char ret;
80
        register int max_delay = 20000;
81
        register int i;
82
 
83
        byteout(ale, off);
84
        for (i = 0; i<size; i++) {
85
                ret = HFC_BUSY & bytein(ale);
86
                while (ret && --max_delay)
87
                        ret = HFC_BUSY & bytein(ale);
88
                if (!max_delay) {
89
                        printk(KERN_WARNING "TeleInt Busy not inaktive\n");
90
                        return;
91
                }
92
                data[i] = bytein(adr);
93
        }
94
}
95
 
96
 
97
static inline void
98
writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
99
{
100
        register u_char ret;
101
        int max_delay = 2000;
102
        long flags;
103
 
104
        save_flags(flags);
105
        cli();
106
        byteout(ale, off);
107
        ret = HFC_BUSY & bytein(ale);
108
        while (ret && --max_delay)
109
                ret = HFC_BUSY & bytein(ale);
110
        if (!max_delay) {
111
                printk(KERN_WARNING "TeleInt Busy not inaktive\n");
112
                restore_flags(flags);
113
                return;
114
        }
115
        byteout(adr, data);
116
        restore_flags(flags);
117
}
118
 
119
static inline void
120
writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
121
{
122
        register u_char ret;
123
        register int max_delay = 20000;
124
        register int i;
125
 
126
        /* fifo write without cli because it's allready done  */
127
        byteout(ale, off);
128
        for (i = 0; i<size; i++) {
129
                ret = HFC_BUSY & bytein(ale);
130
                while (ret && --max_delay)
131
                        ret = HFC_BUSY & bytein(ale);
132
                if (!max_delay) {
133
                        printk(KERN_WARNING "TeleInt Busy not inaktive\n");
134
                        return;
135
                }
136
                byteout(adr, data[i]);
137
        }
138
}
139
 
140
/* Interface functions */
141
 
142
static u_char
143
ReadISAC(struct IsdnCardState *cs, u_char offset)
144
{
145
        cs->hw.hfc.cip = offset;
146
        return (readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, offset));
147
}
148
 
149
static void
150
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
151
{
152
        cs->hw.hfc.cip = offset;
153
        writereg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, offset, value);
154
}
155
 
156
static void
157
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
158
{
159
        cs->hw.hfc.cip = 0;
160
        readfifo(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, 0, data, size);
161
}
162
 
163
static void
164
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
165
{
166
        cs->hw.hfc.cip = 0;
167
        writefifo(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, 0, data, size);
168
}
169
 
170
static u_char
171
ReadHFC(struct IsdnCardState *cs, int data, u_char reg)
172
{
173
        register u_char ret;
174
 
175
        if (data) {
176
                cs->hw.hfc.cip = reg;
177
                byteout(cs->hw.hfc.addr | 1, reg);
178
                ret = bytein(cs->hw.hfc.addr);
179
                if (cs->debug & L1_DEB_HSCX_FIFO && (data != 2))
180
                        debugl1(cs, "hfc RD %02x %02x", reg, ret);
181
        } else
182
                ret = bytein(cs->hw.hfc.addr | 1);
183
        return (ret);
184
}
185
 
186
static void
187
WriteHFC(struct IsdnCardState *cs, int data, u_char reg, u_char value)
188
{
189
        byteout(cs->hw.hfc.addr | 1, reg);
190
        cs->hw.hfc.cip = reg;
191
        if (data)
192
                byteout(cs->hw.hfc.addr, value);
193
        if (cs->debug & L1_DEB_HSCX_FIFO && (data != 2))
194
                debugl1(cs, "hfc W%c %02x %02x", data ? 'D' : 'C', reg, value);
195
}
196
 
197
static void
198
TeleInt_interrupt(int intno, void *dev_id, struct pt_regs *regs)
199
{
200
        struct IsdnCardState *cs = dev_id;
201
        u_char val, stat = 0;
202
 
203
        if (!cs) {
204
                printk(KERN_WARNING "TeleInt: Spurious interrupt!\n");
205
                return;
206
        }
207
        val = readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_ISTA);
208
      Start_ISAC:
209
        if (val) {
210
                isac_interrupt(cs, val);
211
                stat |= 2;
212
        }
213
        val = readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_ISTA);
214
        if (val) {
215
                if (cs->debug & L1_DEB_ISAC)
216
                        debugl1(cs, "ISAC IntStat after IntRoutine");
217
                goto Start_ISAC;
218
        }
219
        if (stat & 2) {
220
                writereg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_MASK, 0xFF);
221
                writereg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_MASK, 0x0);
222
        }
223
}
224
 
225
static void
226
TeleInt_Timer(struct IsdnCardState *cs)
227
{
228
        int stat = 0;
229
 
230
        if (cs->bcs[0].mode) {
231
                stat |= 1;
232
                main_irq_hfc(&cs->bcs[0]);
233
        }
234
        if (cs->bcs[1].mode) {
235
                stat |= 2;
236
                main_irq_hfc(&cs->bcs[1]);
237
        }
238
        cs->hw.hfc.timer.expires = jiffies + 1;
239
        add_timer(&cs->hw.hfc.timer);
240
}
241
 
242
void
243
release_io_TeleInt(struct IsdnCardState *cs)
244
{
245
        del_timer(&cs->hw.hfc.timer);
246
        releasehfc(cs);
247
        if (cs->hw.hfc.addr)
248
                release_region(cs->hw.hfc.addr, 2);
249
}
250
 
251
static void
252
reset_TeleInt(struct IsdnCardState *cs)
253
{
254
        long flags;
255
 
256
        printk(KERN_INFO "TeleInt: resetting card\n");
257
        cs->hw.hfc.cirm |= HFC_RESET;
258
        byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm);  /* Reset On */
259
        save_flags(flags);
260
        sti();
261
        current->state = TASK_INTERRUPTIBLE;
262
        current->timeout = jiffies + 3;
263
        schedule();
264
        cs->hw.hfc.cirm &= ~HFC_RESET;
265
        byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm);  /* Reset Off */
266
        current->state = TASK_INTERRUPTIBLE;
267
        current->timeout = jiffies + 1;
268
        schedule();
269
        restore_flags(flags);
270
}
271
 
272
static int
273
TeleInt_card_msg(struct IsdnCardState *cs, int mt, void *arg)
274
{
275
        switch (mt) {
276
                case CARD_RESET:
277
                        reset_TeleInt(cs);
278
                        return(0);
279
                case CARD_RELEASE:
280
                        release_io_TeleInt(cs);
281
                        return(0);
282
                case CARD_SETIRQ:
283
                        return(request_irq(cs->irq, &TeleInt_interrupt,
284
                                        I4L_IRQ_FLAG, "HiSax", cs));
285
                case CARD_INIT:
286
                        inithfc(cs);
287
                        clear_pending_isac_ints(cs);
288
                        initisac(cs);
289
                        /* Reenable all IRQ */
290
                        cs->writeisac(cs, ISAC_MASK, 0);
291
                        cs->writeisac(cs, ISAC_CMDR, 0x41);
292
                        cs->hw.hfc.timer.expires = jiffies + 1;
293
                        add_timer(&cs->hw.hfc.timer);
294
                        return(0);
295
                case CARD_TEST:
296
                        return(0);
297
        }
298
        return(0);
299
}
300
 
301
__initfunc(int
302
setup_TeleInt(struct IsdnCard *card))
303
{
304
        struct IsdnCardState *cs = card->cs;
305
        char tmp[64];
306
 
307
        strcpy(tmp, TeleInt_revision);
308
        printk(KERN_INFO "HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp));
309
        if (cs->typ != ISDN_CTYPE_TELEINT)
310
                return (0);
311
 
312
        cs->hw.hfc.addr = card->para[1] & 0x3fe;
313
        cs->irq = card->para[0];
314
        cs->hw.hfc.cirm = HFC_CIRM;
315
        cs->hw.hfc.isac_spcr = 0x00;
316
        cs->hw.hfc.cip = 0;
317
        cs->hw.hfc.ctmt = HFC_CTMT | HFC_CLTIMER;
318
        cs->bcs[0].hw.hfc.send = NULL;
319
        cs->bcs[1].hw.hfc.send = NULL;
320
        cs->hw.hfc.fifosize = 7 * 1024 + 512;
321
        cs->hw.hfc.timer.function = (void *) TeleInt_Timer;
322
        cs->hw.hfc.timer.data = (long) cs;
323
        init_timer(&cs->hw.hfc.timer);
324
        if (check_region((cs->hw.hfc.addr), 2)) {
325
                printk(KERN_WARNING
326
                       "HiSax: %s config port %x-%x already in use\n",
327
                       CardType[card->typ],
328
                       cs->hw.hfc.addr,
329
                       cs->hw.hfc.addr + 2);
330
                return (0);
331
        } else {
332
                request_region(cs->hw.hfc.addr, 2, "TeleInt isdn");
333
        }
334
        /* HW IO = IO */
335
        byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff);
336
        byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54);
337
        switch (cs->irq) {
338
                case 3:
339
                        cs->hw.hfc.cirm |= HFC_INTA;
340
                        break;
341
                case 4:
342
                        cs->hw.hfc.cirm |= HFC_INTB;
343
                        break;
344
                case 5:
345
                        cs->hw.hfc.cirm |= HFC_INTC;
346
                        break;
347
                case 7:
348
                        cs->hw.hfc.cirm |= HFC_INTD;
349
                        break;
350
                case 10:
351
                        cs->hw.hfc.cirm |= HFC_INTE;
352
                        break;
353
                case 11:
354
                        cs->hw.hfc.cirm |= HFC_INTF;
355
                        break;
356
                default:
357
                        printk(KERN_WARNING "TeleInt: wrong IRQ\n");
358
                        release_io_TeleInt(cs);
359
                        return (0);
360
        }
361
        byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm);
362
        byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt);
363
 
364
        printk(KERN_INFO
365
               "TeleInt: defined at 0x%x IRQ %d\n",
366
               cs->hw.hfc.addr,
367
               cs->irq);
368
 
369
        reset_TeleInt(cs);
370
        cs->readisac = &ReadISAC;
371
        cs->writeisac = &WriteISAC;
372
        cs->readisacfifo = &ReadISACfifo;
373
        cs->writeisacfifo = &WriteISACfifo;
374
        cs->BC_Read_Reg = &ReadHFC;
375
        cs->BC_Write_Reg = &WriteHFC;
376
        cs->cardmsg = &TeleInt_card_msg;
377
        ISACVersion(cs, "TeleInt:");
378
        return (1);
379
}

powered by: WebSVN 2.1.0

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