1 /* $Id: teleint.c,v 1.16.2.5 2004/01/19 15:31:50 keil Exp $
3 * low level stuff for TeleInt isdn cards
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
13 #include <linux/init.h>
19 static const char *TeleInt_revision
= "$Revision: 1.16.2.5 $";
21 #define byteout(addr,val) outb(val,addr)
22 #define bytein(addr) inb(addr)
25 readreg(unsigned int ale
, unsigned int adr
, u_char off
)
31 ret
= HFC_BUSY
& bytein(ale
);
32 while (ret
&& --max_delay
)
33 ret
= HFC_BUSY
& bytein(ale
);
35 printk(KERN_WARNING
"TeleInt Busy not inactive\n");
43 readfifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
46 register int max_delay
= 20000;
50 for (i
= 0; i
<size
; i
++) {
51 ret
= HFC_BUSY
& bytein(ale
);
52 while (ret
&& --max_delay
)
53 ret
= HFC_BUSY
& bytein(ale
);
55 printk(KERN_WARNING
"TeleInt Busy not inactive\n");
58 data
[i
] = bytein(adr
);
64 writereg(unsigned int ale
, unsigned int adr
, u_char off
, u_char data
)
70 ret
= HFC_BUSY
& bytein(ale
);
71 while (ret
&& --max_delay
)
72 ret
= HFC_BUSY
& bytein(ale
);
74 printk(KERN_WARNING
"TeleInt Busy not inactive\n");
81 writefifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
84 register int max_delay
= 20000;
88 for (i
= 0; i
<size
; i
++) {
89 ret
= HFC_BUSY
& bytein(ale
);
90 while (ret
&& --max_delay
)
91 ret
= HFC_BUSY
& bytein(ale
);
93 printk(KERN_WARNING
"TeleInt Busy not inactive\n");
96 byteout(adr
, data
[i
]);
100 /* Interface functions */
103 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
105 cs
->hw
.hfc
.cip
= offset
;
106 return (readreg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, offset
));
110 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
112 cs
->hw
.hfc
.cip
= offset
;
113 writereg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, offset
, value
);
117 ReadISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
120 readfifo(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, 0, data
, size
);
124 WriteISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
127 writefifo(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, 0, data
, size
);
131 ReadHFC(struct IsdnCardState
*cs
, int data
, u_char reg
)
136 cs
->hw
.hfc
.cip
= reg
;
137 byteout(cs
->hw
.hfc
.addr
| 1, reg
);
138 ret
= bytein(cs
->hw
.hfc
.addr
);
139 if (cs
->debug
& L1_DEB_HSCX_FIFO
&& (data
!= 2))
140 debugl1(cs
, "hfc RD %02x %02x", reg
, ret
);
142 ret
= bytein(cs
->hw
.hfc
.addr
| 1);
147 WriteHFC(struct IsdnCardState
*cs
, int data
, u_char reg
, u_char value
)
149 byteout(cs
->hw
.hfc
.addr
| 1, reg
);
150 cs
->hw
.hfc
.cip
= reg
;
152 byteout(cs
->hw
.hfc
.addr
, value
);
153 if (cs
->debug
& L1_DEB_HSCX_FIFO
&& (data
!= 2))
154 debugl1(cs
, "hfc W%c %02x %02x", data
? 'D' : 'C', reg
, value
);
158 TeleInt_interrupt(int intno
, void *dev_id
)
160 struct IsdnCardState
*cs
= dev_id
;
164 spin_lock_irqsave(&cs
->lock
, flags
);
165 val
= readreg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_ISTA
);
168 isac_interrupt(cs
, val
);
169 val
= readreg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_ISTA
);
171 if (cs
->debug
& L1_DEB_ISAC
)
172 debugl1(cs
, "ISAC IntStat after IntRoutine");
175 writereg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_MASK
, 0xFF);
176 writereg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_MASK
, 0x0);
177 spin_unlock_irqrestore(&cs
->lock
, flags
);
182 TeleInt_Timer(struct IsdnCardState
*cs
)
187 spin_lock_irqsave(&cs
->lock
, flags
);
188 if (cs
->bcs
[0].mode
) {
190 main_irq_hfc(&cs
->bcs
[0]);
192 if (cs
->bcs
[1].mode
) {
194 main_irq_hfc(&cs
->bcs
[1]);
196 spin_unlock_irqrestore(&cs
->lock
, flags
);
200 cs
->hw
.hfc
.timer
.expires
= jiffies
+ stat
;
201 add_timer(&cs
->hw
.hfc
.timer
);
205 release_io_TeleInt(struct IsdnCardState
*cs
)
207 del_timer(&cs
->hw
.hfc
.timer
);
210 release_region(cs
->hw
.hfc
.addr
, 2);
214 reset_TeleInt(struct IsdnCardState
*cs
)
216 printk(KERN_INFO
"TeleInt: resetting card\n");
217 cs
->hw
.hfc
.cirm
|= HFC_RESET
;
218 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.cirm
); /* Reset On */
220 cs
->hw
.hfc
.cirm
&= ~HFC_RESET
;
221 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.cirm
); /* Reset Off */
226 TeleInt_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
233 spin_lock_irqsave(&cs
->lock
, flags
);
235 spin_unlock_irqrestore(&cs
->lock
, flags
);
238 release_io_TeleInt(cs
);
241 spin_lock_irqsave(&cs
->lock
, flags
);
244 clear_pending_isac_ints(cs
);
246 /* Reenable all IRQ */
247 cs
->writeisac(cs
, ISAC_MASK
, 0);
248 cs
->writeisac(cs
, ISAC_CMDR
, 0x41);
249 spin_unlock_irqrestore(&cs
->lock
, flags
);
253 cs
->hw
.hfc
.timer
.expires
= jiffies
+ delay
;
254 add_timer(&cs
->hw
.hfc
.timer
);
263 setup_TeleInt(struct IsdnCard
*card
)
265 struct IsdnCardState
*cs
= card
->cs
;
268 strcpy(tmp
, TeleInt_revision
);
269 printk(KERN_INFO
"HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp
));
270 if (cs
->typ
!= ISDN_CTYPE_TELEINT
)
273 cs
->hw
.hfc
.addr
= card
->para
[1] & 0x3fe;
274 cs
->irq
= card
->para
[0];
275 cs
->hw
.hfc
.cirm
= HFC_CIRM
;
276 cs
->hw
.hfc
.isac_spcr
= 0x00;
278 cs
->hw
.hfc
.ctmt
= HFC_CTMT
| HFC_CLTIMER
;
279 cs
->bcs
[0].hw
.hfc
.send
= NULL
;
280 cs
->bcs
[1].hw
.hfc
.send
= NULL
;
281 cs
->hw
.hfc
.fifosize
= 7 * 1024 + 512;
282 cs
->hw
.hfc
.timer
.function
= (void *) TeleInt_Timer
;
283 cs
->hw
.hfc
.timer
.data
= (long) cs
;
284 init_timer(&cs
->hw
.hfc
.timer
);
285 if (!request_region(cs
->hw
.hfc
.addr
, 2, "TeleInt isdn")) {
287 "HiSax: TeleInt config port %x-%x already in use\n",
289 cs
->hw
.hfc
.addr
+ 2);
293 byteout(cs
->hw
.hfc
.addr
, cs
->hw
.hfc
.addr
& 0xff);
294 byteout(cs
->hw
.hfc
.addr
| 1, ((cs
->hw
.hfc
.addr
& 0x300) >> 8) | 0x54);
297 cs
->hw
.hfc
.cirm
|= HFC_INTA
;
300 cs
->hw
.hfc
.cirm
|= HFC_INTB
;
303 cs
->hw
.hfc
.cirm
|= HFC_INTC
;
306 cs
->hw
.hfc
.cirm
|= HFC_INTD
;
309 cs
->hw
.hfc
.cirm
|= HFC_INTE
;
312 cs
->hw
.hfc
.cirm
|= HFC_INTF
;
315 printk(KERN_WARNING
"TeleInt: wrong IRQ\n");
316 release_io_TeleInt(cs
);
319 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.cirm
);
320 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.ctmt
);
322 printk(KERN_INFO
"TeleInt: defined at 0x%x IRQ %d\n",
323 cs
->hw
.hfc
.addr
, cs
->irq
);
326 cs
->readisac
= &ReadISAC
;
327 cs
->writeisac
= &WriteISAC
;
328 cs
->readisacfifo
= &ReadISACfifo
;
329 cs
->writeisacfifo
= &WriteISACfifo
;
330 cs
->BC_Read_Reg
= &ReadHFC
;
331 cs
->BC_Write_Reg
= &WriteHFC
;
332 cs
->cardmsg
= &TeleInt_card_msg
;
333 cs
->irq_func
= &TeleInt_interrupt
;
334 ISACVersion(cs
, "TeleInt:");