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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $Id: telespci.c,v 2.23.2.3 2004/01/13 14:31:26 keil Exp $
2
 *
3
 * low level stuff for Teles PCI isdn cards
4
 *
5
 * Author       Ton van Rosmalen
6
 *              Karsten Keil
7
 * Copyright    by Ton van Rosmalen
8
 *              by Karsten Keil      <keil@isdn4linux.de>
9
 *
10
 * This software may be used and distributed according to the terms
11
 * of the GNU General Public License, incorporated herein by reference.
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
#include <linux/pci.h>
21
 
22
extern const char *CardType[];
23
static const char *telespci_revision = "$Revision: 2.23.2.3 $";
24
 
25
#define ZORAN_PO_RQ_PEN 0x02000000
26
#define ZORAN_PO_WR     0x00800000
27
#define ZORAN_PO_GID0   0x00000000
28
#define ZORAN_PO_GID1   0x00100000
29
#define ZORAN_PO_GREG0  0x00000000
30
#define ZORAN_PO_GREG1  0x00010000
31
#define ZORAN_PO_DMASK  0xFF
32
 
33
#define WRITE_ADDR_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG0)
34
#define READ_DATA_ISAC  (ZORAN_PO_GID0 | ZORAN_PO_GREG1)
35
#define WRITE_DATA_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG1)
36
#define WRITE_ADDR_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG0)
37
#define READ_DATA_HSCX  (ZORAN_PO_GID1 | ZORAN_PO_GREG1)
38
#define WRITE_DATA_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG1)
39
 
40
#define ZORAN_WAIT_NOBUSY       do { \
41
                                        portdata = readl(adr + 0x200); \
42
                                } while (portdata & ZORAN_PO_RQ_PEN)
43
 
44
static inline u_char
45
readisac(void __iomem *adr, u_char off)
46
{
47
        register unsigned int portdata;
48
 
49
        ZORAN_WAIT_NOBUSY;
50
 
51
        /* set address for ISAC */
52
        writel(WRITE_ADDR_ISAC | off, adr + 0x200);
53
        ZORAN_WAIT_NOBUSY;
54
 
55
        /* read data from ISAC */
56
        writel(READ_DATA_ISAC, adr + 0x200);
57
        ZORAN_WAIT_NOBUSY;
58
        return((u_char)(portdata & ZORAN_PO_DMASK));
59
}
60
 
61
static inline void
62
writeisac(void __iomem *adr, u_char off, u_char data)
63
{
64
        register unsigned int portdata;
65
 
66
        ZORAN_WAIT_NOBUSY;
67
 
68
        /* set address for ISAC */
69
        writel(WRITE_ADDR_ISAC | off, adr + 0x200);
70
        ZORAN_WAIT_NOBUSY;
71
 
72
        /* write data to ISAC */
73
        writel(WRITE_DATA_ISAC | data, adr + 0x200);
74
        ZORAN_WAIT_NOBUSY;
75
}
76
 
77
static inline u_char
78
readhscx(void __iomem *adr, int hscx, u_char off)
79
{
80
        register unsigned int portdata;
81
 
82
        ZORAN_WAIT_NOBUSY;
83
        /* set address for HSCX */
84
        writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
85
        ZORAN_WAIT_NOBUSY;
86
 
87
        /* read data from HSCX */
88
        writel(READ_DATA_HSCX, adr + 0x200);
89
        ZORAN_WAIT_NOBUSY;
90
        return ((u_char)(portdata & ZORAN_PO_DMASK));
91
}
92
 
93
static inline void
94
writehscx(void __iomem *adr, int hscx, u_char off, u_char data)
95
{
96
        register unsigned int portdata;
97
 
98
        ZORAN_WAIT_NOBUSY;
99
        /* set address for HSCX */
100
        writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
101
        ZORAN_WAIT_NOBUSY;
102
 
103
        /* write data to HSCX */
104
        writel(WRITE_DATA_HSCX | data, adr + 0x200);
105
        ZORAN_WAIT_NOBUSY;
106
}
107
 
