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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $Id: isurf.c,v 1.12.2.4 2004/01/13 21:46:03 keil Exp $
2
 *
3
 * low level stuff for Siemens I-Surf/I-Talk cards
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
 */
12
 
13
#include <linux/init.h>
14
#include "hisax.h"
15
#include "isac.h"
16
#include "isar.h"
17
#include "isdnl1.h"
18
#include <linux/isapnp.h>
19
 
20
extern const char *CardType[];
21
 
22
static const char *ISurf_revision = "$Revision: 1.12.2.4 $";
23
 
24
#define byteout(addr,val) outb(val,addr)
25
#define bytein(addr) inb(addr)
26
 
27
#define ISURF_ISAR_RESET        1
28
#define ISURF_ISAC_RESET        2
29
#define ISURF_ISAR_EA           4
30
#define ISURF_ARCOFI_RESET      8
31
#define ISURF_RESET (ISURF_ISAR_RESET | ISURF_ISAC_RESET | ISURF_ARCOFI_RESET)
32
 
33
#define ISURF_ISAR_OFFSET       0
34
#define ISURF_ISAC_OFFSET       0x100
35
#define ISURF_IOMEM_SIZE        0x400
36
/* Interface functions */
37
 
38
static u_char
39
ReadISAC(struct IsdnCardState *cs, u_char offset)
40
{
41
        return (readb(cs->hw.isurf.isac + offset));
42
}
43
 
44
static void
45
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
46
{
47
        writeb(value, cs->hw.isurf.isac + offset); mb();
48
}
49
 
50
static void
51
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
52
{
53
        register int i;
54
        for (i = 0; i < size; i++)
55
                data[i] = readb(cs->hw.isurf.isac);
56
}
57
 
58
static void
59
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
60
{
61
        register int i;
62
        for (i = 0; i < size; i++){
63
                writeb(data[i], cs->hw.isurf.isac);mb();
64
        }
65
}
66
 
67
/* ISAR access routines
68
 * mode = 0 access with IRQ on
69
 * mode = 1 access with IRQ off
70
 * mode = 2 access with IRQ off and using last offset
71
 */
72
 
73
static u_char
74
ReadISAR(struct IsdnCardState *cs, int mode, u_char offset)
75
{
76
        return(readb(cs->hw.isurf.isar + offset));
77
}
78
 
79
static void
80
WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value)
81
{
82
        writeb(value, cs->hw.isurf.isar + offset);mb();
83
}
84
 
85
static irqreturn_t
86
isurf_interrupt(int intno, void *dev_id)
87
{
88
        struct IsdnCardState *cs = dev_id;
89
        u_char val;
90
        int cnt = 5;
91
        u_long flags;
92
 
93
        spin_lock_irqsave(&cs->lock, flags);
94
        val = readb(cs->hw.isurf.isar + ISAR_IRQBIT);
95
      Start_ISAR:
96
        if (val & ISAR_IRQSTA)
97
                isar_int_main(cs);
98
        val = readb(cs->hw.isurf.isac + ISAC_ISTA);
99
      Start_ISAC:
100
        if (val)
101
                isac_interrupt(cs, val);
102
        val = readb(cs->hw.isurf.isar + ISAR_IRQBIT);
103
        if ((val & ISAR_IRQSTA) && --cnt) {
104
                if (cs->debug & L1_DEB_HSCX)
105
                        debugl1(cs, "ISAR IntStat after IntRoutine");
106
                goto Start_ISAR;
107
        }
108
        val = readb(cs->hw.isurf.isac + ISAC_ISTA);
109
        if (val && --cnt) {
110
                if (cs->debug & L1_DEB_ISAC)
111
                        debugl1(cs, "ISAC IntStat after IntRoutine");
112
                goto Start_ISAC;
113
        }
114
        if (!cnt)
115
                printk(KERN_WARNING "ISurf IRQ LOOP\n");
116
 
117
        writeb(0, cs->hw.isurf.isar + ISAR_IRQBIT); mb();
118
        writeb(0xFF, cs->hw.isurf.isac + ISAC_MASK);mb();
119
        writeb(0, cs->hw.isurf.isac + ISAC_MASK);mb();
120
        writeb(ISAR_IRQMSK, cs->hw.isurf.isar + ISAR_IRQBIT); mb();
121
        spin_unlock_irqrestore(&cs->lock, flags);
122
        return IRQ_HANDLED;
123
}
124
 
