1 /* $Id: telespci.c,v 2.16.6.5 2001/09/23 22:24:52 kai 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>
16 #include <linux/config.h>
21 #include <linux/pci.h>
23 extern const char *CardType
[];
24 const char *telespci_revision
= "$Revision: 2.16.6.5 $";
26 #define ZORAN_PO_RQ_PEN 0x02000000
27 #define ZORAN_PO_WR 0x00800000
28 #define ZORAN_PO_GID0 0x00000000
29 #define ZORAN_PO_GID1 0x00100000
30 #define ZORAN_PO_GREG0 0x00000000
31 #define ZORAN_PO_GREG1 0x00010000
32 #define ZORAN_PO_DMASK 0xFF
34 #define WRITE_ADDR_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG0)
35 #define READ_DATA_ISAC (ZORAN_PO_GID0 | ZORAN_PO_GREG1)
36 #define WRITE_DATA_ISAC (ZORAN_PO_WR | ZORAN_PO_GID0 | ZORAN_PO_GREG1)
37 #define WRITE_ADDR_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG0)
38 #define READ_DATA_HSCX (ZORAN_PO_GID1 | ZORAN_PO_GREG1)
39 #define WRITE_DATA_HSCX (ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG1)
41 #define ZORAN_WAIT_NOBUSY do { \
42 portdata = readl(adr); \
43 } while (portdata & ZORAN_PO_RQ_PEN)
46 isac_read(struct IsdnCardState
*cs
, u8 off
)
48 void *adr
= cs
->hw
.teles0
.membase
+ 0x200;
49 unsigned int portdata
;
53 /* set address for ISAC */
54 writel(WRITE_ADDR_ISAC
| off
, adr
);
57 /* read data from ISAC */
58 writel(READ_DATA_ISAC
, adr
);
60 return((u8
)(portdata
& ZORAN_PO_DMASK
));
64 isac_write(struct IsdnCardState
*cs
, u8 off
, u8 data
)
66 void *adr
= cs
->hw
.teles0
.membase
+ 0x200;
67 unsigned int portdata
;
71 /* set address for ISAC */
72 writel(WRITE_ADDR_ISAC
| off
, adr
);
75 /* write data to ISAC */
76 writel(WRITE_DATA_ISAC
| data
, adr
);
81 isac_read_fifo(struct IsdnCardState
*cs
, u8
*data
, int size
)
83 void *adr
= cs
->hw
.teles0
.membase
+ 0x200;
84 unsigned int portdata
;
88 /* read data from ISAC */
89 for (i
= 0; i
< size
; i
++) {
90 /* set address for ISAC fifo */
91 writel(WRITE_ADDR_ISAC
| 0x1E, adr
);
93 writel(READ_DATA_ISAC
, adr
);
95 data
[i
] = (u8
)(portdata
& ZORAN_PO_DMASK
);
100 isac_write_fifo(struct IsdnCardState
*cs
, u8
*data
, int size
)
102 void *adr
= cs
->hw
.teles0
.membase
+ 0x200;
103 unsigned int portdata
;
107 /* write data to ISAC */
108 for (i
= 0; i
< size
; i
++) {
109 /* set address for ISAC fifo */
110 writel(WRITE_ADDR_ISAC
| 0x1E, adr
);
112 writel(WRITE_DATA_ISAC
| data
[i
], adr
);
117 static struct dc_hw_ops isac_ops
= {
118 .read_reg
= isac_read
,
119 .write_reg
= isac_write
,
120 .read_fifo
= isac_read_fifo
,
121 .write_fifo
= isac_write_fifo
,
125 hscx_read(struct IsdnCardState
*cs
, int hscx
, u8 off
)
127 void *adr
= cs
->hw
.teles0
.membase
+ 0x200;
128 unsigned int portdata
;
131 /* set address for HSCX */
132 writel(WRITE_ADDR_HSCX
| ((hscx
? 0x40:0) + off
), adr
);
135 /* read data from HSCX */
136 writel(READ_DATA_HSCX
, adr
);
138 return ((u8
)(portdata
& ZORAN_PO_DMASK
));
142 hscx_write(struct IsdnCardState
*cs
, int hscx
, u8 off
, u8 data
)
144 void *adr
= cs
->hw
.teles0
.membase
+ 0x200;
145 unsigned int portdata
;
148 /* set address for HSCX */
149 writel(WRITE_ADDR_HSCX
| ((hscx
? 0x40:0) + off
), adr
);
152 /* write data to HSCX */
153 writel(WRITE_DATA_HSCX
| data
, adr
);
158 hscx_read_fifo(struct IsdnCardState
*cs
, int hscx
, u8
* data
, int size
)
160 void *adr
= cs
->hw
.teles0
.membase
+ 0x200;
161 unsigned int portdata
;
165 /* read data from HSCX */
166 for (i
= 0; i
< size
; i
++) {
167 /* set address for HSCX fifo */
168 writel(WRITE_ADDR_HSCX
|(hscx
? 0x5F:0x1F), adr
);
170 writel(READ_DATA_HSCX
, adr
);
172 data
[i
] = (u8
) (portdata
& ZORAN_PO_DMASK
);
177 hscx_write_fifo(struct IsdnCardState
*cs
, int hscx
, u8
* data
, int size
)
179 void *adr
= cs
->hw
.teles0
.membase
+ 0x200;
180 unsigned int portdata
;
184 /* write data to HSCX */
185 for (i
= 0; i
< size
; i
++) {
186 /* set address for HSCX fifo */
187 writel(WRITE_ADDR_HSCX
|(hscx
? 0x5F:0x1F), adr
);
189 writel(WRITE_DATA_HSCX
| data
[i
], adr
);
195 static struct bc_hw_ops hscx_ops
= {
196 .read_reg
= hscx_read
,
197 .write_reg
= hscx_write
,
198 .read_fifo
= hscx_read_fifo
,
199 .write_fifo
= hscx_write_fifo
,
203 telespci_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
206 struct IsdnCardState
*cs
= dev_id
;
209 spin_lock(&cs
->lock
);
210 val
= hscx_read(cs
, 1, HSCX_ISTA
);
212 hscx_int_main(cs
, val
);
213 val
= isac_read(cs
, ISAC_ISTA
);
215 isac_interrupt(cs
, val
);
216 /* Clear interrupt register for Zoran PCI controller */
217 writel(0x70000000, cs
->hw
.teles0
.membase
+ 0x3C);
219 hscx_write(cs
, 0, HSCX_MASK
, 0xFF);
220 hscx_write(cs
, 1, HSCX_MASK
, 0xFF);
221 isac_write(cs
, ISAC_MASK
, 0xFF);
222 isac_write(cs
, ISAC_MASK
, 0x0);
223 hscx_write(cs
, 0, HSCX_MASK
, 0x0);
224 hscx_write(cs
, 1, HSCX_MASK
, 0x0);
225 spin_unlock(&cs
->lock
);
229 static struct card_ops telespci_ops
= {
230 .init
= inithscxisac
,
231 .release
= hisax_release_resources
,
232 .irq_func
= telespci_interrupt
,
236 telespci_probe(struct IsdnCardState
*cs
, struct pci_dev
*pdev
)
240 printk(KERN_INFO
"TelesPCI: defined at %#lx IRQ %d\n",
241 pci_resource_start(pdev
, 0), pdev
->irq
);
244 if (pci_enable_device(pdev
))
248 cs
->irq_flags
|= SA_SHIRQ
;
249 cs
->hw
.teles0
.membase
= request_mmio(&cs
->rs
, pci_resource_start(pdev
, 0), 4096, "telespci");
250 if (!cs
->hw
.teles0
.membase
)
253 /* Initialize Zoran PCI controller */
254 writel(0x00000000, cs
->hw
.teles0
.membase
+ 0x28);
255 writel(0x01000000, cs
->hw
.teles0
.membase
+ 0x28);
256 writel(0x01000000, cs
->hw
.teles0
.membase
+ 0x28);
257 writel(0x7BFFFFFF, cs
->hw
.teles0
.membase
+ 0x2C);
258 writel(0x70000000, cs
->hw
.teles0
.membase
+ 0x3C);
259 writel(0x61000000, cs
->hw
.teles0
.membase
+ 0x40);
260 /* writel(0x00800000, cs->hw.teles0.membase + 0x200); */
262 cs
->card_ops
= &telespci_ops
;
263 if (hscxisac_setup(cs
, &isac_ops
, &hscx_ops
))
267 hisax_release_resources(cs
);
271 static struct pci_dev
*dev_tel __initdata
= NULL
;
274 setup_telespci(struct IsdnCard
*card
)
279 #error "not running on big endian machines now"
281 strcpy(tmp
, telespci_revision
);
282 printk(KERN_INFO
"HiSax: Teles/PCI driver Rev. %s\n",
284 dev_tel
= pci_find_device(PCI_VENDOR_ID_ZORAN
,
285 PCI_DEVICE_ID_ZORAN_36120
, dev_tel
);
287 if (telespci_probe(card
->cs
, dev_tel
) < 0)
291 printk(KERN_WARNING
"TelesPCI: No PCI card found\n");