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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $Id: sportster.c,v 1.16.2.4 2004/01/13 23:48:39 keil Exp $
2
 *
3
 * low level stuff for USR Sportster internal TA
4
 *
5
 * Author       Karsten Keil
6
 * Copyright    by Karsten Keil      <keil@isdn4linux.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
 * Thanks to Christian "naddy" Weisgerber (3Com, US Robotics) for documentation
12
 *
13
 *
14
 */
15
#include <linux/init.h>
16
#include "hisax.h"
17
#include "isac.h"
18
#include "hscx.h"
19
#include "isdnl1.h"
20
 
21
extern const char *CardType[];
22
static const char *sportster_revision = "$Revision: 1.16.2.4 $";
23
 
24
#define byteout(addr,val) outb(val,addr)
25
#define bytein(addr) inb(addr)
26
 
27
#define  SPORTSTER_ISAC         0xC000
28
#define  SPORTSTER_HSCXA        0x0000
29
#define  SPORTSTER_HSCXB        0x4000
30
#define  SPORTSTER_RES_IRQ      0x8000
31
#define  SPORTSTER_RESET        0x80
32
#define  SPORTSTER_INTE         0x40
33
 
34
static inline int
35
calc_off(unsigned int base, unsigned int off)
36
{
37
        return(base + ((off & 0xfc)<<8) + ((off & 3)<<1));
38
}
39
 
40
static inline void
41
read_fifo(unsigned int adr, u_char * data, int size)
42
{
43
        insb(adr, data, size);
44
}
45
 
46
static void
47
write_fifo(unsigned int adr, u_char * data, int size)
48
{
49
        outsb(adr, data, size);
50
}
51
 
52
/* Interface functions */
53
 
54
static u_char
55
ReadISAC(struct IsdnCardState *cs, u_char offset)
56
{
57
        return (bytein(calc_off(cs->hw.spt.isac, offset)));
58
}
59
 
60
static void
61
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
62
{
63
        byteout(calc_off(cs->hw.spt.isac, offset), value);
64
}
65
 
66
static void
67
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
68
{
69
        read_fifo(cs->hw.spt.isac, data, size);
70
}
71
 
72
static void
73
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
74
{
75
        write_fifo(cs->hw.spt.isac, data, size);
76
}
77
 
78
static u_char
79
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
80
{
81
        return (bytein(calc_off(cs->hw.spt.hscx[hscx], offset)));
82
}
83
 
84
static void
85
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
86
{
87
        byteout(calc_off(cs->hw.spt.hscx[hscx], offset), value);
88
}
89
 
90
/*
91
 * fast interrupt HSCX stuff goes here
92
 */
93
 
94
#define READHSCX(cs, nr, reg) bytein(calc_off(cs->hw.spt.hscx[nr], reg))
95
#define WRITEHSCX(cs, nr, reg, data) byteout(calc_off(cs->hw.spt.hscx[nr], reg), data)
96
#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo(cs->hw.spt.hscx[nr], ptr, cnt)
97
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo(cs->hw.spt.hscx[nr], ptr, cnt)
98
 
99
#include "hscx_irq.c"
100
 
101
static irqreturn_t
102
sportster_interrupt(int intno, void *dev_id)
103
{
104
        struct IsdnCardState *cs = dev_id;
105
        u_char val;
106
        u_long flags;
107
 
108
        spin_lock_irqsave(&cs->lock, flags);
109
        val = READHSCX(cs, 1, HSCX_ISTA);
110
      Start_HSCX:
111
        if (val)
112
                hscx_int_main(cs, val);
113
        val = ReadISAC(cs, ISAC_ISTA);
114
      Start_ISAC:
115
        if (val)
116
                isac_interrupt(cs, val);
117
        val = READHSCX(cs, 1, HSCX_ISTA);
118
        if (val) {
119
                if (cs->debug & L1_DEB_HSCX)
120
                        debugl1(cs, "HSCX IntStat after IntRoutine");
121
                goto Start_HSCX;
122
        }
123
        val = ReadISAC(cs, ISAC_ISTA);
124
        if (val) {
125
                if (cs->debug & L1_DEB_ISAC)
126
                        debugl1(cs, "ISAC IntStat after IntRoutine");
127
                goto Start_ISAC;
128
        }
129
        /* get a new irq impulse if there any pending */
130
        bytein(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ +1);
131
        spin_unlock_irqrestore(&cs->lock, flags);
132
        return IRQ_HANDLED;
133
}
134
 
135
static void
136
release_io_sportster(struct IsdnCardState *cs)
137
{
138
        int i, adr;
139
 
140
        byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, 0);
141
        for (i=0; i<64; i++) {
142
                adr = cs->hw.spt.cfg_reg + i *1024;
143
                release_region(adr, 8);
144
        }
145
}
146
 
