1 /* $Id: telespci.c,v 2.13 2000/06/26 08:59:15 keil Exp $
3 * telespci.c low level stuff for Teles PCI isdn cards
5 * Author Ton van Rosmalen
6 * Karsten Keil (keil@isdn4linux.de)
8 * This file is (c) under GNU PUBLIC LICENSE
11 #define __NO_VERSION__
12 #include <linux/config.h>
17 #include <linux/pci.h>
19 extern const char *CardType
[];
20 const char *telespci_revision
= "$Revision: 2.13 $";
22 #define ZORAN_PO_RQ_PEN 0x02000000
23 #define ZORAN_PO_WR 0x00800000
24 #define ZORAN_PO_GID0 0x00000000
25 #define ZORAN_PO_GID1 0x00100000
26 #define ZORAN_PO_GREG0 0x00000000
27 #define ZORAN_PO_GREG1 0x00010000
28 #define ZORAN_PO_DMASK 0xFF
30 #define WRITE_ADDR_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG0)
31 #define READ_DATA_ISAC (ZORAN_PO_GID0 | ZORAN_PO_GREG1)
32 #define WRITE_DATA_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG1)
33 #define WRITE_ADDR_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG0)
34 #define READ_DATA_HSCX (ZORAN_PO_GID1 | ZORAN_PO_GREG1)
35 #define WRITE_DATA_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG1)
37 #define ZORAN_WAIT_NOBUSY do { \
38 portdata = readl(adr + 0x200); \
39 } while (portdata & ZORAN_PO_RQ_PEN)
42 readisac(unsigned long adr
, u_char off
)
44 register unsigned int portdata
;
48 /* set address for ISAC */
49 writel(WRITE_ADDR_ISAC
| off
, adr
+ 0x200);
52 /* read data from ISAC */
53 writel(READ_DATA_ISAC
, adr
+ 0x200);
55 return((u_char
)(portdata
& ZORAN_PO_DMASK
));
59 writeisac(unsigned long adr
, u_char off
, u_char data
)
61 register unsigned int portdata
;
65 /* set address for ISAC */
66 writel(WRITE_ADDR_ISAC
| off
, adr
+ 0x200);
69 /* write data to ISAC */
70 writel(WRITE_DATA_ISAC
| data
, adr
+ 0x200);
75 readhscx(unsigned long adr
, int hscx
, u_char off
)
77 register unsigned int portdata
;
80 /* set address for HSCX */
81 writel(WRITE_ADDR_HSCX
| ((hscx
? 0x40:0) + off
), adr
+ 0x200);
84 /* read data from HSCX */
85 writel(READ_DATA_HSCX
, adr
+ 0x200);
87 return ((u_char
)(portdata
& ZORAN_PO_DMASK
));
91 writehscx(unsigned long adr
, int hscx
, u_char off
, u_char data
)
93 register unsigned int portdata
;
96 /* set address for HSCX */
97 writel(WRITE_ADDR_HSCX
| ((hscx
? 0x40:0) + off
), adr
+ 0x200);
100 /* write data to HSCX */
101 writel(WRITE_DATA_HSCX
| data
, adr
+ 0x200);
106 read_fifo_isac(unsigned long adr
, u_char
* data
, int size
)
108 register unsigned int portdata
;
112 /* read data from ISAC */
113 for (i
= 0; i
< size
; i
++) {
114 /* set address for ISAC fifo */
115 writel(WRITE_ADDR_ISAC
| 0x1E, adr
+ 0x200);
117 writel(READ_DATA_ISAC
, adr
+ 0x200);
119 data
[i
] = (u_char
)(portdata
& ZORAN_PO_DMASK
);
124 write_fifo_isac(unsigned long adr
, u_char
* data
, int size
)
126 register unsigned int portdata
;
130 /* write data to ISAC */
131 for (i
= 0; i
< size
; i
++) {
132 /* set address for ISAC fifo */
133 writel(WRITE_ADDR_ISAC
| 0x1E, adr
+ 0x200);
135 writel(WRITE_DATA_ISAC
| data
[i
], adr
+ 0x200);
141 read_fifo_hscx(unsigned long adr
, int hscx
, u_char
* data
, int size
)
143 register unsigned int portdata
;
147 /* read data from HSCX */
148 for (i
= 0; i
< size
; i
++) {
149 /* set address for HSCX fifo */
150 writel(WRITE_ADDR_HSCX
|(hscx
? 0x5F:0x1F), adr
+ 0x200);
152 writel(READ_DATA_HSCX
, adr
+ 0x200);
154 data
[i
] = (u_char
) (portdata
& ZORAN_PO_DMASK
);
159 write_fifo_hscx(unsigned long adr
, int hscx
, u_char
* data
, int size
)
161 unsigned int portdata
;
165 /* write data to HSCX */
166 for (i
= 0; i
< size
; i
++) {
167 /* set address for HSCX fifo */
168 writel(WRITE_ADDR_HSCX
|(hscx
? 0x5F:0x1F), adr
+ 0x200);
170 writel(WRITE_DATA_HSCX
| data
[i
], adr
+ 0x200);
176 /* Interface functions */
179 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
181 return (readisac(cs
->hw
.teles0
.membase
, offset
));
185 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
187 writeisac(cs
->hw
.teles0
.membase
, offset
, value
);
191 ReadISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
193 read_fifo_isac(cs
->hw
.teles0
.membase
, data
, size
);
197 WriteISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
199 write_fifo_isac(cs
->hw
.teles0
.membase
, data
, size
);
203 ReadHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
)
205 return (readhscx(cs
->hw
.teles0
.membase
, hscx
, offset
));
209 WriteHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
, u_char value
)
211 writehscx(cs
->hw
.teles0
.membase
, hscx
, offset
, value
);
215 * fast interrupt HSCX stuff goes here
218 #define READHSCX(cs, nr, reg) readhscx(cs->hw.teles0.membase, nr, reg)
219 #define WRITEHSCX(cs, nr, reg, data) writehscx(cs->hw.teles0.membase, nr, reg, data)
220 #define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)
221 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)
223 #include "hscx_irq.c"
226 telespci_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
229 struct IsdnCardState
*cs
= dev_id
;
233 printk(KERN_WARNING
"TelesPCI: Spurious interrupt!\n");
236 val
= readhscx(cs
->hw
.teles0
.membase
, 1, HSCX_ISTA
);
238 hscx_int_main(cs
, val
);
239 val
= readisac(cs
->hw
.teles0
.membase
, ISAC_ISTA
);
241 isac_interrupt(cs
, val
);
242 /* Clear interrupt register for Zoran PCI controller */
243 writel(0x70000000, cs
->hw
.teles0
.membase
+ 0x3C);
245 writehscx(cs
->hw
.teles0
.membase
, 0, HSCX_MASK
, 0xFF);
246 writehscx(cs
->hw
.teles0
.membase
, 1, HSCX_MASK
, 0xFF);
247 writeisac(cs
->hw
.teles0
.membase
, ISAC_MASK
, 0xFF);
248 writeisac(cs
->hw
.teles0
.membase
, ISAC_MASK
, 0x0);
249 writehscx(cs
->hw
.teles0
.membase
, 0, HSCX_MASK
, 0x0);
250 writehscx(cs
->hw
.teles0
.membase
, 1, HSCX_MASK
, 0x0);
254 release_io_telespci(struct IsdnCardState
*cs
)
256 iounmap((void *)cs
->hw
.teles0
.membase
);
260 TelesPCI_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
266 release_io_telespci(cs
);
277 static struct pci_dev
*dev_tel __initdata
= NULL
;
280 setup_telespci(struct IsdnCard
*card
))
282 struct IsdnCardState
*cs
= card
->cs
;
285 strcpy(tmp
, telespci_revision
);
286 printk(KERN_INFO
"HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp
));
287 if (cs
->typ
!= ISDN_CTYPE_TELESPCI
)
290 if (!pci_present()) {
291 printk(KERN_ERR
"TelesPCI: no PCI bus present\n");
294 if ((dev_tel
= pci_find_device (0x11DE, 0x6120, dev_tel
))) {
295 if (pci_enable_device(dev_tel
))
297 cs
->irq
= dev_tel
->irq
;
299 printk(KERN_WARNING
"Teles: No IRQ for PCI card found\n");
302 cs
->hw
.teles0
.membase
= (u_long
) ioremap(dev_tel
->resource
[ 0].start
,
304 printk(KERN_INFO
"Found: Zoran, base-address: 0x%lx, irq: 0x%x\n",
305 dev_tel
->resource
[ 0].start
, dev_tel
->irq
);
307 printk(KERN_WARNING
"TelesPCI: No PCI card found\n");
311 printk(KERN_WARNING
"HiSax: Teles/PCI and NO_PCI_BIOS\n");
312 printk(KERN_WARNING
"HiSax: Teles/PCI unable to config\n");
314 #endif /* CONFIG_PCI */
316 /* Initialize Zoran PCI controller */
317 writel(0x00000000, cs
->hw
.teles0
.membase
+ 0x28);
318 writel(0x01000000, cs
->hw
.teles0
.membase
+ 0x28);
319 writel(0x01000000, cs
->hw
.teles0
.membase
+ 0x28);
320 writel(0x7BFFFFFF, cs
->hw
.teles0
.membase
+ 0x2C);
321 writel(0x70000000, cs
->hw
.teles0
.membase
+ 0x3C);
322 writel(0x61000000, cs
->hw
.teles0
.membase
+ 0x40);
323 /* writel(0x00800000, cs->hw.teles0.membase + 0x200); */
326 "HiSax: %s config irq:%d mem:%lx\n",
327 CardType
[cs
->typ
], cs
->irq
,
328 cs
->hw
.teles0
.membase
);
330 cs
->readisac
= &ReadISAC
;
331 cs
->writeisac
= &WriteISAC
;
332 cs
->readisacfifo
= &ReadISACfifo
;
333 cs
->writeisacfifo
= &WriteISACfifo
;
334 cs
->BC_Read_Reg
= &ReadHSCX
;
335 cs
->BC_Write_Reg
= &WriteHSCX
;
336 cs
->BC_Send_Data
= &hscx_fill_fifo
;
337 cs
->cardmsg
= &TelesPCI_card_msg
;
338 cs
->irq_func
= &telespci_interrupt
;
339 cs
->irq_flags
|= SA_SHIRQ
;
340 ISACVersion(cs
, "TelesPCI:");
341 if (HscxVersion(cs
, "TelesPCI:")) {
343 "TelesPCI: wrong HSCX versions check IO/MEM addresses\n");
344 release_io_telespci(cs
);