1 /* $Id: teles0.c,v 2.13.6.2 2001/09/23 22:24:52 kai Exp $
3 * low level stuff for Teles Memory IO isdn cards
6 * based on the teles driver from Jan den Ouden
7 * Copyright by Karsten Keil <keil@isdn4linux.de>
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
12 * Thanks to Jan den Ouden
18 #include <linux/init.h>
24 extern const char *CardType
[];
26 const char *teles0_revision
= "$Revision: 2.13.6.2 $";
28 #define TELES_IOMEM_SIZE 0x400
29 #define byteout(addr,val) outb(val,addr)
30 #define bytein(addr) inb(addr)
33 isac_read(struct IsdnCardState
*cs
, u8 off
)
35 return readb(cs
->hw
.teles0
.membase
+
36 ((off
& 1) ? 0x2ff : 0x100) + off
);
40 isac_write(struct IsdnCardState
*cs
, u8 off
, u8 data
)
42 writeb(data
, cs
->hw
.teles0
.membase
+
43 ((off
& 1) ? 0x2ff : 0x100) + off
); mb();
48 isac_read_fifo(struct IsdnCardState
*cs
, u8
* data
, int size
)
51 void *ad
= cs
->hw
.teles0
.membase
+ 0x100;
52 for (i
= 0; i
< size
; i
++)
57 isac_write_fifo(struct IsdnCardState
*cs
, u8
* data
, int size
)
60 void *ad
= cs
->hw
.teles0
.membase
+ 0x100;
61 for (i
= 0; i
< size
; i
++) {
62 writeb(data
[i
], ad
); mb();
66 static struct dc_hw_ops isac_ops
= {
67 .read_reg
= isac_read
,
68 .write_reg
= isac_write
,
69 .read_fifo
= isac_read_fifo
,
70 .write_fifo
= isac_write_fifo
,
74 hscx_read(struct IsdnCardState
*cs
, int hscx
, u8 off
)
76 return readb(cs
->hw
.teles0
.membase
+ (hscx
? 0x1c0 : 0x180) +
77 ((off
& 1) ? 0x1ff : 0) + off
);
81 hscx_write(struct IsdnCardState
*cs
, int hscx
, u8 off
, u8 data
)
83 writeb(data
, cs
->hw
.teles0
.membase
+ (hscx
? 0x1c0 : 0x180) +
84 ((off
& 1) ? 0x1ff : 0) + off
); mb();
88 hscx_read_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int size
)
91 void *ad
= cs
->hw
.teles0
.membase
+ (hscx
? 0x1c0 : 0x180);
92 for (i
= 0; i
< size
; i
++)
97 hscx_write_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int size
)
100 void *ad
= cs
->hw
.teles0
.membase
+ (hscx
? 0x1c0 : 0x180);
101 for (i
= 0; i
< size
; i
++) {
106 static struct bc_hw_ops hscx_ops
= {
107 .read_reg
= hscx_read
,
108 .write_reg
= hscx_write
,
109 .read_fifo
= hscx_read_fifo
,
110 .write_fifo
= hscx_write_fifo
,
114 teles0_reset(struct IsdnCardState
*cs
)
118 if (cs
->hw
.teles0
.cfg_reg
) {
148 cfval
|= ((cs
->hw
.teles0
.phymem
>> 9) & 0xF0);
149 byteout(cs
->hw
.teles0
.cfg_reg
+ 4, cfval
);
150 HZDELAY(HZ
/ 10 + 1);
151 byteout(cs
->hw
.teles0
.cfg_reg
+ 4, cfval
| 1);
152 HZDELAY(HZ
/ 10 + 1);
154 writeb(0, cs
->hw
.teles0
.membase
+ 0x80); mb();
156 writeb(1, cs
->hw
.teles0
.membase
+ 0x80); mb();
161 static struct card_ops teles0_ops
= {
162 .init
= inithscxisac
,
163 .reset
= teles0_reset
,
164 .release
= hisax_release_resources
,
165 .irq_func
= hscxisac_irq
,
169 teles0_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
171 cs
->irq
= card
->para
[0];
172 /* 16.0 and 8.0 designed for IOM1 */
173 test_and_set_bit(HW_IOM1
, &cs
->HW_Flags
);
174 cs
->hw
.teles0
.phymem
= card
->para
[1];
175 cs
->hw
.teles0
.membase
= request_mmio(&cs
->rs
, cs
->hw
.teles0
.phymem
,
176 TELES_IOMEM_SIZE
, "teles iomem");
177 if (!cs
->hw
.teles0
.membase
)
180 if (teles0_reset(cs
)) {
181 printk(KERN_WARNING
"Teles0: wrong IRQ\n");
184 cs
->card_ops
= &teles0_ops
;
185 if (hscxisac_setup(cs
, &isac_ops
, &hscx_ops
))
192 teles16_0_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
196 cs
->hw
.teles0
.cfg_reg
= card
->para
[2];
197 if (!request_io(&cs
->rs
, cs
->hw
.teles0
.cfg_reg
, 8, "teles cfg"))
200 if ((val
= bytein(cs
->hw
.teles0
.cfg_reg
+ 0)) != 0x51) {
201 printk(KERN_WARNING
"Teles0: 16.0 Byte at %x is %x\n",
202 cs
->hw
.teles0
.cfg_reg
+ 0, val
);
205 if ((val
= bytein(cs
->hw
.teles0
.cfg_reg
+ 1)) != 0x93) {
206 printk(KERN_WARNING
"Teles0: 16.0 Byte at %x is %x\n",
207 cs
->hw
.teles0
.cfg_reg
+ 1, val
);
210 val
= bytein(cs
->hw
.teles0
.cfg_reg
+ 2);/* 0x1e=without AB
214 if (val
!= 0x1e && val
!= 0x1f) {
215 printk(KERN_WARNING
"Teles0: 16.0 Byte at %x is %x\n",
216 cs
->hw
.teles0
.cfg_reg
+ 2, val
);
219 if (teles0_probe(cs
, card
) < 0)
224 hisax_release_resources(cs
);
229 teles8_0_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
231 cs
->hw
.teles0
.cfg_reg
= 0;
233 if (teles0_probe(cs
, card
) < 0)
238 hisax_release_resources(cs
);
243 setup_teles0(struct IsdnCard
*card
)
247 strcpy(tmp
, teles0_revision
);
248 printk(KERN_INFO
"HiSax: Teles 8.0/16.0 driver Rev. %s\n",
251 if (card
->cs
->typ
== ISDN_CTYPE_16_0
) {
252 if (teles16_0_probe(card
->cs
, card
) < 0)
255 if (teles8_0_probe(card
->cs
, card
) < 0)