147
static void
148
reset_sportster(struct IsdnCardState *cs)
149
{
150
        cs->hw.spt.res_irq |= SPORTSTER_RESET; /* Reset On */
151
        byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);
152
        mdelay(10);
153
        cs->hw.spt.res_irq &= ~SPORTSTER_RESET; /* Reset Off */
154
        byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);
155
        mdelay(10);
156
}
157
 
158
static int
159
Sportster_card_msg(struct IsdnCardState *cs, int mt, void *arg)
160
{
161
        u_long flags;
162
 
163
        switch (mt) {
164
                case CARD_RESET:
165
                        spin_lock_irqsave(&cs->lock, flags);
166
                        reset_sportster(cs);
167
                        spin_unlock_irqrestore(&cs->lock, flags);
168
                        return(0);
169
                case CARD_RELEASE:
170
                        release_io_sportster(cs);
171
                        return(0);
172
                case CARD_INIT:
173
                        spin_lock_irqsave(&cs->lock, flags);
174
                        reset_sportster(cs);
175
                        inithscxisac(cs, 1);
176
                        cs->hw.spt.res_irq |= SPORTSTER_INTE; /* IRQ On */
177
                        byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);
178
                        inithscxisac(cs, 2);
179
                        spin_unlock_irqrestore(&cs->lock, flags);
180
                        return(0);
181
                case CARD_TEST:
182
                        return(0);
183
        }
184
        return(0);
185
}
186
 
187
static int __devinit
188
get_io_range(struct IsdnCardState *cs)
189
{
190
        int i, j, adr;
191
 
192
        for (i=0;i<64;i++) {
193
                adr = cs->hw.spt.cfg_reg + i *1024;
194
                if (!request_region(adr, 8, "sportster")) {
195
                        printk(KERN_WARNING
196
                                "HiSax: %s config port %x-%x already in use\n",
197
                                CardType[cs->typ], adr, adr + 8);
198
                        break;
199
                }
200
        }
201
        if (i==64)
202
                return(1);
203
        else {
204
                for (j=0; j<i; j++) {
205
                        adr = cs->hw.spt.cfg_reg + j *1024;
206
                        release_region(adr, 8);
207
                }
208
                return(0);
209
        }
210
}
211
 
212
int __devinit
213
setup_sportster(struct IsdnCard *card)
214
{
215
        struct IsdnCardState *cs = card->cs;
216
        char tmp[64];
217
 
218
        strcpy(tmp, sportster_revision);
219
        printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n", HiSax_getrev(tmp));
220
        if (cs->typ != ISDN_CTYPE_SPORTSTER)
221
                return (0);
222
 
223
        cs->hw.spt.cfg_reg = card->para[1];
224
        cs->irq = card->para[0];
225
        if (!get_io_range(cs))
226
                return (0);
227
        cs->hw.spt.isac = cs->hw.spt.cfg_reg + SPORTSTER_ISAC;
228
        cs->hw.spt.hscx[0] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXA;
229
        cs->hw.spt.hscx[1] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXB;
230
 
231
        switch(cs->irq) {
232
                case 5: cs->hw.spt.res_irq = 1;
233
                        break;
234
                case 7: cs->hw.spt.res_irq = 2;
235
                        break;
236
                case 10:cs->hw.spt.res_irq = 3;
237
                        break;
238
                case 11:cs->hw.spt.res_irq = 4;
239
                        break;
240
                case 12:cs->hw.spt.res_irq = 5;
241
                        break;
242
                case 14:cs->hw.spt.res_irq = 6;
243
                        break;
244
                case 15:cs->hw.spt.res_irq = 7;
245
                        break;
246
                default:release_io_sportster(cs);
247
                        printk(KERN_WARNING "Sportster: wrong IRQ\n");
248
                        return(0);
249
        }
250
        printk(KERN_INFO "HiSax: %s config irq:%d cfg:0x%X\n",
251
                CardType[cs->typ], cs->irq, cs->hw.spt.cfg_reg);
252
        setup_isac(cs);
253
        cs->readisac = &ReadISAC;
254
        cs->writeisac = &WriteISAC;
255
        cs->readisacfifo = &ReadISACfifo;
256
        cs->writeisacfifo = &WriteISACfifo;
257
        cs->BC_Read_Reg = &ReadHSCX;
258
        cs->BC_Write_Reg = &WriteHSCX;
259
        cs->BC_Send_Data = &hscx_fill_fifo;
260
        cs->cardmsg = &Sportster_card_msg;
261
        cs->irq_func = &sportster_interrupt;
262
        ISACVersion(cs, "Sportster:");
263
        if (HscxVersion(cs, "Sportster:")) {
264
                printk(KERN_WARNING
265
                       "Sportster: wrong HSCX versions check IO address\n");
266
                release_io_sportster(cs);
267
                return (0);
268
        }
269
        return (1);
270
}

powered by: WebSVN 2.1.0

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