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

Subversion Repositories or1k

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/* $Id: telespci.c,v 1.1.1.1 2001-09-10 07:44:19 simons Exp $
2
 
3
 * telespci.c     low level stuff for Teles PCI isdn cards
4
 *
5
 * Author       Ton van Rosmalen
6
 *              Karsten Keil (keil@temic-ech.spacenet.de)
7
 *
8
 *
9
 * $Log: not supported by cvs2svn $
10
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
11
 * Initial revision
12
 *
13
 * Revision 1.1.2.3  1998/10/16 12:46:09  keil
14
 * fix pci detection for more as one card
15
 *
16
 * Revision 1.1.2.2  1998/04/20 08:52:46  keil
17
 * Fix register offsets
18
 *
19
 * Revision 1.1.2.1  1998/04/11 18:44:42  keil
20
 * New files
21
 *
22
 *
23
 */
24
#define __NO_VERSION__
25
#include <linux/config.h>
26
#include "hisax.h"
27
#include "isac.h"
28
#include "hscx.h"
29
#include "isdnl1.h"
30
#include <linux/pci.h>
31
#include <linux/bios32.h>
32
 
33
extern const char *CardType[];
34
 
35
const char *telespci_revision = "$Revision: 1.1.1.1 $";
36
 
37
#define ZORAN_PO_RQ_PEN 0x02000000
38
#define ZORAN_PO_WR     0x00800000
39
#define ZORAN_PO_GID0   0x00000000
40
#define ZORAN_PO_GID1   0x00100000
41
#define ZORAN_PO_GREG0  0x00000000
42
#define ZORAN_PO_GREG1  0x00010000
43
#define ZORAN_PO_DMASK  0xFF
44
 
45
#define WRITE_ADDR_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG0)
46
#define READ_DATA_ISAC  (ZORAN_PO_GID0 | ZORAN_PO_GREG1)
47
#define WRITE_DATA_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG1)
48
#define WRITE_ADDR_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG0)
49
#define READ_DATA_HSCX  (ZORAN_PO_GID1 | ZORAN_PO_GREG1)
50
#define WRITE_DATA_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG1)
51
 
52
#define ZORAN_WAIT_NOBUSY       do { \
53
                                        portdata = readl(adr + 0x200); \
54
                                } while (portdata & ZORAN_PO_RQ_PEN)
55
 
56
static inline u_char
57
readisac(unsigned int adr, u_char off)
58
{
59
        register unsigned int portdata;
60
 
61
        ZORAN_WAIT_NOBUSY;
62
 
63
        /* set address for ISAC */
64
        writel(WRITE_ADDR_ISAC | off, adr + 0x200);
65
        ZORAN_WAIT_NOBUSY;
66
 
67
        /* read data from ISAC */
68
        writel(READ_DATA_ISAC, adr + 0x200);
69
        ZORAN_WAIT_NOBUSY;
70
        return((u_char)(portdata & ZORAN_PO_DMASK));
71
}
72
 
73
static inline void
74
writeisac(unsigned int adr, u_char off, u_char data)
75
{
76
        register unsigned int portdata;
77
 
78
        ZORAN_WAIT_NOBUSY;
79
 
80
        /* set address for ISAC */
81
        writel(WRITE_ADDR_ISAC | off, adr + 0x200);
82
        ZORAN_WAIT_NOBUSY;
83
 
84
        /* write data to ISAC */
85
        writel(WRITE_DATA_ISAC | data, adr + 0x200);
86
        ZORAN_WAIT_NOBUSY;
87
}
88
 
89
static inline u_char
90
readhscx(unsigned int adr, int hscx, u_char off)
91
{
92
        register unsigned int portdata;
93
 
94
        ZORAN_WAIT_NOBUSY;
95
        /* set address for HSCX */
96
        writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
97
        ZORAN_WAIT_NOBUSY;
98
 
99
        /* read data from HSCX */
100
        writel(READ_DATA_HSCX, adr + 0x200);
101
        ZORAN_WAIT_NOBUSY;
102
        return ((u_char)(portdata & ZORAN_PO_DMASK));
103
}
104
 
105
static inline void
106
writehscx(unsigned int adr, int hscx, u_char off, u_char data)
107
{
108
        register unsigned int portdata;
109
 
110
        ZORAN_WAIT_NOBUSY;
111
        /* set address for HSCX */
112
        writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
113
        ZORAN_WAIT_NOBUSY;
114
 
115
        /* write data to HSCX */
116
        writel(WRITE_DATA_HSCX | data, adr + 0x200);
117
        ZORAN_WAIT_NOBUSY;
118
}
119
 
