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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [isdn/] [hisax/] [niccy.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/* $Id: niccy.c,v 1.1.1.1 2001-09-10 07:44:18 simons Exp $
2
 
3
 * niccy.c  low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and
4
 *          compatible (SAGEM cybermodem)
5
 *
6
 * Author   Karsten Keil
7
 *
8
 * Thanks to Dr. Neuhaus and SAGEM for informations
9
 *
10
 * $Log: not supported by cvs2svn $
11
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
12
 * Initial revision
13
 *
14
 * Revision 1.1.2.4  1998/04/16 19:18:19  keil
15
 * need config.h
16
 *
17
 * Revision 1.1.2.3  1998/04/08 22:05:26  keil
18
 * Forgot PCI fix
19
 *
20
 * Revision 1.1.2.2  1998/04/08 21:48:23  keil
21
 * New init; working Niccy PCI
22
 *
23
 * Revision 1.1.2.1  1998/02/11 14:23:20  keil
24
 * support for Dr Neuhaus Niccy PnP and PCI
25
 *
26
 *
27
 */
28
 
29
 
30
#define __NO_VERSION__
31
#include <linux/config.h>
32
#include "hisax.h"
33
#include "isac.h"
34
#include "hscx.h"
35
#include "isdnl1.h"
36
#include <linux/pci.h>
37
#include <linux/bios32.h>
38
 
39
extern const char *CardType[];
40
const char *niccy_revision = "$Revision: 1.1.1.1 $";
41
 
42
#define byteout(addr,val) outb(val,addr)
43
#define bytein(addr) inb(addr)
44
 
45
#define ISAC_PCI_DATA   0
46
#define HSCX_PCI_DATA   1
47
#define ISAC_PCI_ADDR   2
48
#define HSCX_PCI_ADDR   3
49
#define ISAC_PNP        0
50
#define HSCX_PNP        1
51
 
52
/* SUB Types */
53
#define NICCY_PNP       1
54
#define NICCY_PCI       2
55
 
56
/* PCI stuff */
57
#define PCI_VENDOR_DR_NEUHAUS   0x1267
58
#define PCI_NICCY_ID            0x1016
59
#define PCI_IRQ_CTRL_REG        0x38
60
#define PCI_IRQ_ENABLE          0x1f00
61
#define PCI_IRQ_DISABLE         0xff0000
62
#define PCI_IRQ_ASSERT          0x800000
63
 
64
static inline u_char
65
readreg(unsigned int ale, unsigned int adr, u_char off)
66
{
67
        register u_char ret;
68
        long flags;
69
 
70
        save_flags(flags);
71
        cli();
72
        byteout(ale, off);
73
        ret = bytein(adr);
74
        restore_flags(flags);
75
        return (ret);
76
}
77
 
78
static inline void
79
readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
80
{
81
        /* fifo read without cli because it's allready done  */
82
 
83
        byteout(ale, off);
84
        insb(adr, data, size);
85
}
86
 
87
 
88
static inline void
89
writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
90
{
91
        long flags;
92
 
93
        save_flags(flags);
94
        cli();
95
        byteout(ale, off);
96
        byteout(adr, data);
97
        restore_flags(flags);
98
}
99
 
100
static inline void
101
writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
102
{
103
        /* fifo write without cli because it's allready done  */
104
        byteout(ale, off);
105
        outsb(adr, data, size);
106
}
107
 
108
/* Interface functions */
109
 
110
static u_char
111
ReadISAC(struct IsdnCardState *cs, u_char offset)
112
{
113
        return (readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset));
114
}
115
 
116
static void
117
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
118
{
119
        writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset, value);
120
}
121
 
122
static void
123
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
124
{
125
        readfifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size);
126
}
127
 
128
static void
129
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
130
{
131
        writefifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size);
132
}
133
 
134
static u_char
135
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
136
{
137
        return (readreg(cs->hw.niccy.hscx_ale,
138
                        cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0)));
139
}
140
 
141
static void
142
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
143
{
144
        writereg(cs->hw.niccy.hscx_ale,
145
                 cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0), value);
146
}
147
 
148
#define READHSCX(cs, nr, reg) readreg(cs->hw.niccy.hscx_ale, \
149
                cs->hw.niccy.hscx, reg + (nr ? 0x40 : 0))
150
#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.niccy.hscx_ale, \
151
                cs->hw.niccy.hscx, reg + (nr ? 0x40 : 0), data)
152
 
153
#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.niccy.hscx_ale, \
154
                cs->hw.niccy.hscx, (nr ? 0x40 : 0), ptr, cnt)
155
 
156
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.niccy.hscx_ale, \
157
                cs->hw.niccy.hscx, (nr ? 0x40 : 0), ptr, cnt)
158
 
159
#include "hscx_irq.c"
160
 
