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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [isdn/] [hisax/] [s0box.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: s0box.c,v 1.1 2005-12-20 10:17:01 jcastillo Exp $
2
 
3
 * s0box.c      low level stuff for Creatix S0BOX
4
 *
5
 * Author       S0BOX specific stuff: Enrik Berkhan (enrik@starfleet.inka.de)
6
 *
7
 *
8
 */
9
#define __NO_VERSION__
10
#include "hisax.h"
11
#include "isac.h"
12
#include "hscx.h"
13
#include "isdnl1.h"
14
 
15
extern const char *CardType[];
16
const char *s0box_revision = "$Revision: 1.1 $";
17
 
18
static inline void
19
writereg(unsigned int padr, signed int addr, u_char off, u_char val) {
20
        unsigned long flags;
21
 
22
        save_flags(flags);
23
        cli();
24
        outb_p(0x1c,padr+2);
25
        outb_p(0x14,padr+2);
26
        outb_p((addr+off)&0x7f,padr);
27
        outb_p(0x16,padr+2);
28
        outb_p(val,padr);
29
        outb_p(0x17,padr+2);
30
        outb_p(0x14,padr+2);
31
        outb_p(0x1c,padr+2);
32
        restore_flags(flags);
33
}
34
 
35
static u_char nibtab[] = { 1, 9, 5, 0xd, 3, 0xb, 7, 0xf,
36
                         0, 0, 0, 0, 0, 0, 0, 0,
37
                         0, 8, 4, 0xc, 2, 0xa, 6, 0xe } ;
38
 
39
static inline u_char
40
readreg(unsigned int padr, signed int addr, u_char off) {
41
        register u_char n1, n2;
42
        unsigned long flags;
43
 
44
        save_flags(flags);
45
        cli();
46
        outb_p(0x1c,padr+2);
47
        outb_p(0x14,padr+2);
48
        outb_p((addr+off)|0x80,padr);
49
        outb_p(0x16,padr+2);
50
        outb_p(0x17,padr+2);
51
        n1 = (inb_p(padr+1) >> 3) & 0x17;
52
        outb_p(0x16,padr+2);
53
        n2 = (inb_p(padr+1) >> 3) & 0x17;
54
        outb_p(0x14,padr+2);
55
        outb_p(0x1c,padr+2);
56
        restore_flags(flags);
57
        return nibtab[n1] | (nibtab[n2] << 4);
58
}
59
 
60
static inline void
61
read_fifo(unsigned int padr, signed int adr, u_char * data, int size)
62
{
63
        int i;
64
        register u_char n1, n2;
65
 
66
        outb_p(0x1c, padr+2);
67
        outb_p(0x14, padr+2);
68
        outb_p(adr|0x80, padr);
69
        outb_p(0x16, padr+2);
70
        for (i=0; i<size; i++) {
71
                outb_p(0x17, padr+2);
72
                n1 = (inb_p(padr+1) >> 3) & 0x17;
73
                outb_p(0x16,padr+2);
74
                n2 = (inb_p(padr+1) >> 3) & 0x17;
75
                *(data++)=nibtab[n1] | (nibtab[n2] << 4);
76
        }
77
        outb_p(0x14,padr+2);
78
        outb_p(0x1c,padr+2);
79
        return;
80
}
81
 
82
static inline void
83
write_fifo(unsigned int padr, signed int adr, u_char * data, int size)
84
{
85
        int i;
86
        outb_p(0x1c, padr+2);
87
        outb_p(0x14, padr+2);
88
        outb_p(adr&0x7f, padr);
89
        for (i=0; i<size; i++) {
90
                outb_p(0x16, padr+2);
91
                outb_p(*(data++), padr);
92
                outb_p(0x17, padr+2);
93
        }
94
        outb_p(0x14,padr+2);
95
        outb_p(0x1c,padr+2);
96
        return;
97
}
98
 
99
/* Interface functions */
100
 
101
static u_char
102
ReadISAC(struct IsdnCardState *cs, u_char offset)
103
{
104
        return (readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, offset));
105
}
106
 
107
static void
108
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
109
{
110
        writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, offset, value);
111
}
112
 
113
static void
114
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
115
{
116
        read_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.isacfifo, data, size);
117
}
118
 
119
static void
120
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
121
{
122
        write_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.isacfifo, data, size);
123
}
124
 
125
static u_char
126
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
127
{
128
        return (readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[hscx], offset));
129
}
130
 
131
static void
132
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
133
{
134
        writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[hscx], offset, value);
135
}
136
 
137
/*
138
 * fast interrupt HSCX stuff goes here
139
 */
140
 
141
#define READHSCX(cs, nr, reg) readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[nr], reg)
142
#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[nr], reg, data)
143
#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscxfifo[nr], ptr, cnt)
144
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscxfifo[nr], ptr, cnt)
145
 
146
#include "hscx_irq.c"
147
 
