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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [isdn/] [hisax/] [asuscom.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: asuscom.c,v 1.1 2005-12-20 10:17:01 jcastillo Exp $
2
 
3
 * asuscom.c     low level stuff for ASUSCOM NETWORK INC. ISDNLink cards
4
 *
5
 * Author     Karsten Keil (keil@isdn4linux.de)
6
 *
7
 * Thanks to  ASUSCOM NETWORK INC. Taiwan and  Dynalink NL for informations
8
 *
9
 *
10
 * $Log: not supported by cvs2svn $
11
 * Revision 1.1.1.1  2001/09/10 07:44:18  simons
12
 * Initial import
13
 *
14
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
15
 * Initial revision
16
 *
17
 * Revision 1.1.2.4  1998/11/03 00:05:42  keil
18
 * certification related changes
19
 * fixed logging for smaller stack use
20
 *
21
 * Revision 1.1.2.3  1998/06/18 23:10:26  keil
22
 * Support for new IPAC card
23
 *
24
 * Revision 1.1.2.2  1998/04/08 21:58:37  keil
25
 * New init code
26
 *
27
 * Revision 1.1.2.1  1998/01/27 22:34:02  keil
28
 * dynalink ----> asuscom
29
 *
30
 *
31
 */
32
 
33
#define __NO_VERSION__
34
#include "hisax.h"
35
#include "isac.h"
36
#include "ipac.h"
37
#include "hscx.h"
38
#include "isdnl1.h"
39
 
40
extern const char *CardType[];
41
 
42
const char *Asuscom_revision = "$Revision: 1.1 $";
43
 
44
#define byteout(addr,val) outb(val,addr)
45
#define bytein(addr) inb(addr)
46
 
47
#define ASUS_ISAC       0
48
#define ASUS_HSCX       1
49
#define ASUS_ADR        2
50
#define ASUS_CTRL_U7    3
51
#define ASUS_CTRL_POTS  5
52
 
53
#define ASUS_IPAC_ALE   0
54
#define ASUS_IPAC_DATA  1
55
 
56
#define ASUS_ISACHSCX   1
57
#define ASUS_IPAC       2
58
 
59
/* CARD_ADR (Write) */
60
#define ASUS_RESET      0x80    /* Bit 7 Reset-Leitung */
61
 
62
static inline u_char
63
readreg(unsigned int ale, unsigned int adr, u_char off)
64
{
65
        register u_char ret;
66
        long flags;
67
 
68
        save_flags(flags);
69
        cli();
70
        byteout(ale, off);
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
        /* fifo read without cli because it's allready done  */
80
 
81
        byteout(ale, off);
82
        insb(adr, data, size);
83
}
84
 
85
 
86
static inline void
87
writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
88
{
89
        long flags;
90
 
91
        save_flags(flags);
92
        cli();
93
        byteout(ale, off);
94
        byteout(adr, data);
95
        restore_flags(flags);
96
}
97
 
98
static inline void
99
writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
100
{
101
        /* fifo write without cli because it's allready done  */
102
        byteout(ale, off);
103
        outsb(adr, data, size);
104
}
105
 
106
/* Interface functions */
107
 
108
static u_char
109
ReadISAC(struct IsdnCardState *cs, u_char offset)
110
{
111
        return (readreg(cs->hw.asus.adr, cs->hw.asus.isac, offset));
112
}
113
 
114
static void
115
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
116
{
117
        writereg(cs->hw.asus.adr, cs->hw.asus.isac, offset, value);
118
}
119
 
120
static void
121
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
122
{
123
        readfifo(cs->hw.asus.adr, cs->hw.asus.isac, 0, data, size);
124
}
125
 
126
static void
127
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
128
{
129
        writefifo(cs->hw.asus.adr, cs->hw.asus.isac, 0, data, size);
130
}
131
 
132
static u_char
133
ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
134
{
135
        return (readreg(cs->hw.asus.adr, cs->hw.asus.isac, offset|0x80));
136
}
137
 
138
static void
139
WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
140
{
141
        writereg(cs->hw.asus.adr, cs->hw.asus.isac, offset|0x80, value);
142
}
143
 
144
static void
145
ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
146
{
147
        readfifo(cs->hw.asus.adr, cs->hw.asus.isac, 0x80, data, size);
148
}
149
 
150
static void
151
WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
152
{
153
        writefifo(cs->hw.asus.adr, cs->hw.asus.isac, 0x80, data, size);
154
}
155
 
156
static u_char
157
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
158
{
159
        return (readreg(cs->hw.asus.adr,
160
                        cs->hw.asus.hscx, offset + (hscx ? 0x40 : 0)));
161
}
162
 
163
static void
164
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
165
{
166
        writereg(cs->hw.asus.adr,
167
                 cs->hw.asus.hscx, offset + (hscx ? 0x40 : 0), value);
168
}
169
 
170
/*
171
 * fast interrupt HSCX stuff goes here
172
 */
173
 
174
#define READHSCX(cs, nr, reg) readreg(cs->hw.asus.adr, \
175
                cs->hw.asus.hscx, reg + (nr ? 0x40 : 0))
