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 extern const char *CardType[];
23 static const char *telespci_revision = "$Revision: 2.23.2.3 $";
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
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)
40 #define ZORAN_WAIT_NOBUSY do { \
41 portdata = readl(adr + 0x200); \
42 } while (portdata & ZORAN_PO_RQ_PEN)
45 readisac(void __iomem *adr, u_char off)
47 register unsigned int portdata;
51 /* set address for ISAC */
52 writel(WRITE_ADDR_ISAC | off, adr + 0x200);
55 /* read data from ISAC */
56 writel(READ_DATA_ISAC, adr + 0x200);
58 return((u_char)(portdata & ZORAN_PO_DMASK));
62 writeisac(void __iomem *adr, u_char off, u_char data)
64 register unsigned int portdata;
68 /* set address for ISAC */
69 writel(WRITE_ADDR_ISAC | off, adr + 0x200);
72 /* write data to ISAC */
73 writel(WRITE_DATA_ISAC | data, adr + 0x200);
78 readhscx(void __iomem *adr, int hscx, u_char off)
80 register unsigned int portdata;
83 /* set address for HSCX */
84 writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
87 /* read data from HSCX */
88 writel(READ_DATA_HSCX, adr + 0x200);
90 return ((u_char)(portdata & ZORAN_PO_DMASK));
94 writehscx(void __iomem *adr, int hscx, u_char off, u_char data)
96 register unsigned int portdata;
99 /* set address for HSCX */
100 writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
103 /* write data to HSCX */
104 writel(WRITE_DATA_HSCX | data, adr + 0x200);
109 read_fifo_isac(void __iomem *adr, u_char * data, int size)
111 register unsigned int portdata;
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);
120 writel(READ_DATA_ISAC, adr + 0x200);
122 data[i] = (u_char)(portdata & ZORAN_PO_DMASK);
127 write_fifo_isac(void __iomem *adr, u_char * data, int size)
129 register unsigned int portdata;
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);
138 writel(WRITE_DATA_ISAC | data[i], adr + 0x200);
144 read_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
146 register unsigned int portdata;
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);
155 writel(READ_DATA_HSCX, adr + 0x200);
157 data[i] = (u_char) (portdata & ZORAN_PO_DMASK);
162 write_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
164 unsigned int portdata;
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);
173 writel(WRITE_DATA_HSCX | data[i], adr + 0x200);
179 /* Interface functions */
182 ReadISAC(struct IsdnCardState *cs, u_char offset)
184 return (readisac(cs->hw.teles0.membase, offset));
188 WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
190 writeisac(cs->hw.teles0.membase, offset, value);
194 ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
196 read_fifo_isac(cs->hw.teles0.membase, data, size);
200 WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
202 write_fifo_isac(cs->hw.teles0.membase, data, size);
206 ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
208 return (readhscx(cs->hw.teles0.membase, hscx, offset));
212 WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
214 writehscx(cs->hw.teles0.membase, hscx, offset, value);
218 * fast interrupt HSCX stuff goes here
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)
226 #include "hscx_irq.c"
229 telespci_interrupt(int intno, void *dev_id)
231 struct IsdnCardState *cs = dev_id;
235 spin_lock_irqsave(&cs->lock, flags);
236 hval = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA);
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);
245 isac_interrupt(cs, ival);
246 /* Clear interrupt register for Zoran PCI controller */
247 writel(0x70000000, cs->hw.teles0.membase + 0x3C);
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);
260 release_io_telespci(struct IsdnCardState *cs)
262 iounmap(cs->hw.teles0.membase);
266 TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg)
274 release_io_telespci(cs);
277 spin_lock_irqsave(&cs->lock, flags);
279 spin_unlock_irqrestore(&cs->lock, flags);
287 static struct pci_dev *dev_tel __devinitdata = NULL;
290 setup_telespci(struct IsdnCard *card)
292 struct IsdnCardState *cs = card->cs;
296 #error "not running on big endian machines now"
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)
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))
307 cs->irq = dev_tel->irq;
309 printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
312 cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0),
314 printk(KERN_INFO "Found: Zoran, base-address: 0x%llx, irq: 0x%x\n",
315 (unsigned long long)pci_resource_start(dev_tel, 0),
318 printk(KERN_WARNING "TelesPCI: No PCI card found\n");
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); */
332 "HiSax: %s config irq:%d mem:%p\n",
333 CardType[cs->typ], cs->irq,
334 cs->hw.teles0.membase);
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:")) {
350 "TelesPCI: wrong HSCX versions check IO/MEM addresses\n");
351 release_io_telespci(cs);