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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $Id: ix1_micro.c,v 2.12.2.4 2004/01/13 23:48:39 keil Exp $
2
 *
3
 * low level stuff for ITK ix1-micro Rev.2 isdn cards
4
 * derived from the original file teles3.c from Karsten Keil
5
 *
6
 * Author       Klaus-Peter Nischke
7
 * Copyright    by Klaus-Peter Nischke, ITK AG
8
 *                                   <klaus@nischke.do.eunet.de>
9
 *              by Karsten Keil      <keil@isdn4linux.de>
10
 *
11
 * This software may be used and distributed according to the terms
12
 * of the GNU General Public License, incorporated herein by reference.
13
 *
14
 * Klaus-Peter Nischke
15
 * Deusener Str. 287
16
 * 44369 Dortmund
17
 * Germany
18
 */
19
 
20
#include <linux/init.h>
21
#include <linux/isapnp.h>
22
#include "hisax.h"
23
#include "isac.h"
24
#include "hscx.h"
25
#include "isdnl1.h"
26
 
27
extern const char *CardType[];
28
static const char *ix1_revision = "$Revision: 2.12.2.4 $";
29
 
30
#define byteout(addr,val) outb(val,addr)
31
#define bytein(addr) inb(addr)
32
 
33
#define SPECIAL_PORT_OFFSET 3
34
 
35
#define ISAC_COMMAND_OFFSET 2
36
#define ISAC_DATA_OFFSET 0
37
#define HSCX_COMMAND_OFFSET 2
38
#define HSCX_DATA_OFFSET 1
39
 
40
#define TIMEOUT 50
41
 
42
static inline u_char
43
readreg(unsigned int ale, unsigned int adr, u_char off)
44
{
45
        register u_char ret;
46
 
47
        byteout(ale, off);
48
        ret = bytein(adr);
49
        return (ret);
50
}
51
 
52
static inline void
53
readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
54
{
55
        byteout(ale, off);
56
        insb(adr, data, size);
57
}
58
 
59
 
60
static inline void
61
writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
62
{
63
        byteout(ale, off);
64
        byteout(adr, data);
65
}
66
 
67
static inline void
68
writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
69
{
70
        byteout(ale, off);
71
        outsb(adr, data, size);
72
}
73
 
74
/* Interface functions */
75
 
76
static u_char
77
ReadISAC(struct IsdnCardState *cs, u_char offset)
78
{
79
        return (readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, offset));
80
}
81
 
82
static void
83
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
84
{
85
        writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, offset, value);
86
}
87
 
88
static void
89
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
90
{
91
        readfifo(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, 0, data, size);
92
}
93
 
94
static void
95
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
96
{
97
        writefifo(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, 0, data, size);
98
}
99
 
100
static u_char
101
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
102
{
103
        return (readreg(cs->hw.ix1.hscx_ale,
104
                        cs->hw.ix1.hscx, offset + (hscx ? 0x40 : 0)));
105
}
106
 
107
static void
108
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
109
{
110
        writereg(cs->hw.ix1.hscx_ale,
111
                 cs->hw.ix1.hscx, offset + (hscx ? 0x40 : 0), value);
112
}
113
 
114
#define READHSCX(cs, nr, reg) readreg(cs->hw.ix1.hscx_ale, \
115
                cs->hw.ix1.hscx, reg + (nr ? 0x40 : 0))
116
#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.ix1.hscx_ale, \
117
                cs->hw.ix1.hscx, reg + (nr ? 0x40 : 0), data)
118
 
119
#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ix1.hscx_ale, \
120
                cs->hw.ix1.hscx, (nr ? 0x40 : 0), ptr, cnt)
121
 
122
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ix1.hscx_ale, \
123
                cs->hw.ix1.hscx, (nr ? 0x40 : 0), ptr, cnt)
124
 
125
#include "hscx_irq.c"
126
 
