1 /* $Id: telespci.c,v 1.1.1.1 2005/04/11 02:50:24 jack 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 #define __NO_VERSION__
16 #include <linux/init.h>
17 #include <linux/config.h>
22 #include <linux/pci.h>
24 extern const char *CardType[];
25 const char *telespci_revision = "$Revision: 1.1.1.1 $";
27 #define ZORAN_PO_RQ_PEN 0x02000000
28 #define ZORAN_PO_WR 0x00800000
29 #define ZORAN_PO_GID0 0x00000000
30 #define ZORAN_PO_GID1 0x00100000
31 #define ZORAN_PO_GREG0 0x00000000
32 #define ZORAN_PO_GREG1 0x00010000
33 #define ZORAN_PO_DMASK 0xFF
35 #define WRITE_ADDR_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG0)
36 #define READ_DATA_ISAC (ZORAN_PO_GID0 | ZORAN_PO_GREG1)
37 #define WRITE_DATA_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG1)
38 #define WRITE_ADDR_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG0)
39 #define READ_DATA_HSCX (ZORAN_PO_GID1 | ZORAN_PO_GREG1)
40 #define WRITE_DATA_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG1)
42 #define ZORAN_WAIT_NOBUSY do { \
43 portdata = readl(adr + 0x200); \
44 } while (portdata & ZORAN_PO_RQ_PEN)
47 readisac(unsigned long adr, u_char off)
49 register unsigned int portdata;
53 /* set address for ISAC */
54 writel(WRITE_ADDR_ISAC | off, adr + 0x200);
57 /* read data from ISAC */
58 writel(READ_DATA_ISAC, adr + 0x200);
60 return((u_char)(portdata & ZORAN_PO_DMASK));
64 writeisac(unsigned long adr, u_char off, u_char data)
66 register unsigned int portdata;
70 /* set address for ISAC */
71 writel(WRITE_ADDR_ISAC | off, adr + 0x200);
74 /* write data to ISAC */
75 writel(WRITE_DATA_ISAC | data, adr + 0x200);
80 readhscx(unsigned long adr, int hscx, u_char off)
82 register unsigned int portdata;
85 /* set address for HSCX */
86 writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
89 /* read data from HSCX */
90 writel(READ_DATA_HSCX, adr + 0x200);
92 return ((u_char)(portdata & ZORAN_PO_DMASK));
96 writehscx(unsigned long adr, int hscx, u_char off, u_char data)
98 register unsigned int portdata;
101 /* set address for HSCX */
102 writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
105 /* write data to HSCX */
106 writel(WRITE_DATA_HSCX | data, adr + 0x200);
111 read_fifo_isac(unsigned long adr, u_char * data, int size)
113 register unsigned int portdata;
117 /* read data from ISAC */
118 for (i = 0; i < size; i++) {
119 /* set address for ISAC fifo */
120 writel(WRITE_ADDR_ISAC | 0x1E, adr + 0x200);
122 writel(READ_DATA_ISAC, adr + 0x200);
124 data[i] = (u_char)(portdata & ZORAN_PO_DMASK);
129 write_fifo_isac(unsigned long adr, u_char * data, int size)
131 register unsigned int portdata;
135 /* write data to ISAC */
136 for (i = 0; i < size; i++) {
137 /* set address for ISAC fifo */
138 writel(WRITE_ADDR_ISAC | 0x1E, adr + 0x200);
140 writel(WRITE_DATA_ISAC | data[i], adr + 0x200);
146 read_fifo_hscx(unsigned long adr, int hscx, u_char * data, int size)
148 register unsigned int portdata;
152 /* read data from HSCX */
153 for (i = 0; i < size; i++) {
154 /* set address for HSCX fifo */
155 writel(WRITE_ADDR_HSCX |(hscx ? 0x5F:0x1F), adr + 0x200);
157 writel(READ_DATA_HSCX, adr + 0x200);
159 data[i] = (u_char) (portdata & ZORAN_PO_DMASK);
164 write_fifo_hscx(unsigned long adr, int hscx, u_char * data, int size)
166 unsigned int portdata;
170 /* write data to HSCX */
171 for (i = 0; i < size; i++) {
172 /* set address for HSCX fifo */
173 writel(WRITE_ADDR_HSCX |(hscx ? 0x5F:0x1F), adr + 0x200);
175 writel(WRITE_DATA_HSCX | data[i], adr + 0x200);
181 /* Interface functions */
184 ReadISAC(struct IsdnCardState *cs, u_char offset)
186 return (readisac(cs->hw.teles0.membase, offset));
190 WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
192 writeisac(cs->hw.teles0.membase, offset, value);
196 ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
198 read_fifo_isac(cs->hw.teles0.membase, data, size);
202 WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
204 write_fifo_isac(cs->hw.teles0.membase, data, size);
208 ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
210 return (readhscx(cs->hw.teles0.membase, hscx, offset));
214 WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
216 writehscx(cs->hw.teles0.membase, hscx, offset, value);
220 * fast interrupt HSCX stuff goes here
223 #define READHSCX(cs, nr, reg) readhscx(cs->hw.teles0.membase, nr, reg)
224 #define WRITEHSCX(cs, nr, reg, data) writehscx(cs->hw.teles0.membase, nr, reg, data)
225 #define READHSCXFIFO(cs, nr, ptr, cnt) read_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)
226 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) write_fifo_hscx(cs->hw.teles0.membase, nr, ptr, cnt)
228 #include "hscx_irq.c"
231 telespci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
234 struct IsdnCardState *cs = dev_id;
238 printk(KERN_WARNING "TelesPCI: Spurious interrupt!\n");
241 val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA);
243 hscx_int_main(cs, val);
244 val = readisac(cs->hw.teles0.membase, ISAC_ISTA);
246 isac_interrupt(cs, val);
247 /* Clear interrupt register for Zoran PCI controller */
248 writel(0x70000000, cs->hw.teles0.membase + 0x3C);
250 writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF);
251 writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF);
252 writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF);
253 writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0);
254 writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0);
255 writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0);
259 release_io_telespci(struct IsdnCardState *cs)
261 iounmap((void *)cs->hw.teles0.membase);
265 TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg)
271 release_io_telespci(cs);
282 static struct pci_dev *dev_tel __initdata = NULL;
285 setup_telespci(struct IsdnCard *card)
287 struct IsdnCardState *cs = card->cs;
291 #error "not running on big endian machines now"
293 strcpy(tmp, telespci_revision);
294 printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp));
295 if (cs->typ != ISDN_CTYPE_TELESPCI)
298 if (!pci_present()) {
299 printk(KERN_ERR "TelesPCI: no PCI bus present\n");
302 if ((dev_tel = pci_find_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) {
303 if (pci_enable_device(dev_tel))
305 cs->irq = dev_tel->irq;
307 printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
310 cs->hw.teles0.membase = (u_long) ioremap(pci_resource_start(dev_tel, 0),
312 printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n",
313 pci_resource_start(dev_tel, 0), dev_tel->irq);
315 printk(KERN_WARNING "TelesPCI: No PCI card found\n");
319 printk(KERN_WARNING "HiSax: Teles/PCI and NO_PCI_BIOS\n");
320 printk(KERN_WARNING "HiSax: Teles/PCI unable to config\n");
322 #endif /* CONFIG_PCI */
324 /* Initialize Zoran PCI controller */
325 writel(0x00000000, cs->hw.teles0.membase + 0x28);
326 writel(0x01000000, cs->hw.teles0.membase + 0x28);
327 writel(0x01000000, cs->hw.teles0.membase + 0x28);
328 writel(0x7BFFFFFF, cs->hw.teles0.membase + 0x2C);
329 writel(0x70000000, cs->hw.teles0.membase + 0x3C);
330 writel(0x61000000, cs->hw.teles0.membase + 0x40);
331 /* writel(0x00800000, cs->hw.teles0.membase + 0x200); */
334 "HiSax: %s config irq:%d mem:%lx\n",
335 CardType[cs->typ], cs->irq,
336 cs->hw.teles0.membase);
338 cs->readisac = &ReadISAC;
339 cs->writeisac = &WriteISAC;
340 cs->readisacfifo = &ReadISACfifo;
341 cs->writeisacfifo = &WriteISACfifo;
342 cs->BC_Read_Reg = &ReadHSCX;
343 cs->BC_Write_Reg = &WriteHSCX;
344 cs->BC_Send_Data = &hscx_fill_fifo;
345 cs->cardmsg = &TelesPCI_card_msg;
346 cs->irq_func = &telespci_interrupt;
347 cs->irq_flags |= SA_SHIRQ;
348 ISACVersion(cs, "TelesPCI:");
349 if (HscxVersion(cs, "TelesPCI:")) {
351 "TelesPCI: wrong HSCX versions check IO/MEM addresses\n");
352 release_io_telespci(cs);