161
static void
162
niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs)
163
{
164
        struct IsdnCardState *cs = dev_id;
165
        u_char val, stat = 0;
166
 
167
        if (!cs) {
168
                printk(KERN_WARNING "Niccy: Spurious interrupt!\n");
169
                return;
170
        }
171
        if (cs->subtyp == NICCY_PCI) {
172
                int ival;
173
                ival = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
174
                if (!(ival & PCI_IRQ_ASSERT)) /* IRQ not for us (shared) */
175
                        return;
176
                outl(ival, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
177
        }
178
        val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_ISTA + 0x40);
179
      Start_HSCX:
180
        if (val) {
181
                hscx_int_main(cs, val);
182
                stat |= 1;
183
        }
184
        val = readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_ISTA);
185
      Start_ISAC:
186
        if (val) {
187
                isac_interrupt(cs, val);
188
                stat |= 2;
189
        }
190
        val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_ISTA + 0x40);
191
        if (val) {
192
                if (cs->debug & L1_DEB_HSCX)
193
                        debugl1(cs, "HSCX IntStat after IntRoutine");
194
                goto Start_HSCX;
195
        }
196
        val = readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_ISTA);
197
        if (val) {
198
                if (cs->debug & L1_DEB_ISAC)
199
                        debugl1(cs, "ISAC IntStat after IntRoutine");
200
                goto Start_ISAC;
201
        }
202
        if (stat & 1) {
203
                writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0xFF);
204
                writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0xFF);
205
                writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0);
206
                writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0);
207
        }
208
        if (stat & 2) {
209
                writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0xFF);
210
                writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0);
211
        }
212
}
213
 
214
void
215
release_io_niccy(struct IsdnCardState *cs)
216
{
217
        if (cs->subtyp == NICCY_PCI) {
218
                int val;
219
 
220
                val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
221
                val &= PCI_IRQ_DISABLE;
222
                outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
223
                release_region(cs->hw.niccy.cfg_reg, 0x80);
224
                release_region(cs->hw.niccy.isac, 4);
225
        } else {
226
                release_region(cs->hw.niccy.isac, 2);
227
                release_region(cs->hw.niccy.isac_ale, 2);
228
        }
229
}
230
 
231
static void
232
niccy_reset(struct IsdnCardState *cs)
233
{
234
        int val, nval;
235
 
236
        val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
237
        nval = val | PCI_IRQ_ENABLE;
238
        outl(nval, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
239
 
240
        inithscxisac(cs, 3);
241
}
242
 
243
static int
244
niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg)
245
{
246
        int imode;
247
 
248
        switch (mt) {
249
                case CARD_RESET:
250
                        niccy_reset(cs);
251
                        return(0);
252
                case CARD_RELEASE:
253
                        release_io_niccy(cs);
254
                        return(0);
255
                case CARD_SETIRQ:
256
                        if (cs->subtyp == NICCY_PCI)
257
                                imode = I4L_IRQ_FLAG | SA_SHIRQ;
258
                        else
259
                                imode = I4L_IRQ_FLAG;
260
                        return(request_irq(cs->irq, &niccy_interrupt,
261
                                imode, "HiSax", cs));
262
                        break;
263
                case CARD_INIT:
264
                        niccy_reset(cs);
265
                        return(0);
266
                case CARD_TEST:
267
                        return(0);
268
        }
269
        return(0);
270
}
271
 
272
static  int pci_index __initdata = 0;
273
 