108
static inline void
109
read_fifo_isac(void __iomem *adr, u_char * data, int size)
110
{
111
        register unsigned int portdata;
112
        register int i;
113
 
114
        ZORAN_WAIT_NOBUSY;
115
        /* read data from ISAC */
116
        for (i = 0; i < size; i++) {
117
                /* set address for ISAC fifo */
118
                writel(WRITE_ADDR_ISAC | 0x1E, adr + 0x200);
119
                ZORAN_WAIT_NOBUSY;
120
                writel(READ_DATA_ISAC, adr + 0x200);
121
                ZORAN_WAIT_NOBUSY;
122
                data[i] = (u_char)(portdata & ZORAN_PO_DMASK);
123
        }
124
}
125
 
126
static void
127
write_fifo_isac(void __iomem *adr, u_char * data, int size)
128
{
129
        register unsigned int portdata;
130
        register int i;
131
 
132
        ZORAN_WAIT_NOBUSY;
133
        /* write data to ISAC */
134
        for (i = 0; i < size; i++) {
135
                /* set address for ISAC fifo */
136
                writel(WRITE_ADDR_ISAC | 0x1E, adr + 0x200);
137
                ZORAN_WAIT_NOBUSY;
138
                writel(WRITE_DATA_ISAC | data[i], adr + 0x200);
139
                ZORAN_WAIT_NOBUSY;
140
        }
141
}
142
 
143
static inline void
144
read_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
145
{
146
        register unsigned int portdata;
147
        register int i;
148
 
149
        ZORAN_WAIT_NOBUSY;
150
        /* read data from HSCX */
151
        for (i = 0; i < size; i++) {
152
                /* set address for HSCX fifo */
153
                writel(WRITE_ADDR_HSCX |(hscx ? 0x5F:0x1F), adr + 0x200);
154
                ZORAN_WAIT_NOBUSY;
155
                writel(READ_DATA_HSCX, adr + 0x200);
156
                ZORAN_WAIT_NOBUSY;
157
                data[i] = (u_char) (portdata & ZORAN_PO_DMASK);
158
        }
159
}
160
 
161
static inline void
162
write_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
163
{
164
        unsigned int portdata;
165
        register int i;
166
 
167
        ZORAN_WAIT_NOBUSY;
168
        /* write data to HSCX */
169
        for (i = 0; i < size; i++) {
170
                /* set address for HSCX fifo */
171
                writel(WRITE_ADDR_HSCX |(hscx ? 0x5F:0x1F), adr + 0x200);
172
                ZORAN_WAIT_NOBUSY;
173
                writel(WRITE_DATA_HSCX | data[i], adr + 0x200);
174
                ZORAN_WAIT_NOBUSY;
175
                udelay(10);
176
        }
177
}
178
 
179
/* Interface functions */
180
 
181
static u_char
182
ReadISAC(struct IsdnCardState *cs, u_char offset)
183
{
184
        return (readisac(cs->hw.teles0.membase, offset));
185
}
186
 
187
static void
188
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
189
{
190
        writeisac(cs->hw.teles0.membase, offset, value);
191
}
192
 
193
static void
194
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
195
{
196
        read_fifo_isac(cs->hw.teles0.membase, data, size);
197
}
198
 
199
static void
200
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
201
{
202
        write_fifo_isac(cs->hw.teles0.membase, data, size);
203
}
204
 
205
static u_char
206
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
207
{
208
        return (readhscx(cs->hw.teles0.membase, hscx, offset));
209
}
210
 
211
static void
212
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
213
{
214
        writehscx(cs->hw.teles0.membase, hscx, offset, value);
215
}
216
 
217
/*
218
 * fast interrupt HSCX stuff goes here
219
 */
220
 
221
#define READHSCX(cs, nr, reg) readhscx(cs->hw.teles0.membase, nr, reg)
222
#define WRITEHSCX(cs, nr, reg, data) writehscx(cs->hw.teles0.membase, nr, reg, data)
223
#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)
224
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)
225
 
226
#include "hscx_irq.c"
227
 
228
static irqreturn_t
229
telespci_interrupt(int intno, void *dev_id)
230
{
231
        struct IsdnCardState *cs = dev_id;
232
        u_char hval, ival;
233
        u_long flags;
234
 
235
        spin_lock_irqsave(&cs->lock, flags);
236
        hval = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA);
237
        if (hval)
238
                hscx_int_main(cs, hval);
239
        ival = readisac(cs->hw.teles0.membase, ISAC_ISTA);
240
        if ((hval | ival) == 0) {
241
                spin_unlock_irqrestore(&cs->lock, flags);
242
                return IRQ_NONE;
243
        }
