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

Subversion Repositories or1k

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

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

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

powered by: WebSVN 2.1.0

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