148
static void
149
s0box_interrupt(int intno, void *dev_id, struct pt_regs *regs)
150
{
151
#define MAXCOUNT 20
152
        struct IsdnCardState *cs = dev_id;
153
        u_char val, stat = 0;
154
        int count = 0;
155
 
156
        if (!cs) {
157
                printk(KERN_WARNING "Teles: Spurious interrupt!\n");
158
                return;
159
        }
160
        val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_ISTA);
161
      Start_HSCX:
162
        if (val) {
163
                hscx_int_main(cs, val);
164
                stat |= 1;
165
        }
166
        val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_ISTA);
167
      Start_ISAC:
168
        if (val) {
169
                isac_interrupt(cs, val);
170
                stat |= 2;
171
        }
172
        count++;
173
        val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_ISTA);
174
        if (val && count < MAXCOUNT) {
175
                if (cs->debug & L1_DEB_HSCX)
176
                        debugl1(cs, "HSCX IntStat after IntRoutine");
177
                goto Start_HSCX;
178
        }
179
        val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_ISTA);
180
        if (val && count < MAXCOUNT) {
181
                if (cs->debug & L1_DEB_ISAC)
182
                        debugl1(cs, "ISAC IntStat after IntRoutine");
183
                goto Start_ISAC;
184
        }
185
        if (count >= MAXCOUNT)
186
                printk(KERN_WARNING "S0Box: more than %d loops in s0box_interrupt\n", count);
187
        if (stat & 1) {
188
                writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[0], HSCX_MASK, 0xFF);
189
                writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_MASK, 0xFF);
190
                writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[0], HSCX_MASK, 0x0);
191
                writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_MASK, 0x0);
192
        }
193
        if (stat & 2) {
194
                writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_MASK, 0xFF);
195
                writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_MASK, 0x0);
196
        }
197
}
198
 
199
void
200
release_io_s0box(struct IsdnCardState *cs)
201
{
202
        release_region(cs->hw.teles3.cfg_reg, 8);
203
}
204
 
205
static int
206
S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg)
207
{
208
        switch (mt) {
209
                case CARD_RESET:
210
                        break;
211
                case CARD_RELEASE:
212
                        release_io_s0box(cs);
213
                        break;
214
                case CARD_SETIRQ:
215
                        return(request_irq(cs->irq, &s0box_interrupt,
216
                                        I4L_IRQ_FLAG, "HiSax", cs));
217
                case CARD_INIT:
218
                        inithscxisac(cs, 3);
219
                        break;
220
                case CARD_TEST:
221
                        break;
222
        }
223
        return(0);
224
}
225
 
226
__initfunc(int
227
setup_s0box(struct IsdnCard *card))
228
{
229
        struct IsdnCardState *cs = card->cs;
230
        char tmp[64];
231
 
232
        strcpy(tmp, s0box_revision);
233
        printk(KERN_INFO "HiSax: S0Box IO driver Rev. %s\n", HiSax_getrev(tmp));
234
        if (cs->typ != ISDN_CTYPE_S0BOX)
235
                return (0);
236
 
237
        cs->hw.teles3.cfg_reg = card->para[1];
238
        cs->hw.teles3.hscx[0] = -0x20;
239
        cs->hw.teles3.hscx[1] = 0x0;
240
        cs->hw.teles3.isac = 0x20;
241
        cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e;
242
        cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
243
        cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
244
        cs->irq = card->para[0];
245
        if (check_region(cs->hw.teles3.cfg_reg,8)) {
246
                printk(KERN_WARNING
247
                       "HiSax: %s ports %x-%x already in use\n",
248
                       CardType[cs->typ],
249
                       cs->hw.teles3.cfg_reg,
250
                       cs->hw.teles3.cfg_reg + 7);
251
                return 0;
252
        } else
253
                request_region(cs->hw.teles3.cfg_reg, 8, "S0Box parallel I/O");
254
        printk(KERN_INFO
255
               "HiSax: %s config irq:%d isac:0x%x  cfg:0x%x\n",
256
               CardType[cs->typ], cs->irq,
257
               cs->hw.teles3.isac, cs->hw.teles3.cfg_reg);
258
        printk(KERN_INFO
259
               "HiSax: hscx A:0x%x  hscx B:0x%x\n",
260
               cs->hw.teles3.hscx[0], cs->hw.teles3.hscx[1]);
261
        cs->readisac = &ReadISAC;
262
        cs->writeisac = &WriteISAC;
263
        cs->readisacfifo = &ReadISACfifo;
264
        cs->writeisacfifo = &WriteISACfifo;
265
        cs->BC_Read_Reg = &ReadHSCX;
266
        cs->BC_Write_Reg = &WriteHSCX;
267
        cs->BC_Send_Data = &hscx_fill_fifo;
268
        cs->cardmsg = &S0Box_card_msg;
269
        ISACVersion(cs, "S0Box:");
270
        if (HscxVersion(cs, "S0Box:")) {
271
                printk(KERN_WARNING
272
                       "S0Box: wrong HSCX versions check IO address\n");
273
                release_io_s0box(cs);
274
                return (0);
275
        }
276
        return (1);
277
}

powered by: WebSVN 2.1.0

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