176
#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.asus.adr, \
177
                cs->hw.asus.hscx, reg + (nr ? 0x40 : 0), data)
178
 
179
#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.asus.adr, \
180
                cs->hw.asus.hscx, (nr ? 0x40 : 0), ptr, cnt)
181
 
182
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.asus.adr, \
183
                cs->hw.asus.hscx, (nr ? 0x40 : 0), ptr, cnt)
184
 
185
#include "hscx_irq.c"
186
 
187
static void
188
asuscom_interrupt(int intno, void *dev_id, struct pt_regs *regs)
189
{
190
        struct IsdnCardState *cs = dev_id;
191
        u_char val, stat = 0;
192
 
193
        if (!cs) {
194
                printk(KERN_WARNING "ISDNLink: Spurious interrupt!\n");
195
                return;
196
        }
197
        val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40);
198
      Start_HSCX:
199
        if (val) {
200
                hscx_int_main(cs, val);
201
                stat |= 1;
202
        }
203
        val = readreg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_ISTA);
204
      Start_ISAC:
205
        if (val) {
206
                isac_interrupt(cs, val);
207
                stat |= 2;
208
        }
209
        val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40);
210
        if (val) {
211
                if (cs->debug & L1_DEB_HSCX)
212
                        debugl1(cs, "HSCX IntStat after IntRoutine");
213
                goto Start_HSCX;
214
        }
215
        val = readreg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_ISTA);
216
        if (val) {
217
                if (cs->debug & L1_DEB_ISAC)
218
                        debugl1(cs, "ISAC IntStat after IntRoutine");
219
                goto Start_ISAC;
220
        }
221
        if (stat & 1) {
222
                writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK, 0xFF);
223
                writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK + 0x40, 0xFF);
224
                writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK, 0x0);
225
                writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK + 0x40, 0x0);
226
        }
227
        if (stat & 2) {
228
                writereg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_MASK, 0xFF);
229
                writereg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_MASK, 0x0);
230
        }
231
}
232
 
233
static void
234
asuscom_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
235
{
236
        struct IsdnCardState *cs = dev_id;
237
        u_char ista, val, icnt = 20;
238
 
239
        if (!cs) {
240
                printk(KERN_WARNING "ISDNLink: Spurious interrupt!\n");
241
                return;
242
        }
243
        ista = readreg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_ISTA);
244
Start_IPAC:
245
        if (cs->debug & L1_DEB_IPAC)
246
                debugl1(cs, "IPAC ISTA %02X", ista);
247
        if (ista & 0x0f) {
248
                val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40);
249
                if (ista & 0x01)
250
                        val |= 0x01;
251
                if (ista & 0x04)
252
                        val |= 0x02;
253
                if (ista & 0x08)
254
                        val |= 0x04;
255
                if (val)
256
                        hscx_int_main(cs, val);
257
        }
258
        if (ista & 0x20) {
259
                val = 0xfe & readreg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_ISTA | 0x80);
260
                if (val) {
261
                        isac_interrupt(cs, val);
262
                }
263
        }
264
        if (ista & 0x10) {
265
                val = 0x01;
266
                isac_interrupt(cs, val);
267
        }
268
        ista  = readreg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_ISTA);
269
        if ((ista & 0x3f) && icnt) {
270
                icnt--;
271
                goto Start_IPAC;
272
        }
273
        if (!icnt)
274
                printk(KERN_WARNING "ASUS IRQ LOOP\n");
275
        writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_MASK, 0xFF);
276
        writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_MASK, 0xC0);
277
}
278
 
279
void
280
release_io_asuscom(struct IsdnCardState *cs)
281
{
282
        int bytecnt = 8;
283
 
284
        if (cs->hw.asus.cfg_reg)
285
                release_region(cs->hw.asus.cfg_reg, bytecnt);
286
}
287
 
288
static void
289
reset_asuscom(struct IsdnCardState *cs)
290
{
291
        long flags;
292
 
293
        if (cs->subtyp == ASUS_IPAC)
294
                writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_POTA2, 0x20);
295
        else
296
                byteout(cs->hw.asus.adr, ASUS_RESET);   /* Reset On */
297
        save_flags(flags);
298
        sti();
299
        current->state = TASK_INTERRUPTIBLE;
300
        current->timeout = jiffies + 1;
301
        schedule();
302
        if (cs->subtyp == ASUS_IPAC)