125
static void
126
release_io_isurf(struct IsdnCardState *cs)
127
{
128
        release_region(cs->hw.isurf.reset, 1);
129
        iounmap(cs->hw.isurf.isar);
130
        release_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE);
131
}
132
 
133
static void
134
reset_isurf(struct IsdnCardState *cs, u_char chips)
135
{
136
        printk(KERN_INFO "ISurf: resetting card\n");
137
 
138
        byteout(cs->hw.isurf.reset, chips); /* Reset On */
139
        mdelay(10);
140
        byteout(cs->hw.isurf.reset, ISURF_ISAR_EA); /* Reset Off */
141
        mdelay(10);
142
}
143
 
144
static int
145
ISurf_card_msg(struct IsdnCardState *cs, int mt, void *arg)
146
{
147
        u_long flags;
148
 
149
        switch (mt) {
150
                case CARD_RESET:
151
                        spin_lock_irqsave(&cs->lock, flags);
152
                        reset_isurf(cs, ISURF_RESET);
153
                        spin_unlock_irqrestore(&cs->lock, flags);
154
                        return(0);
155
                case CARD_RELEASE:
156
                        release_io_isurf(cs);
157
                        return(0);
158
                case CARD_INIT:
159
                        spin_lock_irqsave(&cs->lock, flags);
160
                        reset_isurf(cs, ISURF_RESET);
161
                        clear_pending_isac_ints(cs);
162
                        writeb(0, cs->hw.isurf.isar+ISAR_IRQBIT);mb();
163
                        initisac(cs);
164
                        initisar(cs);
165
                        /* Reenable ISAC IRQ */
166
                        cs->writeisac(cs, ISAC_MASK, 0);
167
                        /* RESET Receiver and Transmitter */
168
                        cs->writeisac(cs, ISAC_CMDR, 0x41);
169
                        spin_unlock_irqrestore(&cs->lock, flags);
170
                        return(0);
171
                case CARD_TEST:
172
                        return(0);
173
        }
174
        return(0);
175
}
176
 
177
static int
178
isurf_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) {
179
        int ret;
180
        u_long flags;
181
 
182
        if ((ic->command == ISDN_CMD_IOCTL) && (ic->arg == 9)) {
183
                ret = isar_auxcmd(cs, ic);
184
                spin_lock_irqsave(&cs->lock, flags);
185
                if (!ret) {
186
                        reset_isurf(cs, ISURF_ISAR_EA | ISURF_ISAC_RESET |
187
                                ISURF_ARCOFI_RESET);
188
                        initisac(cs);
189
                        cs->writeisac(cs, ISAC_MASK, 0);
190
                        cs->writeisac(cs, ISAC_CMDR, 0x41);
191
                }
192
                spin_unlock_irqrestore(&cs->lock, flags);
193
                return(ret);
194
        }
195
        return(isar_auxcmd(cs, ic));
196
}
197
 
198
#ifdef __ISAPNP__
199
static struct pnp_card *pnp_c __devinitdata = NULL;
200
#endif
201
 
202
int __devinit
203
setup_isurf(struct IsdnCard *card)
204
{
205
        int ver;
206
        struct IsdnCardState *cs = card->cs;
207
        char tmp[64];
208
 
209
        strcpy(tmp, ISurf_revision);
210
        printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp));
211
 
212
        if (cs->typ != ISDN_CTYPE_ISURF)
213
                return(0);