274
__initfunc(int
275
setup_niccy(struct IsdnCard *card))
276
{
277
        struct IsdnCardState *cs = card->cs;
278
        char tmp[64];
279
 
280
        strcpy(tmp, niccy_revision);
281
        printk(KERN_INFO "HiSax: Niccy driver Rev. %s\n", HiSax_getrev(tmp));
282
        if (cs->typ != ISDN_CTYPE_NICCY)
283
                return (0);
284
 
285
        if (card->para[1]) {
286
                cs->hw.niccy.isac = card->para[1] + ISAC_PNP;
287
                cs->hw.niccy.hscx = card->para[1] + HSCX_PNP;
288
                cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP;
289
                cs->hw.niccy.hscx_ale = card->para[2] + HSCX_PNP;
290
                cs->hw.niccy.cfg_reg = 0;
291
                cs->subtyp = NICCY_PNP;
292
                cs->irq = card->para[0];
293
                if (check_region((cs->hw.niccy.isac), 2)) {
294
                        printk(KERN_WARNING
295
                                "HiSax: %s data port %x-%x already in use\n",
296
                                CardType[card->typ],
297
                                cs->hw.niccy.isac,
298
                                cs->hw.niccy.isac + 1);
299
                        return (0);
300
                } else
301
                        request_region(cs->hw.niccy.isac, 2, "niccy data");
302
                if (check_region((cs->hw.niccy.isac_ale), 2)) {
303
                        printk(KERN_WARNING
304
                                "HiSax: %s address port %x-%x already in use\n",
305
                                CardType[card->typ],
306
                                cs->hw.niccy.isac_ale,
307
                                cs->hw.niccy.isac_ale + 1);
308
                        release_region(cs->hw.niccy.isac, 2);
309
                        return (0);
310
                } else
311
                        request_region(cs->hw.niccy.isac_ale, 2, "niccy addr");
312
        } else {
313
#if CONFIG_PCI
314
                u_char pci_bus, pci_device_fn, pci_irq;
315
                u_int pci_ioaddr;
316
 
317
                cs->subtyp = 0;
318
                for (; pci_index < 0xff; pci_index++) {
319
                        if (pcibios_find_device(PCI_VENDOR_DR_NEUHAUS,
320
                           PCI_NICCY_ID, pci_index, &pci_bus, &pci_device_fn)
321
                           == PCIBIOS_SUCCESSFUL)
322
                                cs->subtyp = NICCY_PCI;
323
                        else
324
                                break;
325
                        /* get IRQ */
326
                        pcibios_read_config_byte(pci_bus, pci_device_fn,
327
                                PCI_INTERRUPT_LINE, &pci_irq);
328
 
329
                        /* get IO pci AMCC address */
330
                        pcibios_read_config_dword(pci_bus, pci_device_fn,
331
                                PCI_BASE_ADDRESS_0, &pci_ioaddr);
332
                        if (!pci_ioaddr) {
333
                                printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n");
334
                                return(0);
335
                        }
336
                        cs->hw.niccy.cfg_reg = pci_ioaddr & ~3 ;
337
                        /* get IO address */
338
                        pcibios_read_config_dword(pci_bus, pci_device_fn,
339
                                PCI_BASE_ADDRESS_1, &pci_ioaddr);
340
                        if (cs->subtyp)
341
                                break;
342
                }
343
                if (!cs->subtyp) {
344
                        printk(KERN_WARNING "Niccy: No PCI card found\n");
345
                        return(0);
346
                }
347
                pci_index++;
348
                if (!pci_irq) {
349
                        printk(KERN_WARNING "Niccy: No IRQ for PCI card found\n");
350
                        return(0);
351
                }
352
                if (!pci_ioaddr) {
353
                        printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n");
354
                        return(0);
355
                }
356
 
357
                pci_ioaddr &= ~3; /* remove io/mem flag */
358
                cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA;
359
                cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR;
360
                cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA;
361
                cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR;
362
                cs->irq = pci_irq;
363
                if (check_region((cs->hw.niccy.isac), 4)) {
364
                        printk(KERN_WARNING
365
                                "HiSax: %s data port %x-%x already in use\n",
366
                                CardType[card->typ],
367
                                cs->hw.niccy.isac,
368
                                cs->hw.niccy.isac + 4);
369
                        return (0);
370
                } else
371
                        request_region(cs->hw.niccy.isac, 4, "niccy");
372
                if (check_region(cs->hw.niccy.cfg_reg, 0x80)) {
373
                        printk(KERN_WARNING
374
                               "HiSax: %s pci port %x-%x already in use\n",
375
                                CardType[card->typ],
376
                                cs->hw.niccy.cfg_reg,
377
                                cs->hw.niccy.cfg_reg + 0x80);
378
                        release_region(cs->hw.niccy.isac, 4);
379
                        return (0);
380
                } else {
381
                        request_region(cs->hw.niccy.cfg_reg, 0x80, "niccy pci");
382
                }
383
#else
384
                printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n");
385
                printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n");
386
                return (0);
387
#endif /* CONFIG_PCI */
388
        }
389
        printk(KERN_INFO
390
                "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n",
391
                CardType[cs->typ], (cs->subtyp==1) ? "PnP":"PCI",
392
                cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale);
393
        cs->readisac = &ReadISAC;
394
        cs->writeisac = &WriteISAC;
395
        cs->readisacfifo = &ReadISACfifo;
396
        cs->writeisacfifo = &WriteISACfifo;
397
        cs->BC_Read_Reg = &ReadHSCX;
398
        cs->BC_Write_Reg = &WriteHSCX;
399
        cs->BC_Send_Data = &hscx_fill_fifo;
400
        cs->cardmsg = &niccy_card_msg;
401
        ISACVersion(cs, "Niccy:");
402
        if (HscxVersion(cs, "Niccy:")) {
403
                printk(KERN_WARNING
404
                    "Niccy: wrong HSCX versions check IO address\n");
405
                release_io_niccy(cs);
406
                return (0);
407
        }
408
        return (1);
409
}

powered by: WebSVN 2.1.0

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