120
static inline void
121
read_fifo_isac(unsigned int adr, u_char * data, int size)
122
{
123
        register unsigned int portdata;
124
        register int i;
125
 
126
        ZORAN_WAIT_NOBUSY;
127
        /* read data from ISAC */
128
        for (i = 0; i < size; i++) {
129
                /* set address for ISAC fifo */
130
                writel(WRITE_ADDR_ISAC | 0x1E, adr + 0x200);
131
                ZORAN_WAIT_NOBUSY;
132
                writel(READ_DATA_ISAC, adr + 0x200);
133
                ZORAN_WAIT_NOBUSY;
134
                data[i] = (u_char)(portdata & ZORAN_PO_DMASK);
135
        }
136
}
137
 
138
static void
139
write_fifo_isac(unsigned int adr, u_char * data, int size)
140
{
141
        register unsigned int portdata;
142
        register int i;
143
 
144
        ZORAN_WAIT_NOBUSY;
145
        /* write data to ISAC */
146
        for (i = 0; i < size; i++) {
147
                /* set address for ISAC fifo */
148
                writel(WRITE_ADDR_ISAC | 0x1E, adr + 0x200);
149
                ZORAN_WAIT_NOBUSY;
150
                writel(WRITE_DATA_ISAC | data[i], adr + 0x200);
151
                ZORAN_WAIT_NOBUSY;
152
        }
153
}
154
 
155
static inline void
156
read_fifo_hscx(unsigned int adr, int hscx, u_char * data, int size)
157
{
158
        register unsigned int portdata;
159
        register int i;
160
 
161
        ZORAN_WAIT_NOBUSY;
162
        /* read data from HSCX */
163
        for (i = 0; i < size; i++) {
164
                /* set address for HSCX fifo */
165
                writel(WRITE_ADDR_HSCX |(hscx ? 0x5F:0x1F), adr + 0x200);
166
                ZORAN_WAIT_NOBUSY;
167
                writel(READ_DATA_HSCX, adr + 0x200);
168
                ZORAN_WAIT_NOBUSY;
169
                data[i] = (u_char) (portdata & ZORAN_PO_DMASK);
170
        }
171
}
172
 
173
static inline void
174
write_fifo_hscx(unsigned int adr, int hscx, u_char * data, int size)
175
{
176
        unsigned int portdata;
177
        register int i;
178
 
179
        ZORAN_WAIT_NOBUSY;
180
        /* write data to HSCX */
181
        for (i = 0; i < size; i++) {
182
                /* set address for HSCX fifo */
183
                writel(WRITE_ADDR_HSCX |(hscx ? 0x5F:0x1F), adr + 0x200);
184
                ZORAN_WAIT_NOBUSY;
185
                writel(WRITE_DATA_HSCX | data[i], adr + 0x200);
186
                ZORAN_WAIT_NOBUSY;
187
                udelay(10);
188
        }
189
}
190
 
191
/* Interface functions */
192
 
193
static u_char
194
ReadISAC(struct IsdnCardState *cs, u_char offset)
195
{
196
        return (readisac(cs->hw.teles0.membase, offset));
197
}
198
 
199
static void
200
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
201
{
202
        writeisac(cs->hw.teles0.membase, offset, value);
203
}
204
 
205
static void
206
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
207
{
208
        read_fifo_isac(cs->hw.teles0.membase, data, size);
209
}
210
 
211
static void
212
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
213
{
214
        write_fifo_isac(cs->hw.teles0.membase, data, size);
215
}
216
 
217
static u_char
218
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
219
{
220
        return (readhscx(cs->hw.teles0.membase, hscx, offset));
221
}
222
 
223
static void
224
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
225
{
226
        writehscx(cs->hw.teles0.membase, hscx, offset, value);
227
}
228
 
229
/*
230
 * fast interrupt HSCX stuff goes here
231
 */
232
 
233
#define READHSCX(cs, nr, reg) readhscx(cs->hw.teles0.membase, nr, reg)
234
#define WRITEHSCX(cs, nr, reg, data) writehscx(cs->hw.teles0.membase, nr, reg, data)
235
#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)
236
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)
237
 
238
#include "hscx_irq.c"
239
 
240
static void
241
telespci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
242
{
243
#define MAXCOUNT 20
244
        struct IsdnCardState *cs = dev_id;
245
        u_char val, stat = 0;
246
 
247
        if (!cs) {
248
                printk(KERN_WARNING "TelesPCI: Spurious interrupt!\n");
249
                return;
250
        }
251
        val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA);
252
        if (val) {
253
                hscx_int_main(cs, val);
254
                stat |= 1;
255
        }
256
        val = readisac(cs->hw.teles0.membase, ISAC_ISTA);
257
        if (val) {
258
                isac_interrupt(cs, val);
259
                stat |= 2;
260
        }
261
        /* Clear interrupt register for Zoran PCI controller */
262
        writel(0x70000000, cs->hw.teles0.membase + 0x3C);
