Merge with Linux 2.4.0-test6-pre9.
[linux-2.6/linux-mips.git] / drivers / isdn / hisax / telespci.c
blob856b73fd9f4f0d5ed38e6cbd27320853e8592102
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>
13 #include "hisax.h"
14 #include "isac.h"
15 #include "hscx.h"
16 #include "isdnl1.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)
41 static inline u_char
42 readisac(unsigned long adr, u_char off)
44 register unsigned int portdata;
46 ZORAN_WAIT_NOBUSY;
48 /* set address for ISAC */
49 writel(WRITE_ADDR_ISAC | off, adr + 0x200);
50 ZORAN_WAIT_NOBUSY;
52 /* read data from ISAC */
53 writel(READ_DATA_ISAC, adr + 0x200);
54 ZORAN_WAIT_NOBUSY;
55 return((u_char)(portdata & ZORAN_PO_DMASK));
58 static inline void
59 writeisac(unsigned long adr, u_char off, u_char data)
61 register unsigned int portdata;
63 ZORAN_WAIT_NOBUSY;
65 /* set address for ISAC */
66 writel(WRITE_ADDR_ISAC | off, adr + 0x200);
67 ZORAN_WAIT_NOBUSY;
69 /* write data to ISAC */
70 writel(WRITE_DATA_ISAC | data, adr + 0x200);
71 ZORAN_WAIT_NOBUSY;
74 static inline u_char
75 readhscx(unsigned long adr, int hscx, u_char off)
77 register unsigned int portdata;
79 ZORAN_WAIT_NOBUSY;
80 /* set address for HSCX */
81 writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
82 ZORAN_WAIT_NOBUSY;
84 /* read data from HSCX */
85 writel(READ_DATA_HSCX, adr + 0x200);
86 ZORAN_WAIT_NOBUSY;
87 return ((u_char)(portdata & ZORAN_PO_DMASK));
90 static inline void
91 writehscx(unsigned long adr, int hscx, u_char off, u_char data)
93 register unsigned int portdata;
95 ZORAN_WAIT_NOBUSY;
96 /* set address for HSCX */
97 writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
98 ZORAN_WAIT_NOBUSY;
100 /* write data to HSCX */
101 writel(WRITE_DATA_HSCX | data, adr + 0x200);
102 ZORAN_WAIT_NOBUSY;
105 static inline void
106 read_fifo_isac(unsigned long adr, u_char * data, int size)
108 register unsigned int portdata;
109 register int i;
111 ZORAN_WAIT_NOBUSY;
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);
116 ZORAN_WAIT_NOBUSY;
117 writel(READ_DATA_ISAC, adr + 0x200);
118 ZORAN_WAIT_NOBUSY;
119 data[i] = (u_char)(portdata & ZORAN_PO_DMASK);
123 static void
124 write_fifo_isac(unsigned long adr, u_char * data, int size)
126 register unsigned int portdata;
127 register int i;
129 ZORAN_WAIT_NOBUSY;
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);
134 ZORAN_WAIT_NOBUSY;
135 writel(WRITE_DATA_ISAC | data[i], adr + 0x200);
136 ZORAN_WAIT_NOBUSY;
140 static inline void
141 read_fifo_hscx(unsigned long adr, int hscx, u_char * data, int size)
143 register unsigned int portdata;
144 register int i;
146 ZORAN_WAIT_NOBUSY;
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);
151 ZORAN_WAIT_NOBUSY;
152 writel(READ_DATA_HSCX, adr + 0x200);
153 ZORAN_WAIT_NOBUSY;
154 data[i] = (u_char) (portdata & ZORAN_PO_DMASK);
158 static inline void
159 write_fifo_hscx(unsigned long adr, int hscx, u_char * data, int size)
161 unsigned int portdata;
162 register int i;
164 ZORAN_WAIT_NOBUSY;
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);
169 ZORAN_WAIT_NOBUSY;
170 writel(WRITE_DATA_HSCX | data[i], adr + 0x200);
171 ZORAN_WAIT_NOBUSY;
172 udelay(10);
176 /* Interface functions */
178 static u_char
179 ReadISAC(struct IsdnCardState *cs, u_char offset)
181 return (readisac(cs->hw.teles0.membase, offset));
184 static void
185 WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
187 writeisac(cs->hw.teles0.membase, offset, value);
190 static void
191 ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
193 read_fifo_isac(cs->hw.teles0.membase, data, size);
196 static void
197 WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
199 write_fifo_isac(cs->hw.teles0.membase, data, size);
202 static u_char
203 ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
205 return (readhscx(cs->hw.teles0.membase, hscx, offset));
208 static void
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"
225 static void
226 telespci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
228 #define MAXCOUNT 20
229 struct IsdnCardState *cs = dev_id;
230 u_char val;
232 if (!cs) {
233 printk(KERN_WARNING "TelesPCI: Spurious interrupt!\n");
234 return;
236 val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA);
237 if (val)
238 hscx_int_main(cs, val);
239 val = readisac(cs->hw.teles0.membase, ISAC_ISTA);
240 if (val)
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);
253 void
254 release_io_telespci(struct IsdnCardState *cs)
256 iounmap((void *)cs->hw.teles0.membase);
259 static int
260 TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg)
262 switch (mt) {
263 case CARD_RESET:
264 return(0);
265 case CARD_RELEASE:
266 release_io_telespci(cs);
267 return(0);
268 case CARD_INIT:
269 inithscxisac(cs, 3);
270 return(0);
271 case CARD_TEST:
272 return(0);
274 return(0);
277 static struct pci_dev *dev_tel __initdata = NULL;
279 __initfunc(int
280 setup_telespci(struct IsdnCard *card))
282 struct IsdnCardState *cs = card->cs;
283 char tmp[64];
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)
288 return (0);
289 #if CONFIG_PCI
290 if (!pci_present()) {
291 printk(KERN_ERR "TelesPCI: no PCI bus present\n");
292 return(0);
294 if ((dev_tel = pci_find_device (0x11DE, 0x6120, dev_tel))) {
295 if (pci_enable_device(dev_tel))
296 return (0);
297 cs->irq = dev_tel->irq;
298 if (!cs->irq) {
299 printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
300 return(0);
302 cs->hw.teles0.membase = (u_long) ioremap(dev_tel->resource[ 0].start,
303 PAGE_SIZE);
304 printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n",
305 dev_tel->resource[ 0].start, dev_tel->irq);
306 } else {
307 printk(KERN_WARNING "TelesPCI: No PCI card found\n");
308 return(0);
310 #else
311 printk(KERN_WARNING "HiSax: Teles/PCI and NO_PCI_BIOS\n");
312 printk(KERN_WARNING "HiSax: Teles/PCI unable to config\n");
313 return (0);
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); */
325 printk(KERN_INFO
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:")) {
342 printk(KERN_WARNING
343 "TelesPCI: wrong HSCX versions check IO/MEM addresses\n");
344 release_io_telespci(cs);
345 return (0);
347 return (1);