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
= NULL
;
288 int setup_telespci(struct IsdnCard
*card
)
290 struct IsdnCardState
*cs
= card
->cs
;
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 ((dev_tel
= hisax_find_pci_device(PCI_VENDOR_ID_ZORAN
, PCI_DEVICE_ID_ZORAN_36120
, dev_tel
))) {
299 if (pci_enable_device(dev_tel
))
301 cs
->irq
= dev_tel
->irq
;
303 printk(KERN_WARNING
"Teles: No IRQ for PCI card found\n");
306 cs
->hw
.teles0
.membase
= ioremap(pci_resource_start(dev_tel
, 0),
308 printk(KERN_INFO
"Found: Zoran, base-address: 0x%llx, irq: 0x%x\n",
309 (unsigned long long)pci_resource_start(dev_tel
, 0),
312 printk(KERN_WARNING
"TelesPCI: No PCI card found\n");
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: Teles PCI config irq:%d mem:%p\n",
328 cs
->hw
.teles0
.membase
);
331 cs
->readisac
= &ReadISAC
;
332 cs
->writeisac
= &WriteISAC
;
333 cs
->readisacfifo
= &ReadISACfifo
;
334 cs
->writeisacfifo
= &WriteISACfifo
;
335 cs
->BC_Read_Reg
= &ReadHSCX
;
336 cs
->BC_Write_Reg
= &WriteHSCX
;
337 cs
->BC_Send_Data
= &hscx_fill_fifo
;
338 cs
->cardmsg
= &TelesPCI_card_msg
;
339 cs
->irq_func
= &telespci_interrupt
;
340 cs
->irq_flags
|= IRQF_SHARED
;
341 ISACVersion(cs
, "TelesPCI:");
342 if (HscxVersion(cs
, "TelesPCI:")) {
344 "TelesPCI: wrong HSCX versions check IO/MEM addresses\n");
345 release_io_telespci(cs
);