263
 
264
        if (stat & 1) {
265
                writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF);
266
                writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF);
267
                writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0);
268
                writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0);
269
        }
270
        if (stat & 2) {
271
                writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF);
272
                writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0);
273
        }
274
}
275
 
276
void
277
release_io_telespci(struct IsdnCardState *cs)
278
{
279
        vfree((void *)cs->hw.teles0.membase);
280
}
281
 
282
static int
283
TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg)
284
{
285
        switch (mt) {
286
                case CARD_RESET:
287
                        return(0);
288
                case CARD_RELEASE:
289
                        release_io_telespci(cs);
290
                        return(0);
291
                case CARD_SETIRQ:
292
                        return(request_irq(cs->irq, &telespci_interrupt,
293
                                        I4L_IRQ_FLAG | SA_SHIRQ, "HiSax", cs));
294
                case CARD_INIT:
295
                        inithscxisac(cs, 3);
296
                        return(0);
297
                case CARD_TEST:
298
                        return(0);
299
        }
300
        return(0);
301
}
302
 
303
static  int pci_index __initdata = 0;
304
 
305
__initfunc(int
306
setup_telespci(struct IsdnCard *card))
307
{
308
        int found=0;
309
        struct IsdnCardState *cs = card->cs;
310
        char tmp[64];
311
        u_char pci_bus, pci_device_fn, pci_irq;
312
        u_int pci_memaddr;
313
 
314
        strcpy(tmp, telespci_revision);
315
        printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp));
316
        if (cs->typ != ISDN_CTYPE_TELESPCI)
317
                return (0);
318
 
319
#if CONFIG_PCI
320
        for (; pci_index < 0xff; pci_index++) {
321
                if (pcibios_find_device (0x11DE, 0x6120,
322
                        pci_index, &pci_bus, &pci_device_fn)
323
                        == PCIBIOS_SUCCESSFUL) {
324
                        found = 1;
325
                } else {
326
                        break;
327
                }
328
                pcibios_read_config_dword(pci_bus, pci_device_fn,
329
                                PCI_BASE_ADDRESS_0, &pci_memaddr);
330
                pcibios_read_config_byte(pci_bus, pci_device_fn,
331
                                PCI_INTERRUPT_LINE, &pci_irq);
332
 
333
                printk(KERN_INFO "Found: Zoran, base-address: 0x%x,"
334
                        " irq: 0x%x\n", pci_memaddr, pci_irq);
335
                break;
336
        }
337
        if (!found) {
338
                printk(KERN_WARNING "TelesPCI: No PCI card found\n");
339
                return(0);
340
        }
341
        pci_index++;
342
        cs->hw.teles0.membase = (u_int) vremap(pci_memaddr, PAGE_SIZE);
343
        cs->irq = pci_irq;
344
#else
345
        printk(KERN_WARNING "HiSax: Teles/PCI and NO_PCI_BIOS\n");
346
        printk(KERN_WARNING "HiSax: Teles/PCI unable to config\n");
347
        return (0);
348
#endif /* CONFIG_PCI */
349
 
350
        /* Initialize Zoran PCI controller */
351
        writel(0x00000000, cs->hw.teles0.membase + 0x28);
352
        writel(0x01000000, cs->hw.teles0.membase + 0x28);
353
        writel(0x01000000, cs->hw.teles0.membase + 0x28);
354
        writel(0x7BFFFFFF, cs->hw.teles0.membase + 0x2C);
355
        writel(0x70000000, cs->hw.teles0.membase + 0x3C);
356
        writel(0x61000000, cs->hw.teles0.membase + 0x40);
357
        /* writel(0x00800000, cs->hw.teles0.membase + 0x200); */
358
 
359
        printk(KERN_INFO
360
               "HiSax: %s config irq:%d mem:%x\n",
361
               CardType[cs->typ], cs->irq,
362
               cs->hw.teles0.membase);
363
 
364
        cs->readisac = &ReadISAC;
365
        cs->writeisac = &WriteISAC;
366
        cs->readisacfifo = &ReadISACfifo;
367
        cs->writeisacfifo = &WriteISACfifo;
368
        cs->BC_Read_Reg = &ReadHSCX;
369
        cs->BC_Write_Reg = &WriteHSCX;
370
        cs->BC_Send_Data = &hscx_fill_fifo;
371
        cs->cardmsg = &TelesPCI_card_msg;
372
        ISACVersion(cs, "TelesPCI:");
373
        if (HscxVersion(cs, "TelesPCI:")) {
374
                printk(KERN_WARNING
375
                 "TelesPCI: wrong HSCX versions check IO/MEM addresses\n");
376
                release_io_telespci(cs);
377
                return (0);
378
        }
379
        return (1);
380
}

powered by: WebSVN 2.1.0

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