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 extern const char *CardType
[];
21 const char *TeleInt_revision
= "$Revision: 1.16.2.5 $";
23 #define byteout(addr,val) outb(val,addr)
24 #define bytein(addr) inb(addr)
27 readreg(unsigned int ale
, unsigned int adr
, u_char off
)
33 ret
= HFC_BUSY
& bytein(ale
);
34 while (ret
&& --max_delay
)
35 ret
= HFC_BUSY
& bytein(ale
);
37 printk(KERN_WARNING
"TeleInt Busy not inactive\n");
45 readfifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
48 register int max_delay
= 20000;
52 for (i
= 0; i
<size
; i
++) {
53 ret
= HFC_BUSY
& bytein(ale
);
54 while (ret
&& --max_delay
)
55 ret
= HFC_BUSY
& bytein(ale
);
57 printk(KERN_WARNING
"TeleInt Busy not inactive\n");
60 data
[i
] = bytein(adr
);
66 writereg(unsigned int ale
, unsigned int adr
, u_char off
, u_char data
)
72 ret
= HFC_BUSY
& bytein(ale
);
73 while (ret
&& --max_delay
)
74 ret
= HFC_BUSY
& bytein(ale
);
76 printk(KERN_WARNING
"TeleInt Busy not inactive\n");
83 writefifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
86 register int max_delay
= 20000;
90 for (i
= 0; i
<size
; i
++) {
91 ret
= HFC_BUSY
& bytein(ale
);
92 while (ret
&& --max_delay
)
93 ret
= HFC_BUSY
& bytein(ale
);
95 printk(KERN_WARNING
"TeleInt Busy not inactive\n");
98 byteout(adr
, data
[i
]);
102 /* Interface functions */
105 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
107 cs
->hw
.hfc
.cip
= offset
;
108 return (readreg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, offset
));
112 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
114 cs
->hw
.hfc
.cip
= offset
;
115 writereg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, offset
, value
);
119 ReadISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
122 readfifo(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, 0, data
, size
);
126 WriteISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
129 writefifo(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, 0, data
, size
);
133 ReadHFC(struct IsdnCardState
*cs
, int data
, u_char reg
)
138 cs
->hw
.hfc
.cip
= reg
;
139 byteout(cs
->hw
.hfc
.addr
| 1, reg
);
140 ret
= bytein(cs
->hw
.hfc
.addr
);
141 if (cs
->debug
& L1_DEB_HSCX_FIFO
&& (data
!= 2))
142 debugl1(cs
, "hfc RD %02x %02x", reg
, ret
);
144 ret
= bytein(cs
->hw
.hfc
.addr
| 1);
149 WriteHFC(struct IsdnCardState
*cs
, int data
, u_char reg
, u_char value
)
151 byteout(cs
->hw
.hfc
.addr
| 1, reg
);
152 cs
->hw
.hfc
.cip
= reg
;
154 byteout(cs
->hw
.hfc
.addr
, value
);
155 if (cs
->debug
& L1_DEB_HSCX_FIFO
&& (data
!= 2))
156 debugl1(cs
, "hfc W%c %02x %02x", data
? 'D' : 'C', reg
, value
);
160 TeleInt_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
162 struct IsdnCardState
*cs
= dev_id
;
166 spin_lock_irqsave(&cs
->lock
, flags
);
167 val
= readreg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_ISTA
);
170 isac_interrupt(cs
, val
);
171 val
= readreg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_ISTA
);
173 if (cs
->debug
& L1_DEB_ISAC
)
174 debugl1(cs
, "ISAC IntStat after IntRoutine");
177 writereg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_MASK
, 0xFF);
178 writereg(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.addr
, ISAC_MASK
, 0x0);
179 spin_unlock_irqrestore(&cs
->lock
, flags
);
184 TeleInt_Timer(struct IsdnCardState
*cs
)
189 spin_lock_irqsave(&cs
->lock
, flags
);
190 if (cs
->bcs
[0].mode
) {
192 main_irq_hfc(&cs
->bcs
[0]);
194 if (cs
->bcs
[1].mode
) {
196 main_irq_hfc(&cs
->bcs
[1]);
198 spin_unlock_irqrestore(&cs
->lock
, flags
);
202 cs
->hw
.hfc
.timer
.expires
= jiffies
+ stat
;
203 add_timer(&cs
->hw
.hfc
.timer
);
207 release_io_TeleInt(struct IsdnCardState
*cs
)
209 del_timer(&cs
->hw
.hfc
.timer
);
212 release_region(cs
->hw
.hfc
.addr
, 2);
216 reset_TeleInt(struct IsdnCardState
*cs
)
218 printk(KERN_INFO
"TeleInt: resetting card\n");
219 cs
->hw
.hfc
.cirm
|= HFC_RESET
;
220 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.cirm
); /* Reset On */
222 cs
->hw
.hfc
.cirm
&= ~HFC_RESET
;
223 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.cirm
); /* Reset Off */
228 TeleInt_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
235 spin_lock_irqsave(&cs
->lock
, flags
);
237 spin_unlock_irqrestore(&cs
->lock
, flags
);
240 release_io_TeleInt(cs
);
243 spin_lock_irqsave(&cs
->lock
, flags
);
246 clear_pending_isac_ints(cs
);
248 /* Reenable all IRQ */
249 cs
->writeisac(cs
, ISAC_MASK
, 0);
250 cs
->writeisac(cs
, ISAC_CMDR
, 0x41);
251 spin_unlock_irqrestore(&cs
->lock
, flags
);
255 cs
->hw
.hfc
.timer
.expires
= jiffies
+ delay
;
256 add_timer(&cs
->hw
.hfc
.timer
);
265 setup_TeleInt(struct IsdnCard
*card
)
267 struct IsdnCardState
*cs
= card
->cs
;
270 strcpy(tmp
, TeleInt_revision
);
271 printk(KERN_INFO
"HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp
));
272 if (cs
->typ
!= ISDN_CTYPE_TELEINT
)
275 cs
->hw
.hfc
.addr
= card
->para
[1] & 0x3fe;
276 cs
->irq
= card
->para
[0];
277 cs
->hw
.hfc
.cirm
= HFC_CIRM
;
278 cs
->hw
.hfc
.isac_spcr
= 0x00;
280 cs
->hw
.hfc
.ctmt
= HFC_CTMT
| HFC_CLTIMER
;
281 cs
->bcs
[0].hw
.hfc
.send
= NULL
;
282 cs
->bcs
[1].hw
.hfc
.send
= NULL
;
283 cs
->hw
.hfc
.fifosize
= 7 * 1024 + 512;
284 cs
->hw
.hfc
.timer
.function
= (void *) TeleInt_Timer
;
285 cs
->hw
.hfc
.timer
.data
= (long) cs
;
286 init_timer(&cs
->hw
.hfc
.timer
);
287 if (!request_region(cs
->hw
.hfc
.addr
, 2, "TeleInt isdn")) {
289 "HiSax: %s config port %x-%x already in use\n",
292 cs
->hw
.hfc
.addr
+ 2);
296 byteout(cs
->hw
.hfc
.addr
, cs
->hw
.hfc
.addr
& 0xff);
297 byteout(cs
->hw
.hfc
.addr
| 1, ((cs
->hw
.hfc
.addr
& 0x300) >> 8) | 0x54);
300 cs
->hw
.hfc
.cirm
|= HFC_INTA
;
303 cs
->hw
.hfc
.cirm
|= HFC_INTB
;
306 cs
->hw
.hfc
.cirm
|= HFC_INTC
;
309 cs
->hw
.hfc
.cirm
|= HFC_INTD
;
312 cs
->hw
.hfc
.cirm
|= HFC_INTE
;
315 cs
->hw
.hfc
.cirm
|= HFC_INTF
;
318 printk(KERN_WARNING
"TeleInt: wrong IRQ\n");
319 release_io_TeleInt(cs
);
322 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.cirm
);
323 byteout(cs
->hw
.hfc
.addr
| 1, cs
->hw
.hfc
.ctmt
);
325 printk(KERN_INFO
"TeleInt: defined at 0x%x IRQ %d\n",
326 cs
->hw
.hfc
.addr
, cs
->irq
);
329 cs
->readisac
= &ReadISAC
;
330 cs
->writeisac
= &WriteISAC
;
331 cs
->readisacfifo
= &ReadISACfifo
;
332 cs
->writeisacfifo
= &WriteISACfifo
;
333 cs
->BC_Read_Reg
= &ReadHFC
;
334 cs
->BC_Write_Reg
= &WriteHFC
;
335 cs
->cardmsg
= &TeleInt_card_msg
;
336 cs
->irq_func
= &TeleInt_interrupt
;
337 ISACVersion(cs
, "TeleInt:");