303
                writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_POTA2, 0x0);
304
        else
305
                byteout(cs->hw.asus.adr, 0);     /* Reset Off */
306
        current->state = TASK_INTERRUPTIBLE;
307
        current->timeout = jiffies + 1;
308
        schedule();
309
        if (cs->subtyp == ASUS_IPAC) {
310
                writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_CONF, 0x0);
311
                writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_ACFG, 0xff);
312
                writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_AOE, 0x0);
313
                writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_MASK, 0xc0);
314
                writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_PCFG, 0x12);
315
        }
316
        restore_flags(flags);
317
}
318
 
319
static int
320
Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg)
321
{
322
        switch (mt) {
323
                case CARD_RESET:
324
                        reset_asuscom(cs);
325
                        return(0);
326
                case CARD_RELEASE:
327
                        release_io_asuscom(cs);
328
                        return(0);
329
                case CARD_SETIRQ:
330
                        if (cs->subtyp == ASUS_IPAC)
331
                                return(request_irq(cs->irq, &asuscom_interrupt_ipac,
332
                                        I4L_IRQ_FLAG, "HiSax", cs));
333
                        else
334
                                return(request_irq(cs->irq, &asuscom_interrupt,
335
                                        I4L_IRQ_FLAG, "HiSax", cs));
336
                case CARD_INIT:
337
                        cs->debug |= L1_DEB_IPAC;
338
                        inithscxisac(cs, 3);
339
                        return(0);
340
                case CARD_TEST:
341
                        return(0);
342
        }
343
        return(0);
344
}
345
 
346
__initfunc(int
347
setup_asuscom(struct IsdnCard *card))
348
{
349
        int bytecnt;
350
        struct IsdnCardState *cs = card->cs;
351
        u_char val;
352
        char tmp[64];
353
 
354
        strcpy(tmp, Asuscom_revision);
355
        printk(KERN_INFO "HiSax: Asuscom ISDNLink driver Rev. %s\n", HiSax_getrev(tmp));
356
        if (cs->typ != ISDN_CTYPE_ASUSCOM)
357
                return (0);
358
 
359
        bytecnt = 8;
360
        cs->hw.asus.cfg_reg = card->para[1];
361
        cs->irq = card->para[0];
362
        if (check_region((cs->hw.asus.cfg_reg), bytecnt)) {
363
                printk(KERN_WARNING
364
                       "HiSax: %s config port %x-%x already in use\n",
365
                       CardType[card->typ],
366
                       cs->hw.asus.cfg_reg,
367
                       cs->hw.asus.cfg_reg + bytecnt);
368
                return (0);
369
        } else {
370
                request_region(cs->hw.asus.cfg_reg, bytecnt, "asuscom isdn");
371
        }
372
        printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n",
373
                cs->hw.asus.cfg_reg, cs->irq);
374
        cs->BC_Read_Reg = &ReadHSCX;
375
        cs->BC_Write_Reg = &WriteHSCX;
376
        cs->BC_Send_Data = &hscx_fill_fifo;
377
        cs->cardmsg = &Asus_card_msg;
378
        val = readreg(cs->hw.asus.cfg_reg + ASUS_IPAC_ALE,
379
                cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID);
380
        if (val == 1) {
381
                cs->subtyp = ASUS_IPAC;
382
                cs->hw.asus.adr  = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE;
383
                cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA;
384
                cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA;
385
                test_and_set_bit(HW_IPAC, &cs->HW_Flags);
386
                cs->readisac = &ReadISAC_IPAC;
387
                cs->writeisac = &WriteISAC_IPAC;
388
                cs->readisacfifo = &ReadISACfifo_IPAC;
389
                cs->writeisacfifo = &WriteISACfifo_IPAC;
390
                printk(KERN_INFO "Asus: IPAC version %x\n", val);
391
        } else {
392
                cs->subtyp = ASUS_ISACHSCX;
393
                cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR;
394
                cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC;
395
                cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX;
396
                cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7;
397
                cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS;
398
                cs->readisac = &ReadISAC;
399
                cs->writeisac = &WriteISAC;
400
                cs->readisacfifo = &ReadISACfifo;
401
                cs->writeisacfifo = &WriteISACfifo;
402
                ISACVersion(cs, "ISDNLink:");
403
                if (HscxVersion(cs, "ISDNLink:")) {
404
                        printk(KERN_WARNING
405
                        "ISDNLink: wrong HSCX versions check IO address\n");
406
                        release_io_asuscom(cs);
407
                        return (0);
408
                }
409
        }
410
        printk(KERN_INFO "ISDNLink: resetting card\n");
411
        reset_asuscom(cs);
412
        return (1);
413
}

powered by: WebSVN 2.1.0

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