127
static irqreturn_t
128
ix1micro_interrupt(int intno, void *dev_id)
129
{
130
        struct IsdnCardState *cs = dev_id;
131
        u_char val;
132
        u_long flags;
133
 
134
        spin_lock_irqsave(&cs->lock, flags);
135
        val = readreg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_ISTA + 0x40);
136
      Start_HSCX:
137
        if (val)
138
                hscx_int_main(cs, val);
139
        val = readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_ISTA);
140
      Start_ISAC:
141
        if (val)
142
                isac_interrupt(cs, val);
143
        val = readreg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_ISTA + 0x40);
144
        if (val) {
145
                if (cs->debug & L1_DEB_HSCX)
146
                        debugl1(cs, "HSCX IntStat after IntRoutine");
147
                goto Start_HSCX;
148
        }
149
        val = readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_ISTA);
150
        if (val) {
151
                if (cs->debug & L1_DEB_ISAC)
152
                        debugl1(cs, "ISAC IntStat after IntRoutine");
153
                goto Start_ISAC;
154
        }
155
        writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK, 0xFF);
156
        writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK + 0x40, 0xFF);
157
        writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_MASK, 0xFF);
158
        writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_MASK, 0);
159
        writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK, 0);
160
        writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK + 0x40, 0);
161
        spin_unlock_irqrestore(&cs->lock, flags);
162
        return IRQ_HANDLED;
163
}
164
 
165
static void
166
release_io_ix1micro(struct IsdnCardState *cs)
167
{
168
        if (cs->hw.ix1.cfg_reg)
169
                release_region(cs->hw.ix1.cfg_reg, 4);
170
}
171
 
172
static void
173
ix1_reset(struct IsdnCardState *cs)
174
{
175
        int cnt;
176
 
177
        /* reset isac */
178
        cnt = 3 * (HZ / 10) + 1;
179
        while (cnt--) {
180
                byteout(cs->hw.ix1.cfg_reg + SPECIAL_PORT_OFFSET, 1);
181
                HZDELAY(1);     /* wait >=10 ms */
182
        }
183
        byteout(cs->hw.ix1.cfg_reg + SPECIAL_PORT_OFFSET, 0);
184
}
185
 
186
static int
187
ix1_card_msg(struct IsdnCardState *cs, int mt, void *arg)
188
{
189
        u_long flags;
190
 
191
        switch (mt) {
192
                case CARD_RESET:
193
                        spin_lock_irqsave(&cs->lock, flags);
194
                        ix1_reset(cs);
195
                        spin_unlock_irqrestore(&cs->lock, flags);
196
                        return(0);
197
                case CARD_RELEASE:
198
                        release_io_ix1micro(cs);
199
                        return(0);
200
                case CARD_INIT:
201
                        spin_lock_irqsave(&cs->lock, flags);
202
                        ix1_reset(cs);
203
                        inithscxisac(cs, 3);
204
                        spin_unlock_irqrestore(&cs->lock, flags);
205
                        return(0);
206
                case CARD_TEST:
207
                        return(0);
208
        }
209
        return(0);
210
}
211
 
212
#ifdef __ISAPNP__
213
static struct isapnp_device_id itk_ids[] __devinitdata = {
214
        { ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
215
          ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
216
          (unsigned long) "ITK micro 2" },
217
        { ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29),
218
          ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29),
219
          (unsigned long) "ITK micro 2." },
220
        { 0, }
221
};
222
 
223
static struct isapnp_device_id *ipid __devinitdata = &itk_ids[0];
224
static struct pnp_card *pnp_c __devinitdata = NULL;
225
#endif
226
 
227
 
