1 /* $Id: teles3.c,v 1.11 1997/04/13 19:54:05 keil Exp $
3 * teles3.c low level stuff for Teles 16.3 & PNP isdn cards
5 * based on the teles driver from Jan den Ouden
7 * Author Karsten Keil (keil@temic-ech.spacenet.de)
9 * Thanks to Jan den Ouden
14 * Revision 1.11 1997/04/13 19:54:05 keil
15 * Change in IRQ check delay for SMP
17 * Revision 1.10 1997/04/06 22:54:05 keil
20 * Revision 1.9 1997/03/22 02:01:07 fritz
21 * -Reworked toplevel Makefile. From now on, no different Makefiles
22 * for standalone- and in-kernel-compilation are needed any more.
23 * -Added local Rules.make for above reason.
24 * -Experimental changes in teles3.c for enhanced IRQ-checking with
25 * 2.1.X and SMP kernels.
26 * -Removed diffstd-script, same functionality is in stddiff -r.
27 * -Enhanced scripts std2kern and stddiff.
29 * Revision 1.8 1997/02/23 18:43:55 fritz
30 * Added support for Teles-Vision.
32 * Revision 1.7 1997/01/28 22:48:33 keil
33 * fixes for Teles PCMCIA (Christof Petig)
35 * Revision 1.6 1997/01/27 15:52:55 keil
36 * SMP proof,cosmetics, PCMCIA added
38 * Revision 1.5 1997/01/21 22:28:32 keil
41 * Revision 1.4 1996/12/14 21:05:41 keil
44 * Revision 1.3 1996/11/05 19:56:54 keil
47 * Revision 1.2 1996/10/27 22:09:15 keil
50 * Revision 1.1 1996/10/13 20:04:59 keil
56 #define __NO_VERSION__
61 #include <linux/kernel_stat.h>
63 extern const char *CardType
[];
64 const char *teles3_revision
= "$Revision: 1.11 $";
66 #define byteout(addr,val) outb_p(val,addr)
67 #define bytein(addr) inb_p(addr)
70 readreg(unsigned int adr
, u_char off
)
72 return (bytein(adr
+ off
));
76 writereg(unsigned int adr
, u_char off
, u_char data
)
78 byteout(adr
+ off
, data
);
83 read_fifo(unsigned int adr
, u_char
* data
, int size
)
85 insb(adr
+ 0x1e, data
, size
);
89 write_fifo(unsigned int adr
, u_char
* data
, int size
)
91 outsb(adr
+ 0x1e, data
, size
);
99 while ((readreg(adr
, HSCX_STAR
) & 0x04) && to
) {
104 printk(KERN_WARNING
"Teles3: waitforCEC timeout\n");
113 while ((!(readreg(adr
, HSCX_STAR
) & 0x44) == 0x40) && to
) {
118 printk(KERN_WARNING
"Teles3: waitforXFW timeout\n");
121 writehscxCMDR(int adr
, u_char data
)
128 writereg(adr
, HSCX_CMDR
, data
);
129 restore_flags(flags
);
133 * fast interrupt here
137 hscxreport(struct IsdnCardState
*sp
, int hscx
)
139 printk(KERN_DEBUG
"HSCX %d\n", hscx
);
140 printk(KERN_DEBUG
"ISTA %x\n", readreg(sp
->hscx
[hscx
], HSCX_ISTA
));
141 printk(KERN_DEBUG
"STAR %x\n", readreg(sp
->hscx
[hscx
], HSCX_STAR
));
142 printk(KERN_DEBUG
"EXIR %x\n", readreg(sp
->hscx
[hscx
], HSCX_EXIR
));
146 teles3_report(struct IsdnCardState
*sp
)
148 printk(KERN_DEBUG
"ISAC\n");
149 printk(KERN_DEBUG
"ISTA %x\n", readreg(sp
->isac
, ISAC_ISTA
));
150 printk(KERN_DEBUG
"STAR %x\n", readreg(sp
->isac
, ISAC_STAR
));
151 printk(KERN_DEBUG
"EXIR %x\n", readreg(sp
->isac
, ISAC_EXIR
));
157 * HSCX stuff goes here
161 hscx_empty_fifo(struct HscxState
*hsp
, int count
)
164 struct IsdnCardState
*sp
= hsp
->sp
;
167 if ((sp
->debug
& L1_DEB_HSCX
) && !(sp
->debug
& L1_DEB_HSCX_FIFO
))
168 debugl1(sp
, "hscx_empty_fifo");
170 if (hsp
->rcvidx
+ count
> HSCX_BUFMAX
) {
171 if (sp
->debug
& L1_DEB_WARN
)
172 debugl1(sp
, "hscx_empty_fifo: incoming packet too large");
173 writehscxCMDR(sp
->hscx
[hsp
->hscx
], 0x80);
177 ptr
= hsp
->rcvbuf
+ hsp
->rcvidx
;
178 hsp
->rcvidx
+= count
;
181 read_fifo(sp
->hscx
[hsp
->hscx
], ptr
, count
);
182 writehscxCMDR(sp
->hscx
[hsp
->hscx
], 0x80);
183 restore_flags(flags
);
184 if (sp
->debug
& L1_DEB_HSCX_FIFO
) {
188 t
+= sprintf(t
, "hscx_empty_fifo %c cnt %d",
189 hsp
->hscx
? 'B' : 'A', count
);
190 QuickHex(t
, ptr
, count
);
196 hscx_fill_fifo(struct HscxState
*hsp
)
198 struct IsdnCardState
*sp
= hsp
->sp
;
203 if ((sp
->debug
& L1_DEB_HSCX
) && !(sp
->debug
& L1_DEB_HSCX_FIFO
))
204 debugl1(sp
, "hscx_fill_fifo");
208 if (hsp
->tx_skb
->len
<= 0)
211 more
= (hsp
->mode
== 1) ? 1 : 0;
212 if (hsp
->tx_skb
->len
> 32) {
216 count
= hsp
->tx_skb
->len
;
218 waitforXFW(sp
->hscx
[hsp
->hscx
]);
221 ptr
= hsp
->tx_skb
->data
;
222 skb_pull(hsp
->tx_skb
, count
);
223 hsp
->tx_cnt
-= count
;
225 write_fifo(sp
->hscx
[hsp
->hscx
], ptr
, count
);
226 writehscxCMDR(sp
->hscx
[hsp
->hscx
], more
? 0x8 : 0xa);
227 restore_flags(flags
);
228 if (sp
->debug
& L1_DEB_HSCX_FIFO
) {
232 t
+= sprintf(t
, "hscx_fill_fifo %c cnt %d",
233 hsp
->hscx
? 'B' : 'A', count
);
234 QuickHex(t
, ptr
, count
);
240 hscx_interrupt(struct IsdnCardState
*sp
, u_char val
, u_char hscx
)
243 struct HscxState
*hsp
= sp
->hs
+ hscx
;
251 if (val
& 0x80) { /* RME */
253 r
= readreg(sp
->hscx
[hsp
->hscx
], HSCX_RSTA
);
254 if ((r
& 0xf0) != 0xa0) {
256 if (sp
->debug
& L1_DEB_WARN
)
257 debugl1(sp
, "HSCX invalid frame");
258 if ((r
& 0x40) && hsp
->mode
)
259 if (sp
->debug
& L1_DEB_WARN
) {
260 sprintf(tmp
, "HSCX RDO mode=%d",
265 if (sp
->debug
& L1_DEB_WARN
)
266 debugl1(sp
, "HSCX CRC error");
267 writehscxCMDR(sp
->hscx
[hsp
->hscx
], 0x80);
269 count
= readreg(sp
->hscx
[hsp
->hscx
], HSCX_RBCL
) & 0x1f;
272 hscx_empty_fifo(hsp
, count
);
273 if ((count
= hsp
->rcvidx
- 1) > 0) {
274 if (!(skb
= dev_alloc_skb(count
)))
275 printk(KERN_WARNING
"AVM: receive out of memory\n");
277 memcpy(skb_put(skb
, count
), hsp
->rcvbuf
, count
);
278 skb_queue_tail(&hsp
->rqueue
, skb
);
283 hscx_sched_event(hsp
, HSCX_RCVBUFREADY
);
285 if (val
& 0x40) { /* RPF */
286 hscx_empty_fifo(hsp
, 32);
287 if (hsp
->mode
== 1) {
288 /* receive audio data */
289 if (!(skb
= dev_alloc_skb(32)))
290 printk(KERN_WARNING
"AVM: receive out of memory\n");
292 memcpy(skb_put(skb
, 32), hsp
->rcvbuf
, 32);
293 skb_queue_tail(&hsp
->rqueue
, skb
);
296 hscx_sched_event(hsp
, HSCX_RCVBUFREADY
);
299 if (val
& 0x10) { /* XPR */
301 if (hsp
->tx_skb
->len
) {
305 SET_SKB_FREE(hsp
->tx_skb
);
306 dev_kfree_skb(hsp
->tx_skb
, FREE_WRITE
);
308 if (hsp
->st
->l4
.l1writewakeup
)
309 hsp
->st
->l4
.l1writewakeup(hsp
->st
);
312 if ((hsp
->tx_skb
= skb_dequeue(&hsp
->squeue
))) {
316 hscx_sched_event(hsp
, HSCX_XMTBUFREADY
);
321 * ISAC stuff goes here
325 isac_empty_fifo(struct IsdnCardState
*sp
, int count
)
330 if ((sp
->debug
& L1_DEB_ISAC
) && !(sp
->debug
& L1_DEB_ISAC_FIFO
))
331 if (sp
->debug
& L1_DEB_ISAC
)
332 debugl1(sp
, "isac_empty_fifo");
334 if ((sp
->rcvidx
+ count
) >= MAX_DFRAME_LEN
) {
335 if (sp
->debug
& L1_DEB_WARN
) {
337 sprintf(tmp
, "isac_empty_fifo overrun %d",
341 writereg(sp
->isac
, ISAC_CMDR
, 0x80);
345 ptr
= sp
->rcvbuf
+ sp
->rcvidx
;
349 read_fifo(sp
->isac
, ptr
, count
);
350 writereg(sp
->isac
, ISAC_CMDR
, 0x80);
351 restore_flags(flags
);
352 if (sp
->debug
& L1_DEB_ISAC_FIFO
) {
356 t
+= sprintf(t
, "isac_empty_fifo cnt %d", count
);
357 QuickHex(t
, ptr
, count
);
363 isac_fill_fifo(struct IsdnCardState
*sp
)
369 if ((sp
->debug
& L1_DEB_ISAC
) && !(sp
->debug
& L1_DEB_ISAC_FIFO
))
370 debugl1(sp
, "isac_fill_fifo");
375 count
= sp
->tx_skb
->len
;
386 ptr
= sp
->tx_skb
->data
;
387 skb_pull(sp
->tx_skb
, count
);
389 write_fifo(sp
->isac
, ptr
, count
);
390 writereg(sp
->isac
, ISAC_CMDR
, more
? 0x8 : 0xa);
391 restore_flags(flags
);
392 if (sp
->debug
& L1_DEB_ISAC_FIFO
) {
396 t
+= sprintf(t
, "isac_fill_fifo cnt %d", count
);
397 QuickHex(t
, ptr
, count
);
403 ph_command(struct IsdnCardState
*sp
, unsigned int command
)
405 if (sp
->debug
& L1_DEB_ISAC
) {
407 sprintf(tmp
, "ph_command %d", command
);
410 writereg(sp
->isac
, ISAC_CIX0
, (command
<< 2) | 3);
415 isac_interrupt(struct IsdnCardState
*sp
, u_char val
)
422 if (sp
->debug
& L1_DEB_ISAC
) {
423 sprintf(tmp
, "ISAC interrupt %x", val
);
426 if (val
& 0x80) { /* RME */
427 exval
= readreg(sp
->isac
, ISAC_RSTA
);
428 if ((exval
& 0x70) != 0x20) {
430 if (sp
->debug
& L1_DEB_WARN
)
431 debugl1(sp
, "ISAC RDO");
433 if (sp
->debug
& L1_DEB_WARN
)
434 debugl1(sp
, "ISAC CRC error");
435 writereg(sp
->isac
, ISAC_CMDR
, 0x80);
437 count
= readreg(sp
->isac
, ISAC_RBCL
) & 0x1f;
440 isac_empty_fifo(sp
, count
);
441 if ((count
= sp
->rcvidx
) > 0) {
442 if (!(skb
= alloc_skb(count
, GFP_ATOMIC
)))
443 printk(KERN_WARNING
"AVM: D receive out of memory\n");
445 memcpy(skb_put(skb
, count
), sp
->rcvbuf
, count
);
446 skb_queue_tail(&sp
->rq
, skb
);
451 isac_sched_event(sp
, ISAC_RCVBUFREADY
);
453 if (val
& 0x40) { /* RPF */
454 isac_empty_fifo(sp
, 32);
456 if (val
& 0x20) { /* RSC */
458 if (sp
->debug
& L1_DEB_WARN
)
459 debugl1(sp
, "ISAC RSC interrupt");
461 if (val
& 0x10) { /* XPR */
463 if (sp
->tx_skb
->len
) {
467 SET_SKB_FREE(sp
->tx_skb
);
468 dev_kfree_skb(sp
->tx_skb
, FREE_WRITE
);
472 if ((sp
->tx_skb
= skb_dequeue(&sp
->sq
))) {
476 isac_sched_event(sp
, ISAC_XMTBUFREADY
);
479 if (val
& 0x04) { /* CISQ */
480 sp
->ph_state
= (readreg(sp
->isac
, ISAC_CIX0
) >> 2)
482 if (sp
->debug
& L1_DEB_ISAC
) {
483 sprintf(tmp
, "l1state %d", sp
->ph_state
);
488 if (val
& 0x02) { /* SIN */
490 if (sp
->debug
& L1_DEB_WARN
)
491 debugl1(sp
, "ISAC SIN interrupt");
493 if (val
& 0x01) { /* EXI */
494 exval
= readreg(sp
->isac
, ISAC_EXIR
);
495 if (sp
->debug
& L1_DEB_WARN
) {
496 sprintf(tmp
, "ISAC EXIR %02x", exval
);
503 hscx_int_main(struct IsdnCardState
*sp
, u_char val
)
507 struct HscxState
*hsp
;
513 exval
= readreg(sp
->hscx
[1], HSCX_EXIR
);
518 /* Here we lost an TX interrupt, so
519 * restart transmitting the whole frame.
522 skb_push(hsp
->tx_skb
, hsp
->count
);
523 hsp
->tx_cnt
+= hsp
->count
;
526 writehscxCMDR(sp
->hscx
[hsp
->hscx
], 0x01);
527 if (sp
->debug
& L1_DEB_WARN
) {
528 sprintf(tmp
, "HSCX B EXIR %x Lost TX", exval
);
532 } else if (sp
->debug
& L1_DEB_HSCX
) {
533 sprintf(tmp
, "HSCX B EXIR %x", exval
);
538 if (sp
->debug
& L1_DEB_HSCX
) {
539 sprintf(tmp
, "HSCX B interrupt %x", val
);
542 hscx_interrupt(sp
, val
, 1);
546 exval
= readreg(sp
->hscx
[0], HSCX_EXIR
);
551 /* Here we lost an TX interrupt, so
552 * restart transmitting the whole frame.
555 skb_push(hsp
->tx_skb
, hsp
->count
);
556 hsp
->tx_cnt
+= hsp
->count
;
559 writehscxCMDR(sp
->hscx
[hsp
->hscx
], 0x01);
560 if (sp
->debug
& L1_DEB_WARN
) {
561 sprintf(tmp
, "HSCX A EXIR %x Lost TX", exval
);
565 } else if (sp
->debug
& L1_DEB_HSCX
) {
566 sprintf(tmp
, "HSCX A EXIR %x", exval
);
571 exval
= readreg(sp
->hscx
[0], HSCX_ISTA
);
572 if (sp
->debug
& L1_DEB_HSCX
) {
573 sprintf(tmp
, "HSCX A interrupt %x", exval
);
576 hscx_interrupt(sp
, exval
, 0);
581 teles3_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
584 struct IsdnCardState
*sp
;
585 u_char val
, stat
= 0;
588 sp
= (struct IsdnCardState
*) dev_id
;
591 printk(KERN_WARNING
"Teles: Spurious interrupt!\n");
594 val
= readreg(sp
->hscx
[1], HSCX_ISTA
);
597 hscx_int_main(sp
, val
);
600 val
= readreg(sp
->isac
, ISAC_ISTA
);
603 isac_interrupt(sp
, val
);
607 val
= readreg(sp
->hscx
[1], HSCX_ISTA
);
608 if (val
&& count
< MAXCOUNT
) {
609 if (sp
->debug
& L1_DEB_HSCX
)
610 debugl1(sp
, "HSCX IntStat after IntRoutine");
613 val
= readreg(sp
->isac
, ISAC_ISTA
);
614 if (val
&& count
< MAXCOUNT
) {
615 if (sp
->debug
& L1_DEB_ISAC
)
616 debugl1(sp
, "ISAC IntStat after IntRoutine");
619 if (count
>= MAXCOUNT
)
620 printk(KERN_WARNING
"Teles3: more than %d loops in teles3_interrupt\n", count
);
622 writereg(sp
->hscx
[0], HSCX_MASK
, 0xFF);
623 writereg(sp
->hscx
[1], HSCX_MASK
, 0xFF);
624 writereg(sp
->hscx
[0], HSCX_MASK
, 0x0);
625 writereg(sp
->hscx
[1], HSCX_MASK
, 0x0);
628 writereg(sp
->isac
, ISAC_MASK
, 0xFF);
629 writereg(sp
->isac
, ISAC_MASK
, 0x0);
635 initisac(struct IsdnCardState
*sp
)
637 unsigned int adr
= sp
->isac
;
639 /* 16.3 IOM 2 Mode */
640 writereg(adr
, ISAC_MASK
, 0xff);
641 writereg(adr
, ISAC_ADF2
, 0x80);
642 writereg(adr
, ISAC_SQXR
, 0x2f);
643 writereg(adr
, ISAC_SPCR
, 0x0);
644 writereg(adr
, ISAC_ADF1
, 0x2);
645 writereg(adr
, ISAC_STCR
, 0x70);
646 writereg(adr
, ISAC_MODE
, 0xc9);
647 writereg(adr
, ISAC_TIMR
, 0x0);
648 writereg(adr
, ISAC_ADF1
, 0x0);
649 writereg(adr
, ISAC_CMDR
, 0x41);
650 writereg(adr
, ISAC_CIX0
, (1 << 2) | 3);
651 writereg(adr
, ISAC_MASK
, 0xff);
652 writereg(adr
, ISAC_MASK
, 0x0);
656 modehscx(struct HscxState
*hs
, int mode
, int ichan
)
658 struct IsdnCardState
*sp
= hs
->sp
;
661 if (sp
->debug
& L1_DEB_HSCX
) {
663 sprintf(tmp
, "hscx %c mode %d ichan %d",
664 'A' + hscx
, mode
, ichan
);
668 writereg(sp
->hscx
[hscx
], HSCX_CCR1
, 0x85);
669 writereg(sp
->hscx
[hscx
], HSCX_XAD1
, 0xFF);
670 writereg(sp
->hscx
[hscx
], HSCX_XAD2
, 0xFF);
671 writereg(sp
->hscx
[hscx
], HSCX_RAH2
, 0xFF);
672 writereg(sp
->hscx
[hscx
], HSCX_XBCH
, 0x0);
673 writereg(sp
->hscx
[hscx
], HSCX_RLCR
, 0x0);
677 writereg(sp
->hscx
[hscx
], HSCX_CCR2
, 0x30);
678 writereg(sp
->hscx
[hscx
], HSCX_TSAX
, 0xff);
679 writereg(sp
->hscx
[hscx
], HSCX_TSAR
, 0xff);
680 writereg(sp
->hscx
[hscx
], HSCX_XCCR
, 7);
681 writereg(sp
->hscx
[hscx
], HSCX_RCCR
, 7);
682 writereg(sp
->hscx
[hscx
], HSCX_MODE
, 0x84);
686 writereg(sp
->hscx
[hscx
], HSCX_CCR2
, 0x30);
687 writereg(sp
->hscx
[hscx
], HSCX_TSAX
, 0x2f);
688 writereg(sp
->hscx
[hscx
], HSCX_TSAR
, 0x2f);
689 writereg(sp
->hscx
[hscx
], HSCX_XCCR
, 7);
690 writereg(sp
->hscx
[hscx
], HSCX_RCCR
, 7);
692 writereg(sp
->hscx
[hscx
], HSCX_CCR2
, 0x30);
693 writereg(sp
->hscx
[hscx
], HSCX_TSAX
, 0x3);
694 writereg(sp
->hscx
[hscx
], HSCX_TSAR
, 0x3);
695 writereg(sp
->hscx
[hscx
], HSCX_XCCR
, 7);
696 writereg(sp
->hscx
[hscx
], HSCX_RCCR
, 7);
698 writereg(sp
->hscx
[hscx
], HSCX_MODE
, 0xe4);
699 writereg(sp
->hscx
[hscx
], HSCX_CMDR
, 0x41);
703 writereg(sp
->hscx
[hscx
], HSCX_CCR2
, 0x30);
704 writereg(sp
->hscx
[hscx
], HSCX_TSAX
, 0x2f);
705 writereg(sp
->hscx
[hscx
], HSCX_TSAR
, 0x2f);
706 writereg(sp
->hscx
[hscx
], HSCX_XCCR
, 7);
707 writereg(sp
->hscx
[hscx
], HSCX_RCCR
, 7);
709 writereg(sp
->hscx
[hscx
], HSCX_CCR2
, 0x30);
710 writereg(sp
->hscx
[hscx
], HSCX_TSAX
, 0x3);
711 writereg(sp
->hscx
[hscx
], HSCX_TSAR
, 0x3);
712 writereg(sp
->hscx
[hscx
], HSCX_XCCR
, 7);
713 writereg(sp
->hscx
[hscx
], HSCX_RCCR
, 7);
715 writereg(sp
->hscx
[hscx
], HSCX_MODE
, 0x8c);
716 writereg(sp
->hscx
[hscx
], HSCX_CMDR
, 0x41);
719 writereg(sp
->hscx
[hscx
], HSCX_ISTA
, 0x00);
723 release_ioregs(struct IsdnCard
*card
, int mask
)
726 release_region(card
->sp
->isac
, 32);
728 release_region(card
->sp
->hscx
[0], 32);
730 release_region(card
->sp
->hscx
[1], 32);
734 release_io_teles3(struct IsdnCard
*card
)
736 if (card
->sp
->typ
== ISDN_CTYPE_TELESPCMCIA
)
737 release_region(card
->sp
->hscx
[0], 97);
739 if (card
->sp
->cfg_reg
)
740 release_region(card
->sp
->cfg_reg
, 8);
741 release_ioregs(card
, 0x7);
746 clear_pending_ints(struct IsdnCardState
*sp
)
751 val
= readreg(sp
->hscx
[1], HSCX_ISTA
);
752 sprintf(tmp
, "HSCX B ISTA %x", val
);
755 val
= readreg(sp
->hscx
[1], HSCX_EXIR
);
756 sprintf(tmp
, "HSCX B EXIR %x", val
);
758 } else if (val
& 0x02) {
759 val
= readreg(sp
->hscx
[0], HSCX_EXIR
);
760 sprintf(tmp
, "HSCX A EXIR %x", val
);
763 val
= readreg(sp
->hscx
[0], HSCX_ISTA
);
764 sprintf(tmp
, "HSCX A ISTA %x", val
);
766 val
= readreg(sp
->hscx
[1], HSCX_STAR
);
767 sprintf(tmp
, "HSCX B STAR %x", val
);
769 val
= readreg(sp
->hscx
[0], HSCX_STAR
);
770 sprintf(tmp
, "HSCX A STAR %x", val
);
772 val
= readreg(sp
->isac
, ISAC_STAR
);
773 sprintf(tmp
, "ISAC STAR %x", val
);
775 val
= readreg(sp
->isac
, ISAC_MODE
);
776 sprintf(tmp
, "ISAC MODE %x", val
);
778 val
= readreg(sp
->isac
, ISAC_ADF2
);
779 sprintf(tmp
, "ISAC ADF2 %x", val
);
781 val
= readreg(sp
->isac
, ISAC_ISTA
);
782 sprintf(tmp
, "ISAC ISTA %x", val
);
785 val
= readreg(sp
->isac
, ISAC_EXIR
);
786 sprintf(tmp
, "ISAC EXIR %x", val
);
788 } else if (val
& 0x04) {
789 val
= readreg(sp
->isac
, ISAC_CIR0
);
790 sprintf(tmp
, "ISAC CIR0 %x", val
);
793 writereg(sp
->isac
, ISAC_MASK
, 0);
794 writereg(sp
->isac
, ISAC_CMDR
, 0x41);
798 initteles3(struct IsdnCardState
*sp
)
804 sp
->counter
= kstat_irqs(sp
->irq
);
805 sprintf(tmp
, "IRQ %d count %d", sp
->irq
, sp
->counter
);
807 clear_pending_ints(sp
);
808 ret
= get_irq(sp
->cardnr
, &teles3_interrupt
);
811 sp
->modehscx(sp
->hs
, 0, 0);
812 writereg(sp
->hscx
[sp
->hs
->hscx
], HSCX_CMDR
, 0x01);
813 sp
->modehscx(sp
->hs
+ 1, 0, 0);
814 writereg(sp
->hscx
[(sp
->hs
+ 1)->hscx
], HSCX_CMDR
, 0x01);
815 while (loop
++ < 10) {
816 /* At least 1-3 irqs must happen
817 * (one from HSCX A, one from HSCX B, 3rd from ISAC)
819 if (kstat_irqs(sp
->irq
) > sp
->counter
)
821 current
->state
= TASK_INTERRUPTIBLE
;
822 current
->timeout
= jiffies
+ 1;
825 sprintf(tmp
, "IRQ %d count %d loop %d", sp
->irq
,
826 kstat_irqs(sp
->irq
), loop
);
828 if (kstat_irqs(sp
->irq
) <= sp
->counter
) {
830 "Teles3: IRQ(%d) getting no interrupts during init\n",
832 free_irq(sp
->irq
, sp
);
840 setup_teles3(struct IsdnCard
*card
)
842 u_char cfval
= 0, val
, verA
, verB
;
843 struct IsdnCardState
*sp
= card
->sp
;
847 strcpy(tmp
, teles3_revision
);
848 printk(KERN_NOTICE
"HiSax: Teles IO driver Rev. %s\n", HiSax_getrev(tmp
));
849 if ((sp
->typ
!= ISDN_CTYPE_16_3
) && (sp
->typ
!= ISDN_CTYPE_PNP
)
850 && (sp
->typ
!= ISDN_CTYPE_TELESPCMCIA
))
853 if (sp
->typ
== ISDN_CTYPE_16_3
) {
854 sp
->cfg_reg
= card
->para
[1];
855 switch (sp
->cfg_reg
) {
859 sp
->cfg_reg
|= 0xc00;
862 sp
->isac
= sp
->cfg_reg
- 0x400;
863 sp
->hscx
[0] = sp
->cfg_reg
- 0xc00;
864 sp
->hscx
[1] = sp
->cfg_reg
- 0x800;
865 } else if (sp
->typ
== ISDN_CTYPE_TELESPCMCIA
) {
867 sp
->hscx
[0] = card
->para
[1];
868 sp
->hscx
[1] = card
->para
[1] + 0x20;
869 sp
->isac
= card
->para
[1] + 0x40;
872 sp
->isac
= card
->para
[1];
873 sp
->hscx
[0] = card
->para
[2];
874 sp
->hscx
[1] = card
->para
[2] + 0x20;
876 sp
->irq
= card
->para
[0];
877 if (sp
->typ
== ISDN_CTYPE_TELESPCMCIA
) {
878 if (check_region((sp
->hscx
[0]), 97)) {
880 "HiSax: %s ports %x-%x already in use\n",
886 request_region(sp
->hscx
[0], 97, "HiSax Teles PCMCIA");
889 if (check_region((sp
->cfg_reg
), 8)) {
891 "HiSax: %s config port %x-%x already in use\n",
897 request_region(sp
->cfg_reg
, 8, "teles3 cfg");
900 if (check_region((sp
->isac
), 32)) {
902 "HiSax: %s isac ports %x-%x already in use\n",
907 release_region(sp
->cfg_reg
, 8);
911 request_region(sp
->isac
, 32, "HiSax isac");
913 if (check_region((sp
->hscx
[0]), 32)) {
915 "HiSax: %s hscx A ports %x-%x already in use\n",
920 release_region(sp
->cfg_reg
, 8);
922 release_ioregs(card
, 1);
925 request_region(sp
->hscx
[0], 32, "HiSax hscx A");
927 if (check_region((sp
->hscx
[1]), 32)) {
929 "HiSax: %s hscx B ports %x-%x already in use\n",
934 release_region(sp
->cfg_reg
, 8);
936 release_ioregs(card
, 3);
939 request_region(sp
->hscx
[1], 32, "HiSax hscx B");
972 if ((val
= bytein(sp
->cfg_reg
+ 0)) != 0x51) {
973 printk(KERN_WARNING
"Teles: 16.3 Byte at %x is %x\n",
974 sp
->cfg_reg
+ 0, val
);
975 release_io_teles3(card
);
978 if ((val
= bytein(sp
->cfg_reg
+ 1)) != 0x93) {
979 printk(KERN_WARNING
"Teles: 16.3 Byte at %x is %x\n",
980 sp
->cfg_reg
+ 1, val
);
981 release_io_teles3(card
);
984 val
= bytein(sp
->cfg_reg
+ 2); /* 0x1e=without AB
987 * 0x46 16.3 with AB + Video (Teles-Vision)
989 if (val
!= 0x46 && val
!= 0x1c && val
!= 0x1e && val
!= 0x1f) {
990 printk(KERN_WARNING
"Teles: 16.3 Byte at %x is %x\n",
991 sp
->cfg_reg
+ 2, val
);
992 release_io_teles3(card
);
996 byteout(sp
->cfg_reg
+ 4, cfval
);
998 HZDELAY(HZ
/ 10 + 1);
999 byteout(sp
->cfg_reg
+ 4, cfval
| 1);
1000 HZDELAY(HZ
/ 10 + 1);
1001 restore_flags(flags
);
1003 /* Reset off for 16.3 PnP , thanks to Georg Acher */
1005 byteout(sp
->isac
+ 0x1c, 1);
1007 restore_flags(flags
);
1010 "HiSax: %s config irq:%d isac:%x cfg:%x\n",
1011 CardType
[sp
->typ
], sp
->irq
,
1012 sp
->isac
, sp
->cfg_reg
);
1014 "HiSax: hscx A:%x hscx B:%x\n",
1015 sp
->hscx
[0], sp
->hscx
[1]);
1016 verA
= readreg(sp
->hscx
[0], HSCX_VSTR
) & 0xf;
1017 verB
= readreg(sp
->hscx
[1], HSCX_VSTR
) & 0xf;
1018 printk(KERN_INFO
"Teles3: HSCX version A: %s B: %s\n",
1019 HscxVersion(verA
), HscxVersion(verB
));
1020 val
= readreg(sp
->isac
, ISAC_RBCH
);
1021 printk(KERN_INFO
"Teles3: ISAC %s\n",
1023 if ((verA
== 0) | (verA
== 0xf) | (verB
== 0) | (verB
== 0xf)) {
1025 "Teles3: wrong HSCX versions check IO address\n");
1026 release_io_teles3(card
);
1029 sp
->modehscx
= &modehscx
;
1030 sp
->ph_command
= &ph_command
;
1031 sp
->hscx_fill_fifo
= &hscx_fill_fifo
;
1032 sp
->isac_fill_fifo
= &isac_fill_fifo
;