214
        if (card->para[1] && card->para[2]) {
215
                cs->hw.isurf.reset = card->para[1];
216
                cs->hw.isurf.phymem = card->para[2];
217
                cs->irq = card->para[0];
218
        } else {
219
#ifdef __ISAPNP__
220
                if (isapnp_present()) {
221
                        struct pnp_dev *pnp_d = NULL;
222
                        int err;
223
 
224
                        cs->subtyp = 0;
225
                        if ((pnp_c = pnp_find_card(
226
                                ISAPNP_VENDOR('S', 'I', 'E'),
227
                                ISAPNP_FUNCTION(0x0010), pnp_c))) {
228
                                if (!(pnp_d = pnp_find_dev(pnp_c,
229
                                        ISAPNP_VENDOR('S', 'I', 'E'),
230
                                        ISAPNP_FUNCTION(0x0010), pnp_d))) {
231
                                        printk(KERN_ERR "ISurfPnP: PnP error card found, no device\n");
232
                                        return (0);
233
                                }
234
                                pnp_disable_dev(pnp_d);
235
                                err = pnp_activate_dev(pnp_d);
236
                                cs->hw.isurf.reset = pnp_port_start(pnp_d, 0);
237
                                cs->hw.isurf.phymem = pnp_mem_start(pnp_d, 1);
238
                                cs->irq = pnp_irq(pnp_d, 0);
239
                                if (!cs->irq || !cs->hw.isurf.reset || !cs->hw.isurf.phymem) {
240
                                        printk(KERN_ERR "ISurfPnP:some resources are missing %d/%x/%lx\n",
241
                                                cs->irq, cs->hw.isurf.reset, cs->hw.isurf.phymem);
242
                                        pnp_disable_dev(pnp_d);
243
                                        return(0);
244
                                }
245
                        } else {
246
                                printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n");
247
                                return(0);
248
                        }
249
                } else {
250
                        printk(KERN_INFO "ISurfPnP: no ISAPnP bus found\n");
251
                        return(0);
252
                }
253
#else
254
                printk(KERN_WARNING "HiSax: %s port/mem not set\n",
255
                        CardType[card->typ]);
256
                return (0);
257
#endif
258
        }
259
        if (!request_region(cs->hw.isurf.reset, 1, "isurf isdn")) {
260
                printk(KERN_WARNING
261
                        "HiSax: %s config port %x already in use\n",
262
                        CardType[card->typ],
263
                        cs->hw.isurf.reset);
264
                        return (0);
265
        }
266
        if (!request_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE, "isurf iomem")) {
267
                printk(KERN_WARNING
268
                        "HiSax: %s memory region %lx-%lx already in use\n",
269
                        CardType[card->typ],
270
                        cs->hw.isurf.phymem,
271
                        cs->hw.isurf.phymem + ISURF_IOMEM_SIZE);
272
                release_region(cs->hw.isurf.reset, 1);
273
                return (0);
274
        }
275
        cs->hw.isurf.isar = ioremap(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE);
276
        cs->hw.isurf.isac = cs->hw.isurf.isar + ISURF_ISAC_OFFSET;
277
        printk(KERN_INFO
278
               "ISurf: defined at 0x%x 0x%lx IRQ %d\n",
279
               cs->hw.isurf.reset,
280
               cs->hw.isurf.phymem,
281
               cs->irq);
282
 
283
        setup_isac(cs);
284
        cs->cardmsg = &ISurf_card_msg;
285
        cs->irq_func = &isurf_interrupt;
286
        cs->auxcmd = &isurf_auxcmd;
287
        cs->readisac = &ReadISAC;
288
        cs->writeisac = &WriteISAC;
289
        cs->readisacfifo = &ReadISACfifo;
290
        cs->writeisacfifo = &WriteISACfifo;
291
        cs->bcs[0].hw.isar.reg = &cs->hw.isurf.isar_r;
292
        cs->bcs[1].hw.isar.reg = &cs->hw.isurf.isar_r;
293
        test_and_set_bit(HW_ISAR, &cs->HW_Flags);
294
        ISACVersion(cs, "ISurf:");
295
        cs->BC_Read_Reg = &ReadISAR;
296
        cs->BC_Write_Reg = &WriteISAR;
297
        cs->BC_Send_Data = &isar_fill_fifo;
298
        ver = ISARVersion(cs, "ISurf:");
299
        if (ver < 0) {
300
                printk(KERN_WARNING
301
                        "ISurf: wrong ISAR version (ret = %d)\n", ver);
302
                release_io_isurf(cs);
303
                return (0);
304
        }
305
        return (1);
306
}

powered by: WebSVN 2.1.0

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