228
int __devinit
229
setup_ix1micro(struct IsdnCard *card)
230
{
231
        struct IsdnCardState *cs = card->cs;
232
        char tmp[64];
233
 
234
        strcpy(tmp, ix1_revision);
235
        printk(KERN_INFO "HiSax: ITK IX1 driver Rev. %s\n", HiSax_getrev(tmp));
236
        if (cs->typ != ISDN_CTYPE_IX1MICROR2)
237
                return (0);
238
 
239
#ifdef __ISAPNP__
240
        if (!card->para[1] && isapnp_present()) {
241
                struct pnp_dev *pnp_d;
242
                while(ipid->card_vendor) {
243
                        if ((pnp_c = pnp_find_card(ipid->card_vendor,
244
                                ipid->card_device, pnp_c))) {
245
                                pnp_d = NULL;
246
                                if ((pnp_d = pnp_find_dev(pnp_c,
247
                                        ipid->vendor, ipid->function, pnp_d))) {
248
                                        int err;
249
 
250
                                        printk(KERN_INFO "HiSax: %s detected\n",
251
                                                (char *)ipid->driver_data);
252
                                        pnp_disable_dev(pnp_d);
253
                                        err = pnp_activate_dev(pnp_d);
254
                                        if (err<0) {
255
                                                printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
256
                                                        __FUNCTION__, err);
257
                                                return(0);
258
                                        }
259
                                        card->para[1] = pnp_port_start(pnp_d, 0);
260
                                        card->para[0] = pnp_irq(pnp_d, 0);
261
                                        if (!card->para[0] || !card->para[1]) {
262
                                                printk(KERN_ERR "ITK PnP:some resources are missing %ld/%lx\n",
263
                                                        card->para[0], card->para[1]);
264
                                                pnp_disable_dev(pnp_d);
265
                                                return(0);
266
                                        }
267
                                        break;
268
                                } else {
269
                                        printk(KERN_ERR "ITK PnP: PnP error card found, no device\n");
270
                                }
271
                        }
272
                        ipid++;
273
                        pnp_c = NULL;
274
                }
275
                if (!ipid->card_vendor) {
276
                        printk(KERN_INFO "ITK PnP: no ISAPnP card found\n");
277
                        return(0);
278
                }
279
        }
280
#endif
281
        /* IO-Ports */
282
        cs->hw.ix1.isac_ale = card->para[1] + ISAC_COMMAND_OFFSET;
283
        cs->hw.ix1.hscx_ale = card->para[1] + HSCX_COMMAND_OFFSET;
284
        cs->hw.ix1.isac = card->para[1] + ISAC_DATA_OFFSET;
285
        cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET;
286
        cs->hw.ix1.cfg_reg = card->para[1];
287
        cs->irq = card->para[0];
288
        if (cs->hw.ix1.cfg_reg) {
289
                if (!request_region(cs->hw.ix1.cfg_reg, 4, "ix1micro cfg")) {
290
                        printk(KERN_WARNING
291
                          "HiSax: %s config port %x-%x already in use\n",
292
                               CardType[card->typ],
293
                               cs->hw.ix1.cfg_reg,
294
                               cs->hw.ix1.cfg_reg + 4);
295
                        return (0);
296
                }
297
        }
298
        printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n",
299
                CardType[cs->typ], cs->irq, cs->hw.ix1.cfg_reg);
300
        setup_isac(cs);
301
        cs->readisac = &ReadISAC;
302
        cs->writeisac = &WriteISAC;
303
        cs->readisacfifo = &ReadISACfifo;
304
        cs->writeisacfifo = &WriteISACfifo;
305
        cs->BC_Read_Reg = &ReadHSCX;
306
        cs->BC_Write_Reg = &WriteHSCX;
307
        cs->BC_Send_Data = &hscx_fill_fifo;
308
        cs->cardmsg = &ix1_card_msg;
309
        cs->irq_func = &ix1micro_interrupt;
310
        ISACVersion(cs, "ix1-Micro:");
311
        if (HscxVersion(cs, "ix1-Micro:")) {
312
                printk(KERN_WARNING
313
                    "ix1-Micro: wrong HSCX versions check IO address\n");
314
                release_io_ix1micro(cs);
315
                return (0);
316
        }
317
        return (1);
318
}

powered by: WebSVN 2.1.0

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