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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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