244
        if (ival)
245
                isac_interrupt(cs, ival);
246
        /* Clear interrupt register for Zoran PCI controller */
247
        writel(0x70000000, cs->hw.teles0.membase + 0x3C);
248
 
249
        writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF);
250
        writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF);
251
        writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF);
252
        writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0);
253
        writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0);
254
        writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0);
255
        spin_unlock_irqrestore(&cs->lock, flags);
256
        return IRQ_HANDLED;
257
}
258
 
259
static void
260
release_io_telespci(struct IsdnCardState *cs)
261
{
262
        iounmap(cs->hw.teles0.membase);
263
}
264
 
265
static int
266
TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg)
267
{
268
        u_long flags;
269
 
270
        switch (mt) {
271
                case CARD_RESET:
272
                        return(0);
273
                case CARD_RELEASE:
274
                        release_io_telespci(cs);
275
                        return(0);
276
                case CARD_INIT:
277
                        spin_lock_irqsave(&cs->lock, flags);
278
                        inithscxisac(cs, 3);
279
                        spin_unlock_irqrestore(&cs->lock, flags);
280
                        return(0);
281
                case CARD_TEST:
282
                        return(0);
283
        }
284
        return(0);
285
}
286
 
287
static struct pci_dev *dev_tel __devinitdata = NULL;
288
 
289
int __devinit
290
setup_telespci(struct IsdnCard *card)
291
{
292
        struct IsdnCardState *cs = card->cs;
293
        char tmp[64];
294
 
295
#ifdef __BIG_ENDIAN
296
#error "not running on big endian machines now"
297
#endif
298
 
299
        strcpy(tmp, telespci_revision);
300
        printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp));
301
        if (cs->typ != ISDN_CTYPE_TELESPCI)
302
                return (0);
303
 
304
        if ((dev_tel = pci_find_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) {
305
                if (pci_enable_device(dev_tel))
306
                        return(0);
307
                cs->irq = dev_tel->irq;
308
                if (!cs->irq) {
309
                        printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
310
                        return(0);
311
                }
312
                cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0),
313
                        PAGE_SIZE);
314
                printk(KERN_INFO "Found: Zoran, base-address: 0x%llx, irq: 0x%x\n",
315
                        (unsigned long long)pci_resource_start(dev_tel, 0),
316
                        dev_tel->irq);
317
        } else {
318
                printk(KERN_WARNING "TelesPCI: No PCI card found\n");
319
                return(0);
320
        }
321
 
322
        /* Initialize Zoran PCI controller */
323
        writel(0x00000000, cs->hw.teles0.membase + 0x28);
324
        writel(0x01000000, cs->hw.teles0.membase + 0x28);
325
        writel(0x01000000, cs->hw.teles0.membase + 0x28);
326
        writel(0x7BFFFFFF, cs->hw.teles0.membase + 0x2C);
327
        writel(0x70000000, cs->hw.teles0.membase + 0x3C);
328
        writel(0x61000000, cs->hw.teles0.membase + 0x40);
329
        /* writel(0x00800000, cs->hw.teles0.membase + 0x200); */
330
 
331
        printk(KERN_INFO
332
               "HiSax: %s config irq:%d mem:%p\n",
333
               CardType[cs->typ], cs->irq,
334
               cs->hw.teles0.membase);
335
 
336
        setup_isac(cs);
337
        cs->readisac = &ReadISAC;
338
        cs->writeisac = &WriteISAC;
339
        cs->readisacfifo = &ReadISACfifo;
340
        cs->writeisacfifo = &WriteISACfifo;
341
        cs->BC_Read_Reg = &ReadHSCX;
342
        cs->BC_Write_Reg = &WriteHSCX;
343
        cs->BC_Send_Data = &hscx_fill_fifo;
344
        cs->cardmsg = &TelesPCI_card_msg;
345
        cs->irq_func = &telespci_interrupt;
346
        cs->irq_flags |= IRQF_SHARED;
347
        ISACVersion(cs, "TelesPCI:");
348
        if (HscxVersion(cs, "TelesPCI:")) {
349
                printk(KERN_WARNING
350
                 "TelesPCI: wrong HSCX versions check IO/MEM addresses\n");
351
                release_io_telespci(cs);
352
                return (0);
353
        }
354
        return (1);
355
}

powered by: WebSVN 2.1.0

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