1
/* $Id: telespci.c,v 2.23.2.3 2004/01/13 14:31:26 keil Exp $
3
* low level stuff for Teles PCI isdn cards
5
* Author Ton van Rosmalen
7
* Copyright by Ton van Rosmalen
8
* by Karsten Keil <keil@isdn4linux.de>
10
* This software may be used and distributed according to the terms
11
* of the GNU General Public License, incorporated herein by reference.
15
#include <linux/init.h>
20
#include <linux/pci.h>
22
static const char *telespci_revision = "$Revision: 2.23.2.3 $";
24
#define ZORAN_PO_RQ_PEN 0x02000000
25
#define ZORAN_PO_WR 0x00800000
26
#define ZORAN_PO_GID0 0x00000000
27
#define ZORAN_PO_GID1 0x00100000
28
#define ZORAN_PO_GREG0 0x00000000
29
#define ZORAN_PO_GREG1 0x00010000
30
#define ZORAN_PO_DMASK 0xFF
32
#define WRITE_ADDR_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG0)
33
#define READ_DATA_ISAC (ZORAN_PO_GID0 | ZORAN_PO_GREG1)
34
#define WRITE_DATA_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG1)
35
#define WRITE_ADDR_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG0)
36
#define READ_DATA_HSCX (ZORAN_PO_GID1 | ZORAN_PO_GREG1)
37
#define WRITE_DATA_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG1)
39
#define ZORAN_WAIT_NOBUSY do { \
40
portdata = readl(adr + 0x200); \
41
} while (portdata & ZORAN_PO_RQ_PEN)
44
readisac(void __iomem *adr, u_char off)
46
register unsigned int portdata;
50
/* set address for ISAC */
51
writel(WRITE_ADDR_ISAC | off, adr + 0x200);
54
/* read data from ISAC */
55
writel(READ_DATA_ISAC, adr + 0x200);
57
return((u_char)(portdata & ZORAN_PO_DMASK));
61
writeisac(void __iomem *adr, u_char off, u_char data)
63
register unsigned int portdata;
67
/* set address for ISAC */
68
writel(WRITE_ADDR_ISAC | off, adr + 0x200);
71
/* write data to ISAC */
72
writel(WRITE_DATA_ISAC | data, adr + 0x200);
77
readhscx(void __iomem *adr, int hscx, u_char off)
79
register unsigned int portdata;
82
/* set address for HSCX */
83
writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
86
/* read data from HSCX */
87
writel(READ_DATA_HSCX, adr + 0x200);
89
return ((u_char)(portdata & ZORAN_PO_DMASK));
93
writehscx(void __iomem *adr, int hscx, u_char off, u_char data)
95
register unsigned int portdata;
98
/* set address for HSCX */
99
writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
102
/* write data to HSCX */
103
writel(WRITE_DATA_HSCX | data, adr + 0x200);
108
read_fifo_isac(void __iomem *adr, u_char * data, int size)
110
register unsigned int portdata;
114
/* read data from ISAC */
115
for (i = 0; i < size; i++) {
116
/* set address for ISAC fifo */
117
writel(WRITE_ADDR_ISAC | 0x1E, adr + 0x200);
119
writel(READ_DATA_ISAC, adr + 0x200);
121
data[i] = (u_char)(portdata & ZORAN_PO_DMASK);
126
write_fifo_isac(void __iomem *adr, u_char * data, int size)
128
register unsigned int portdata;
132
/* write data to ISAC */
133
for (i = 0; i < size; i++) {
134
/* set address for ISAC fifo */
135
writel(WRITE_ADDR_ISAC | 0x1E, adr + 0x200);
137
writel(WRITE_DATA_ISAC | data[i], adr + 0x200);
143
read_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
145
register unsigned int portdata;
149
/* read data from HSCX */
150
for (i = 0; i < size; i++) {
151
/* set address for HSCX fifo */
152
writel(WRITE_ADDR_HSCX |(hscx ? 0x5F:0x1F), adr + 0x200);
154
writel(READ_DATA_HSCX, adr + 0x200);
156
data[i] = (u_char) (portdata & ZORAN_PO_DMASK);
161
write_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
163
unsigned int portdata;
167
/* write data to HSCX */
168
for (i = 0; i < size; i++) {
169
/* set address for HSCX fifo */
170
writel(WRITE_ADDR_HSCX |(hscx ? 0x5F:0x1F), adr + 0x200);
172
writel(WRITE_DATA_HSCX | data[i], adr + 0x200);
178
/* Interface functions */
181
ReadISAC(struct IsdnCardState *cs, u_char offset)
183
return (readisac(cs->hw.teles0.membase, offset));
187
WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
189
writeisac(cs->hw.teles0.membase, offset, value);
193
ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
195
read_fifo_isac(cs->hw.teles0.membase, data, size);
199
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
201
write_fifo_isac(cs->hw.teles0.membase, data, size);
205
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
207
return (readhscx(cs->hw.teles0.membase, hscx, offset));
211
WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
213
writehscx(cs->hw.teles0.membase, hscx, offset, value);
217
* fast interrupt HSCX stuff goes here
220
#define READHSCX(cs, nr, reg) readhscx(cs->hw.teles0.membase, nr, reg)
221
#define WRITEHSCX(cs, nr, reg, data) writehscx(cs->hw.teles0.membase, nr, reg, data)
222
#define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)
223
#define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)
225
#include "hscx_irq.c"
228
telespci_interrupt(int intno, void *dev_id)
230
struct IsdnCardState *cs = dev_id;
234
spin_lock_irqsave(&cs->lock, flags);
235
hval = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA);
237
hscx_int_main(cs, hval);
238
ival = readisac(cs->hw.teles0.membase, ISAC_ISTA);
239
if ((hval | ival) == 0) {
240
spin_unlock_irqrestore(&cs->lock, flags);
244
isac_interrupt(cs, ival);
245
/* Clear interrupt register for Zoran PCI controller */
246
writel(0x70000000, cs->hw.teles0.membase + 0x3C);
248
writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF);
249
writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF);
250
writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF);
251
writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0);
252
writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0);
253
writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0);
254
spin_unlock_irqrestore(&cs->lock, flags);
259
release_io_telespci(struct IsdnCardState *cs)
261
iounmap(cs->hw.teles0.membase);
265
TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg)
273
release_io_telespci(cs);
276
spin_lock_irqsave(&cs->lock, flags);
278
spin_unlock_irqrestore(&cs->lock, flags);
286
static struct pci_dev *dev_tel __devinitdata = NULL;
289
setup_telespci(struct IsdnCard *card)
291
struct IsdnCardState *cs = card->cs;
295
#error "not running on big endian machines now"
298
strcpy(tmp, telespci_revision);
299
printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp));
300
if (cs->typ != ISDN_CTYPE_TELESPCI)
303
if ((dev_tel = hisax_find_pci_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) {
304
if (pci_enable_device(dev_tel))
306
cs->irq = dev_tel->irq;
308
printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
311
cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0),
313
printk(KERN_INFO "Found: Zoran, base-address: 0x%llx, irq: 0x%x\n",
314
(unsigned long long)pci_resource_start(dev_tel, 0),
317
printk(KERN_WARNING "TelesPCI: No PCI card found\n");
321
/* Initialize Zoran PCI controller */
322
writel(0x00000000, cs->hw.teles0.membase + 0x28);
323
writel(0x01000000, cs->hw.teles0.membase + 0x28);
324
writel(0x01000000, cs->hw.teles0.membase + 0x28);
325
writel(0x7BFFFFFF, cs->hw.teles0.membase + 0x2C);
326
writel(0x70000000, cs->hw.teles0.membase + 0x3C);
327
writel(0x61000000, cs->hw.teles0.membase + 0x40);
328
/* writel(0x00800000, cs->hw.teles0.membase + 0x200); */
331
"HiSax: Teles PCI config irq:%d mem:%p\n",
333
cs->hw.teles0.membase);
336
cs->readisac = &ReadISAC;
337
cs->writeisac = &WriteISAC;
338
cs->readisacfifo = &ReadISACfifo;
339
cs->writeisacfifo = &WriteISACfifo;
340
cs->BC_Read_Reg = &ReadHSCX;
341
cs->BC_Write_Reg = &WriteHSCX;
342
cs->BC_Send_Data = &hscx_fill_fifo;
343
cs->cardmsg = &TelesPCI_card_msg;
344
cs->irq_func = &telespci_interrupt;
345
cs->irq_flags |= IRQF_SHARED;
346
ISACVersion(cs, "TelesPCI:");
347
if (HscxVersion(cs, "TelesPCI:")) {
349
"TelesPCI: wrong HSCX versions check IO/MEM addresses\n");
350
release_io_telespci(cs);