1 /* $Id: teleint.c,v 1.7 1998/11/15 23:55:26 keil Exp $
3 * teleint.c low level stuff for TeleInt isdn cards
5 * Author Karsten Keil (keil@isdn4linux.de)
9 * Revision 1.7 1998/11/15 23:55:26 keil
12 * Revision 1.6 1998/04/15 16:45:31 keil
15 * Revision 1.5 1998/02/02 13:40:47 keil
18 * Revision 1.4 1997/11/08 21:35:53 keil
21 * Revision 1.3 1997/11/06 17:09:30 keil
24 * Revision 1.2 1997/10/29 18:55:53 keil
25 * changes for 2.1.60 (irq2dev_map)
27 * Revision 1.1 1997/09/11 17:32:32 keil
33 #define __NO_VERSION__
39 extern const char *CardType
[];
41 const char *TeleInt_revision
= "$Revision: 1.7 $";
43 #define byteout(addr,val) outb(val,addr)
44 #define bytein(addr) inb(addr)
47 readreg(unsigned int ale
, unsigned int adr
, u_char off
)
56 ret
= HFC_BUSY
& bytein(ale
);
57 while (ret
&& --max_delay
)
58 ret
= HFC_BUSY
& bytein(ale
);
60 printk(KERN_WARNING
"TeleInt Busy not inaktive\n");
70 readfifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
73 register int max_delay
= 20000;
77 for (i
= 0; i
<size
; i
++) {
78 ret
= HFC_BUSY
& bytein(ale
);
79 while (ret
&& --max_delay
)
80 ret
= HFC_BUSY
& bytein(ale
);
82 printk(KERN_WARNING
"TeleInt Busy not inaktive\n");
85 data
[i
] = bytein(adr
);
91 writereg(unsigned int ale
, unsigned int adr
, u_char off
, u_char data
)
100 ret
= HFC_BUSY
& bytein(ale
);
101 while (ret
&& --max_delay
)
102 ret
= HFC_BUSY
& bytein(ale
);
104 printk(KERN_WARNING
"TeleInt Busy not inaktive\n");
105 restore_flags(flags
);
109 restore_flags(flags
);
113 writefifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
116 register int max_delay
= 20000;
119 /* fifo write without cli because it's allready done */
121 for (i
= 0; i
<size
; i
++) {
122 ret
= HFC_BUSY
& bytein(ale
);
123 while (ret
&& --max_delay
)
124 ret
= HFC_BUSY
& bytein(ale
);
126 printk(KERN_WARNING
"TeleInt Busy not inaktive\n");
129 byteout(adr
, data
[i
]);
133 /* Interface functions */
136 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
138 cs
->hw
.hfc
.cip
= offset
;
139 return (readreg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, offset
));
143 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
145 cs
->hw
.hfc
.cip
= offset
;
146 writereg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, offset
, value
);
150 ReadISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
153 readfifo(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, 0, data
, size
);
157 WriteISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
160 writefifo(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, 0, data
, size
);
164 ReadHFC(struct IsdnCardState
*cs
, int data
, u_char reg
)
169 cs
->hw
.hfc
.cip
= reg
;
170 byteout(cs
->hw
.hfc
.addr
| 1, reg
);
171 ret
= bytein(cs
->hw
.hfc
.addr
);
172 if (cs
->debug
& L1_DEB_HSCX_FIFO
&& (data
!= 2))
173 debugl1(cs
, "hfc RD %02x %02x", reg
, ret
);
175 ret
= bytein(cs
->hw
.hfc
.addr
| 1);
180 WriteHFC(struct IsdnCardState
*cs
, int data
, u_char reg
, u_char value
)
182 byteout(cs
->hw
.hfc
.addr
| 1, reg
);
183 cs
->hw
.hfc
.cip
= reg
;
185 byteout(cs
->hw
.hfc
.addr
, value
);
186 if (cs
->debug
& L1_DEB_HSCX_FIFO
&& (data
!= 2))
187 debugl1(cs
, "hfc W%c %02x %02x", data
? 'D' : 'C', reg
, value
);
191 TeleInt_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
193 struct IsdnCardState
*cs
= dev_id
;
194 u_char val
, stat
= 0;
197 printk(KERN_WARNING
"TeleInt: Spurious interrupt!\n");
200 val
= readreg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_ISTA
);
203 isac_interrupt(cs
, val
);
206 val
= readreg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_ISTA
);
208 if (cs
->debug
& L1_DEB_ISAC
)
209 debugl1(cs
, "ISAC IntStat after IntRoutine");
213 writereg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_MASK
, 0xFF);
214 writereg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_MASK
, 0x0);
219 TeleInt_Timer(struct IsdnCardState
*cs
)
223 if (cs
->bcs
[0].mode
) {
225 main_irq_hfc(&cs
->bcs
[0]);
227 if (cs
->bcs
[1].mode
) {
229 main_irq_hfc(&cs
->bcs
[1]);
231 cs
->hw
.hfc
.timer
.expires
= jiffies
+ 1;
232 add_timer(&cs
->hw
.hfc
.timer
);
236 release_io_TeleInt(struct IsdnCardState
*cs
)
238 del_timer(&cs
->hw
.hfc
.timer
);
241 release_region(cs
->hw
.hfc
.addr
, 2);
245 reset_TeleInt(struct IsdnCardState
*cs
)
249 printk(KERN_INFO
"TeleInt: resetting card\n");
250 cs
->hw
.hfc
.cirm
|= HFC_RESET
;
251 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.cirm
); /* Reset On */
254 current
->state
= TASK_INTERRUPTIBLE
;
256 cs
->hw
.hfc
.cirm
&= ~HFC_RESET
;
257 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.cirm
); /* Reset Off */
258 current
->state
= TASK_INTERRUPTIBLE
;
260 restore_flags(flags
);
264 TeleInt_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
271 release_io_TeleInt(cs
);
274 return(request_irq(cs
->irq
, &TeleInt_interrupt
,
275 I4L_IRQ_FLAG
, "HiSax", cs
));
278 clear_pending_isac_ints(cs
);
280 /* Reenable all IRQ */
281 cs
->writeisac(cs
, ISAC_MASK
, 0);
282 cs
->writeisac(cs
, ISAC_CMDR
, 0x41);
283 cs
->hw
.hfc
.timer
.expires
= jiffies
+ 1;
284 add_timer(&cs
->hw
.hfc
.timer
);
293 setup_TeleInt(struct IsdnCard
*card
)
295 struct IsdnCardState
*cs
= card
->cs
;
298 strcpy(tmp
, TeleInt_revision
);
299 printk(KERN_INFO
"HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp
));
300 if (cs
->typ
!= ISDN_CTYPE_TELEINT
)
303 cs
->hw
.hfc
.addr
= card
->para
[1] & 0x3fe;
304 cs
->irq
= card
->para
[0];
305 cs
->hw
.hfc
.cirm
= HFC_CIRM
;
306 cs
->hw
.hfc
.isac_spcr
= 0x00;
308 cs
->hw
.hfc
.ctmt
= HFC_CTMT
| HFC_CLTIMER
;
309 cs
->bcs
[0].hw
.hfc
.send
= NULL
;
310 cs
->bcs
[1].hw
.hfc
.send
= NULL
;
311 cs
->hw
.hfc
.fifosize
= 7 * 1024 + 512;
312 cs
->hw
.hfc
.timer
.function
= (void *) TeleInt_Timer
;
313 cs
->hw
.hfc
.timer
.data
= (long) cs
;
314 init_timer(&cs
->hw
.hfc
.timer
);
315 if (check_region((cs
->hw
.hfc
.addr
), 2)) {
317 "HiSax: %s config port %x-%x already in use\n",
320 cs
->hw
.hfc
.addr
+ 2);
323 request_region(cs
->hw
.hfc
.addr
, 2, "TeleInt isdn");
326 byteout(cs
->hw
.hfc
.addr
, cs
->hw
.hfc
.addr
& 0xff);
327 byteout(cs
->hw
.hfc
.addr
| 1, ((cs
->hw
.hfc
.addr
& 0x300) >> 8) | 0x54);
330 cs
->hw
.hfc
.cirm
|= HFC_INTA
;
333 cs
->hw
.hfc
.cirm
|= HFC_INTB
;
336 cs
->hw
.hfc
.cirm
|= HFC_INTC
;
339 cs
->hw
.hfc
.cirm
|= HFC_INTD
;
342 cs
->hw
.hfc
.cirm
|= HFC_INTE
;
345 cs
->hw
.hfc
.cirm
|= HFC_INTF
;
348 printk(KERN_WARNING
"TeleInt: wrong IRQ\n");
349 release_io_TeleInt(cs
);
352 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.cirm
);
353 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.ctmt
);
356 "TeleInt: defined at 0x%x IRQ %d\n",
361 cs
->readisac
= &ReadISAC
;
362 cs
->writeisac
= &WriteISAC
;
363 cs
->readisacfifo
= &ReadISACfifo
;
364 cs
->writeisacfifo
= &WriteISACfifo
;
365 cs
->BC_Read_Reg
= &ReadHFC
;
366 cs
->BC_Write_Reg
= &WriteHFC
;
367 cs
->cardmsg
= &TeleInt_card_msg
;
368 ISACVersion(cs
, "TeleInt:");