1 /* $Id: ix1_micro.c,v 1.3 1997/04/13 19:54:02 keil Exp $
3 * ix1_micro.c low level stuff for ITK ix1-micro Rev.2 isdn cards
4 * derived from the original file teles3.c from Karsten Keil
6 * Copyright (C) 1997 Klaus-Peter Nischke (ITK AG) (for the modifications to
7 * the original file teles.c)
9 * Thanks to Jan den Ouden
13 * $Log: ix1_micro.c,v $
14 * Revision 1.3 1997/04/13 19:54:02 keil
15 * Change in IRQ check delay for SMP
17 * Revision 1.2 1997/04/06 22:54:21 keil
20 * Revision 1.1 1997/01/27 15:43:10 keil
27 For the modification done by the author the following terms and conditions
28 apply (GNU PUBLIC LICENSE)
31 This program is free software; you can redistribute it and/or modify
32 it under the terms of the GNU General Public License as published by
33 the Free Software Foundation; either version 2 of the License, or
34 (at your option) any later version.
36 This program is distributed in the hope that it will be useful,
37 but WITHOUT ANY WARRANTY; without even the implied warranty of
38 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 GNU General Public License for more details.
41 You should have received a copy of the GNU General Public License
42 along with this program; if not, write to the Free Software
43 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
46 You may contact Klaus-Peter Nischke by email: klaus@nischke.do.eunet.de
47 or by conventional mail:
56 #define __NO_VERSION__
61 #include <linux/kernel_stat.h>
63 extern const char *CardType
[];
64 const char *ix1_revision
= "$Revision: 1.3 $";
66 #define byteout(addr,val) outb_p(val,addr)
67 #define bytein(addr) inb_p(addr)
69 #define SPECIAL_PORT_OFFSET 3
71 #define ISAC_COMMAND_OFFSET 2
72 #define ISAC_DATA_OFFSET 0
73 #define HSCX_COMMAND_OFFSET 2
74 #define HSCX_DATA_OFFSET 1
76 #define ISAC_FIFOSIZE 16
77 #define HSCX_FIFOSIZE 16
82 IsacReadReg(unsigned int adr
, u_char off
)
84 byteout(adr
+ ISAC_COMMAND_OFFSET
, off
+ 0x20);
85 return bytein(adr
+ ISAC_DATA_OFFSET
);
89 IsacWriteReg(unsigned int adr
, u_char off
, u_char data
)
91 byteout(adr
+ ISAC_COMMAND_OFFSET
, off
+ 0x20);
92 byteout(adr
+ ISAC_DATA_OFFSET
, data
);
95 #define HSCX_OFFSET(WhichHscx,offset) \
96 ( (WhichHscx) ? (offset+0x60) : (offset+0x20) )
99 HscxReadReg(unsigned int adr
, int WhichHscx
, u_char off
)
101 byteout(adr
+ HSCX_COMMAND_OFFSET
, HSCX_OFFSET(WhichHscx
, off
));
102 return bytein(adr
+ HSCX_DATA_OFFSET
);
106 HscxWriteReg(unsigned int adr
, int WhichHscx
, u_char off
, u_char data
)
108 byteout(adr
+ HSCX_COMMAND_OFFSET
, HSCX_OFFSET(WhichHscx
, off
));
109 byteout(adr
+ HSCX_DATA_OFFSET
, data
);
114 IsacReadFifo(unsigned int adr
, u_char
* data
, int size
)
116 byteout(adr
+ ISAC_COMMAND_OFFSET
, 0);
118 *data
++ = bytein(adr
+ ISAC_DATA_OFFSET
);
122 IsacWriteFifo(unsigned int adr
, u_char
* data
, int size
)
124 byteout(adr
+ ISAC_COMMAND_OFFSET
, 0);
126 byteout(adr
+ ISAC_DATA_OFFSET
, *data
);
132 HscxReadFifo(unsigned int adr
, int WhichHscx
, u_char
* data
, int size
)
134 byteout(adr
+ HSCX_COMMAND_OFFSET
, (WhichHscx
) ? 0x40 : 0x00);
136 *data
++ = bytein(adr
+ HSCX_DATA_OFFSET
);
140 HscxWriteFifo(unsigned int adr
, int WhichHscx
, u_char
* data
, int size
)
142 byteout(adr
+ HSCX_COMMAND_OFFSET
, (WhichHscx
) ? 0x40 : 0x00);
144 byteout(adr
+ HSCX_DATA_OFFSET
, *data
);
150 waitforCEC(int adr
, int WhichHscx
)
154 while ((HscxReadReg(adr
, WhichHscx
, HSCX_STAR
) & 0x04) && to
) {
159 printk(KERN_WARNING
"ix1-Micro: waitforCEC timeout\n");
164 waitforXFW(int adr
, int WhichHscx
)
168 while ((!(HscxReadReg(adr
, WhichHscx
, HSCX_STAR
) & 0x44) == 0x40) && to
) {
173 printk(KERN_WARNING
"ix1-Micro: waitforXFW timeout\n");
177 writehscxCMDR(int adr
, int WhichHscx
, u_char data
)
183 waitforCEC(adr
, WhichHscx
);
184 HscxWriteReg(adr
, WhichHscx
, HSCX_CMDR
, data
);
185 restore_flags(flags
);
189 * fast interrupt here
193 hscxreport(struct IsdnCardState
*sp
, int hscx
)
195 printk(KERN_DEBUG
"HSCX %d\n", hscx
);
196 printk(KERN_DEBUG
"ISTA %x\n", HscxReadReg(sp
->hscx
[hscx
], hscx
, HSCX_ISTA
));
197 printk(KERN_DEBUG
"STAR %x\n", HscxReadReg(sp
->hscx
[hscx
], hscx
, HSCX_STAR
));
198 printk(KERN_DEBUG
"EXIR %x\n", HscxReadReg(sp
->hscx
[hscx
], hscx
, HSCX_EXIR
));
202 ix1micro_report(struct IsdnCardState
*sp
)
204 printk(KERN_DEBUG
"ISAC\n");
205 printk(KERN_DEBUG
"ISTA %x\n", IsacReadReg(sp
->isac
, ISAC_ISTA
));
206 printk(KERN_DEBUG
"STAR %x\n", IsacReadReg(sp
->isac
, ISAC_STAR
));
207 printk(KERN_DEBUG
"EXIR %x\n", IsacReadReg(sp
->isac
, ISAC_EXIR
));
213 * HSCX stuff goes here
217 hscx_empty_fifo(struct HscxState
*hsp
, int count
)
220 struct IsdnCardState
*sp
= hsp
->sp
;
223 if ((sp
->debug
& L1_DEB_HSCX
) && !(sp
->debug
& L1_DEB_HSCX_FIFO
))
224 debugl1(sp
, "hscx_empty_fifo");
226 if (hsp
->rcvidx
+ count
> HSCX_BUFMAX
) {
227 if (sp
->debug
& L1_DEB_WARN
)
228 debugl1(sp
, "hscx_empty_fifo: incoming packet too large");
229 writehscxCMDR(sp
->hscx
[hsp
->hscx
], hsp
->hscx
, 0x80);
233 ptr
= hsp
->rcvbuf
+ hsp
->rcvidx
;
234 hsp
->rcvidx
+= count
;
237 HscxReadFifo(sp
->hscx
[hsp
->hscx
], hsp
->hscx
, ptr
, count
);
238 writehscxCMDR(sp
->hscx
[hsp
->hscx
], hsp
->hscx
, 0x80);
239 restore_flags(flags
);
240 if (sp
->debug
& L1_DEB_HSCX_FIFO
) {
244 t
+= sprintf(t
, "hscx_empty_fifo %c cnt %d",
245 hsp
->hscx
? 'B' : 'A', count
);
246 QuickHex(t
, ptr
, count
);
252 hscx_fill_fifo(struct HscxState
*hsp
)
254 struct IsdnCardState
*sp
= hsp
->sp
;
259 if ((sp
->debug
& L1_DEB_HSCX
) && !(sp
->debug
& L1_DEB_HSCX_FIFO
))
260 debugl1(sp
, "hscx_fill_fifo");
264 if (hsp
->tx_skb
->len
<= 0)
267 more
= (hsp
->mode
== 1) ? 1 : 0;
268 if (hsp
->tx_skb
->len
> 32) {
272 count
= hsp
->tx_skb
->len
;
274 waitforXFW(sp
->hscx
[hsp
->hscx
], hsp
->hscx
);
277 ptr
= hsp
->tx_skb
->data
;
278 skb_pull(hsp
->tx_skb
, count
);
279 hsp
->tx_cnt
-= count
;
281 HscxWriteFifo(sp
->hscx
[hsp
->hscx
], hsp
->hscx
, ptr
, count
);
282 writehscxCMDR(sp
->hscx
[hsp
->hscx
], hsp
->hscx
, more
? 0x8 : 0xa);
283 restore_flags(flags
);
284 if (sp
->debug
& L1_DEB_HSCX_FIFO
) {
288 t
+= sprintf(t
, "hscx_fill_fifo %c cnt %d",
289 hsp
->hscx
? 'B' : 'A', count
);
290 QuickHex(t
, ptr
, count
);
296 hscx_interrupt(struct IsdnCardState
*sp
, u_char val
, u_char hscx
)
299 struct HscxState
*hsp
= sp
->hs
+ hscx
;
307 if (val
& 0x80) { /* RME */
309 r
= HscxReadReg(sp
->hscx
[hsp
->hscx
], hscx
, HSCX_RSTA
);
310 if ((r
& 0xf0) != 0xa0) {
312 if (sp
->debug
& L1_DEB_WARN
)
313 debugl1(sp
, "HSCX invalid frame");
314 if ((r
& 0x40) && hsp
->mode
)
315 if (sp
->debug
& L1_DEB_WARN
) {
316 sprintf(tmp
, "HSCX RDO mode=%d",
321 if (sp
->debug
& L1_DEB_WARN
)
322 debugl1(sp
, "HSCX CRC error");
323 writehscxCMDR(sp
->hscx
[hsp
->hscx
], hsp
->hscx
, 0x80);
325 count
= HscxReadReg(sp
->hscx
[hsp
->hscx
], hscx
, HSCX_RBCL
) & 0x1f;
328 hscx_empty_fifo(hsp
, count
);
329 if ((count
= hsp
->rcvidx
- 1) > 0) {
330 if (sp
->debug
& L1_DEB_HSCX_FIFO
) {
331 sprintf(tmp
, "HX Frame %d", count
);
334 if (!(skb
= dev_alloc_skb(count
)))
335 printk(KERN_WARNING
"IX1: receive out of memory\n");
337 memcpy(skb_put(skb
, count
), hsp
->rcvbuf
, count
);
338 skb_queue_tail(&hsp
->rqueue
, skb
);
343 hscx_sched_event(hsp
, HSCX_RCVBUFREADY
);
345 if (val
& 0x40) { /* RPF */
346 hscx_empty_fifo(hsp
, 32);
347 if (hsp
->mode
== 1) {
348 /* receive audio data */
349 if (!(skb
= dev_alloc_skb(32)))
350 printk(KERN_WARNING
"IX1: receive out of memory\n");
352 memcpy(skb_put(skb
, 32), hsp
->rcvbuf
, 32);
353 skb_queue_tail(&hsp
->rqueue
, skb
);
356 hscx_sched_event(hsp
, HSCX_RCVBUFREADY
);
359 if (val
& 0x10) { /* XPR */
361 if (hsp
->tx_skb
->len
) {
365 SET_SKB_FREE(hsp
->tx_skb
);
366 dev_kfree_skb(hsp
->tx_skb
, FREE_WRITE
);
368 if (hsp
->st
->l4
.l1writewakeup
)
369 hsp
->st
->l4
.l1writewakeup(hsp
->st
);
372 if ((hsp
->tx_skb
= skb_dequeue(&hsp
->squeue
))) {
376 hscx_sched_event(hsp
, HSCX_XMTBUFREADY
);
381 * ISAC stuff goes here
385 isac_empty_fifo(struct IsdnCardState
*sp
, int count
)
390 if ((sp
->debug
& L1_DEB_ISAC
) && !(sp
->debug
& L1_DEB_ISAC_FIFO
))
391 if (sp
->debug
& L1_DEB_ISAC
)
392 debugl1(sp
, "isac_empty_fifo");
394 if ((sp
->rcvidx
+ count
) >= MAX_DFRAME_LEN
) {
395 if (sp
->debug
& L1_DEB_WARN
) {
397 sprintf(tmp
, "isac_empty_fifo overrun %d",
401 IsacWriteReg(sp
->isac
, ISAC_CMDR
, 0x80);
405 ptr
= sp
->rcvbuf
+ sp
->rcvidx
;
409 IsacReadFifo(sp
->isac
, ptr
, count
);
410 IsacWriteReg(sp
->isac
, ISAC_CMDR
, 0x80);
411 restore_flags(flags
);
412 if (sp
->debug
& L1_DEB_ISAC_FIFO
) {
416 t
+= sprintf(t
, "isac_empty_fifo cnt %d", count
);
417 QuickHex(t
, ptr
, count
);
423 isac_fill_fifo(struct IsdnCardState
*sp
)
429 if ((sp
->debug
& L1_DEB_ISAC
) && !(sp
->debug
& L1_DEB_ISAC_FIFO
))
430 debugl1(sp
, "isac_fill_fifo");
435 count
= sp
->tx_skb
->len
;
446 ptr
= sp
->tx_skb
->data
;
447 skb_pull(sp
->tx_skb
, count
);
449 IsacWriteFifo(sp
->isac
, ptr
, count
);
450 IsacWriteReg(sp
->isac
, ISAC_CMDR
, more
? 0x8 : 0xa);
451 restore_flags(flags
);
452 if (sp
->debug
& L1_DEB_ISAC_FIFO
) {
456 t
+= sprintf(t
, "isac_fill_fifo cnt %d", count
);
457 QuickHex(t
, ptr
, count
);
463 ph_command(struct IsdnCardState
*sp
, unsigned int command
)
465 if (sp
->debug
& L1_DEB_ISAC
) {
467 sprintf(tmp
, "ph_command %d", command
);
470 IsacWriteReg(sp
->isac
, ISAC_CIX0
, (command
<< 2) | 3);
475 isac_interrupt(struct IsdnCardState
*sp
, u_char val
)
482 if (sp
->debug
& L1_DEB_ISAC
) {
483 sprintf(tmp
, "ISAC interrupt %x", val
);
486 if (val
& 0x80) { /* RME */
487 exval
= IsacReadReg(sp
->isac
, ISAC_RSTA
);
488 if ((exval
& 0x70) != 0x20) {
490 if (sp
->debug
& L1_DEB_WARN
)
491 debugl1(sp
, "ISAC RDO");
493 if (sp
->debug
& L1_DEB_WARN
)
494 debugl1(sp
, "ISAC CRC error");
495 IsacWriteReg(sp
->isac
, ISAC_CMDR
, 0x80);
497 count
= IsacReadReg(sp
->isac
, ISAC_RBCL
) & 0x1f;
500 isac_empty_fifo(sp
, count
);
501 if ((count
= sp
->rcvidx
) > 0) {
503 if (!(skb
= alloc_skb(count
, GFP_ATOMIC
)))
504 printk(KERN_WARNING
"IX1: D receive out of memory\n");
506 memcpy(skb_put(skb
, count
), sp
->rcvbuf
, count
);
507 skb_queue_tail(&sp
->rq
, skb
);
512 isac_sched_event(sp
, ISAC_RCVBUFREADY
);
514 if (val
& 0x40) { /* RPF */
515 isac_empty_fifo(sp
, 32);
517 if (val
& 0x20) { /* RSC */
519 if (sp
->debug
& L1_DEB_WARN
)
520 debugl1(sp
, "ISAC RSC interrupt");
522 if (val
& 0x10) { /* XPR */
524 if (sp
->tx_skb
->len
) {
528 SET_SKB_FREE(sp
->tx_skb
);
529 dev_kfree_skb(sp
->tx_skb
, FREE_WRITE
);
533 if ((sp
->tx_skb
= skb_dequeue(&sp
->sq
))) {
537 isac_sched_event(sp
, ISAC_XMTBUFREADY
);
540 if (val
& 0x04) { /* CISQ */
541 sp
->ph_state
= (IsacReadReg(sp
->isac
, ISAC_CIX0
) >> 2)
543 if (sp
->debug
& L1_DEB_ISAC
) {
544 sprintf(tmp
, "l1state %d", sp
->ph_state
);
549 if (val
& 0x02) { /* SIN */
551 if (sp
->debug
& L1_DEB_WARN
)
552 debugl1(sp
, "ISAC SIN interrupt");
554 if (val
& 0x01) { /* EXI */
555 exval
= IsacReadReg(sp
->isac
, ISAC_EXIR
);
556 if (sp
->debug
& L1_DEB_WARN
) {
557 sprintf(tmp
, "ISAC EXIR %02x", exval
);
564 hscx_int_main(struct IsdnCardState
*sp
, u_char val
)
568 struct HscxState
*hsp
;
574 exval
= HscxReadReg(sp
->hscx
[1], 1, HSCX_EXIR
);
579 /* Here we lost an TX interrupt, so
580 * restart transmitting the whole frame.
583 skb_push(hsp
->tx_skb
, hsp
->count
);
584 hsp
->tx_cnt
+= hsp
->count
;
587 writehscxCMDR(sp
->hscx
[hsp
->hscx
], hsp
->hscx
, 0x01);
588 if (sp
->debug
& L1_DEB_WARN
) {
589 sprintf(tmp
, "HSCX B EXIR %x Lost TX", exval
);
593 } else if (sp
->debug
& L1_DEB_HSCX
) {
594 sprintf(tmp
, "HSCX B EXIR %x", exval
);
599 if (sp
->debug
& L1_DEB_HSCX
) {
600 sprintf(tmp
, "HSCX B interrupt %x", val
);
603 hscx_interrupt(sp
, val
, 1);
607 exval
= HscxReadReg(sp
->hscx
[0], 0, HSCX_EXIR
);
612 /* Here we lost an TX interrupt, so
613 * restart transmitting the whole frame.
616 skb_push(hsp
->tx_skb
, hsp
->count
);
617 hsp
->tx_cnt
+= hsp
->count
;
620 writehscxCMDR(sp
->hscx
[hsp
->hscx
], hsp
->hscx
, 0x01);
621 if (sp
->debug
& L1_DEB_WARN
) {
622 sprintf(tmp
, "HSCX A EXIR %x Lost TX", exval
);
626 } else if (sp
->debug
& L1_DEB_HSCX
) {
627 sprintf(tmp
, "HSCX A EXIR %x", exval
);
632 exval
= HscxReadReg(sp
->hscx
[0], 0, HSCX_ISTA
);
633 if (sp
->debug
& L1_DEB_HSCX
) {
634 sprintf(tmp
, "HSCX A interrupt %x", exval
);
637 hscx_interrupt(sp
, exval
, 0);
642 ix1micro_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
644 struct IsdnCardState
*sp
;
645 u_char val
, stat
= 0;
647 sp
= (struct IsdnCardState
*) dev_id
;
650 printk(KERN_WARNING
"Teles: Spurious interrupt!\n");
653 val
= HscxReadReg(sp
->hscx
[1], 1, HSCX_ISTA
);
656 hscx_int_main(sp
, val
);
659 val
= IsacReadReg(sp
->isac
, ISAC_ISTA
);
662 isac_interrupt(sp
, val
);
665 val
= HscxReadReg(sp
->hscx
[1], 1, HSCX_ISTA
);
667 if (sp
->debug
& L1_DEB_HSCX
)
668 debugl1(sp
, "HSCX IntStat after IntRoutine");
671 val
= IsacReadReg(sp
->isac
, ISAC_ISTA
);
673 if (sp
->debug
& L1_DEB_ISAC
)
674 debugl1(sp
, "ISAC IntStat after IntRoutine");
678 HscxWriteReg(sp
->hscx
[0], 0, HSCX_MASK
, 0xFF);
679 HscxWriteReg(sp
->hscx
[1], 1, HSCX_MASK
, 0xFF);
680 HscxWriteReg(sp
->hscx
[0], 0, HSCX_MASK
, 0x0);
681 HscxWriteReg(sp
->hscx
[1], 1, HSCX_MASK
, 0x0);
684 IsacWriteReg(sp
->isac
, ISAC_MASK
, 0xFF);
685 IsacWriteReg(sp
->isac
, ISAC_MASK
, 0x0);
691 initisac(struct IsdnCardState
*sp
)
693 unsigned int adr
= sp
->isac
;
695 /* 16.3 IOM 2 Mode */
696 IsacWriteReg(adr
, ISAC_MASK
, 0xff);
697 IsacWriteReg(adr
, ISAC_ADF2
, 0x80);
698 IsacWriteReg(adr
, ISAC_SQXR
, 0x2f);
699 IsacWriteReg(adr
, ISAC_SPCR
, 0x0);
700 IsacWriteReg(adr
, ISAC_ADF1
, 0x2);
701 IsacWriteReg(adr
, ISAC_STCR
, 0x70);
702 IsacWriteReg(adr
, ISAC_MODE
, 0xc9);
703 IsacWriteReg(adr
, ISAC_TIMR
, 0x0);
704 IsacWriteReg(adr
, ISAC_ADF1
, 0x0);
705 IsacWriteReg(adr
, ISAC_CMDR
, 0x41);
706 IsacWriteReg(adr
, ISAC_CIX0
, (1 << 2) | 3);
707 IsacWriteReg(adr
, ISAC_MASK
, 0xff);
708 IsacWriteReg(adr
, ISAC_MASK
, 0x0);
712 modehscx(struct HscxState
*hs
, int mode
, int ichan
)
714 struct IsdnCardState
*sp
= hs
->sp
;
717 if (sp
->debug
& L1_DEB_HSCX
) {
719 sprintf(tmp
, "hscx %c mode %d ichan %d",
720 'A' + hscx
, mode
, ichan
);
724 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_CCR1
, 0x85);
725 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_XAD1
, 0xFF);
726 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_XAD2
, 0xFF);
727 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_RAH2
, 0xFF);
728 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_XBCH
, 0x0);
729 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_RLCR
, 0x0);
733 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_CCR2
, 0x30);
734 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_TSAX
, 0xff);
735 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_TSAR
, 0xff);
736 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_XCCR
, 7);
737 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_RCCR
, 7);
738 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_MODE
, 0x84);
742 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_CCR2
, 0x30);
743 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_TSAX
, 0x2f);
744 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_TSAR
, 0x2f);
745 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_XCCR
, 7);
746 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_RCCR
, 7);
748 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_CCR2
, 0x30);
749 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_TSAX
, 0x3);
750 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_TSAR
, 0x3);
751 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_XCCR
, 7);
752 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_RCCR
, 7);
754 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_MODE
, 0xe4);
755 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_CMDR
, 0x41);
759 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_CCR2
, 0x30);
760 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_TSAX
, 0x2f);
761 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_TSAR
, 0x2f);
762 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_XCCR
, 7);
763 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_RCCR
, 7);
765 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_CCR2
, 0x30);
766 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_TSAX
, 0x3);
767 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_TSAR
, 0x3);
768 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_XCCR
, 7);
769 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_RCCR
, 7);
771 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_MODE
, 0x8c);
772 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_CMDR
, 0x41);
775 HscxWriteReg(sp
->hscx
[hscx
], hscx
, HSCX_ISTA
, 0x00);
779 release_io_ix1micro(struct IsdnCard
*card
)
781 if (card
->sp
->cfg_reg
)
782 release_region(card
->sp
->cfg_reg
, 4);
786 clear_pending_ints(struct IsdnCardState
*sp
)
791 val
= HscxReadReg(sp
->hscx
[1], 1, HSCX_ISTA
);
792 sprintf(tmp
, "HSCX B ISTA %x", val
);
795 val
= HscxReadReg(sp
->hscx
[1], 1, HSCX_EXIR
);
796 sprintf(tmp
, "HSCX B EXIR %x", val
);
798 } else if (val
& 0x02) {
799 val
= HscxReadReg(sp
->hscx
[0], 0, HSCX_EXIR
);
800 sprintf(tmp
, "HSCX A EXIR %x", val
);
803 val
= HscxReadReg(sp
->hscx
[0], 0, HSCX_ISTA
);
804 sprintf(tmp
, "HSCX A ISTA %x", val
);
806 val
= HscxReadReg(sp
->hscx
[1], 1, HSCX_STAR
);
807 sprintf(tmp
, "HSCX B STAR %x", val
);
809 val
= HscxReadReg(sp
->hscx
[0], 0, HSCX_STAR
);
810 sprintf(tmp
, "HSCX A STAR %x", val
);
812 val
= IsacReadReg(sp
->isac
, ISAC_STAR
);
813 sprintf(tmp
, "ISAC STAR %x", val
);
815 val
= IsacReadReg(sp
->isac
, ISAC_MODE
);
816 sprintf(tmp
, "ISAC MODE %x", val
);
818 val
= IsacReadReg(sp
->isac
, ISAC_ADF2
);
819 sprintf(tmp
, "ISAC ADF2 %x", val
);
821 val
= IsacReadReg(sp
->isac
, ISAC_ISTA
);
822 sprintf(tmp
, "ISAC ISTA %x", val
);
825 val
= IsacReadReg(sp
->isac
, ISAC_EXIR
);
826 sprintf(tmp
, "ISAC EXIR %x", val
);
828 } else if (val
& 0x04) {
829 val
= IsacReadReg(sp
->isac
, ISAC_CIR0
);
830 sprintf(tmp
, "ISAC CIR0 %x", val
);
833 IsacWriteReg(sp
->isac
, ISAC_MASK
, 0);
834 IsacWriteReg(sp
->isac
, ISAC_CMDR
, 0x41);
838 initix1micro(struct IsdnCardState
*sp
)
844 sp
->counter
= kstat_irqs(sp
->irq
);
845 sprintf(tmp
, "IRQ %d count %d", sp
->irq
, sp
->counter
);
847 clear_pending_ints(sp
);
848 ret
= get_irq(sp
->cardnr
, &ix1micro_interrupt
);
851 sp
->modehscx(sp
->hs
, 0, 0);
852 sp
->modehscx(sp
->hs
+ 1, 0, 0);
853 while (loop
++ < 10) {
854 /* At least 1-3 irqs must happen
855 * (one from HSCX A, one from HSCX B, 3rd from ISAC)
857 if (kstat_irqs(sp
->irq
) > sp
->counter
)
859 current
->state
= TASK_INTERRUPTIBLE
;
860 current
->timeout
= jiffies
+ 1;
863 sprintf(tmp
, "IRQ %d count %d", sp
->irq
,
864 kstat_irqs(sp
->irq
));
866 if (kstat_irqs(sp
->irq
) == sp
->counter
) {
868 "ix1-Micro: IRQ(%d) getting no interrupts during init\n",
870 free_irq(sp
->irq
, sp
);
878 setup_ix1micro(struct IsdnCard
*card
)
880 u_char val
, verA
, verB
;
881 struct IsdnCardState
*sp
= card
->sp
;
885 strcpy(tmp
, ix1_revision
);
886 printk(KERN_NOTICE
"HiSax: ITK IX1 driver Rev. %s\n", HiSax_getrev(tmp
));
887 if (sp
->typ
!= ISDN_CTYPE_IX1MICROR2
)
891 sp
->isac
= sp
->hscx
[0] = sp
->hscx
[1] = sp
->cfg_reg
= card
->para
[1];
892 sp
->irq
= card
->para
[0];
894 if (check_region((sp
->cfg_reg
), 4)) {
896 "HiSax: %s config port %x-%x already in use\n",
902 request_region(sp
->cfg_reg
, 4, "ix1micro cfg");
906 val
= 3 * (HZ
/ 10) + 1;
909 byteout(sp
->cfg_reg
+ SPECIAL_PORT_OFFSET
, 1);
910 HZDELAY(1); /* wait >=10 ms */
912 byteout(sp
->cfg_reg
+ SPECIAL_PORT_OFFSET
, 0);
913 restore_flags(flags
);
916 "HiSax: %s config irq:%d io:0x%x\n",
917 CardType
[sp
->typ
], sp
->irq
,
919 verA
= HscxReadReg(sp
->hscx
[0], 0, HSCX_VSTR
) & 0xf;
920 verB
= HscxReadReg(sp
->hscx
[1], 1, HSCX_VSTR
) & 0xf;
921 printk(KERN_INFO
"ix1-Micro: HSCX version A: %s B: %s\n",
922 HscxVersion(verA
), HscxVersion(verB
));
923 val
= IsacReadReg(sp
->isac
, ISAC_RBCH
);
924 printk(KERN_INFO
"ix1-Micro: ISAC %s\n",
926 if ((verA
== 0) | (verA
== 0xf) | (verB
== 0) | (verB
== 0xf)) {
928 "ix1-Micro: wrong HSCX versions check IO address\n");
929 release_io_ix1micro(card
);
932 sp
->modehscx
= &modehscx
;
933 sp
->ph_command
= &ph_command
;
934 sp
->hscx_fill_fifo
= &hscx_fill_fifo
;
935 sp
->isac_fill_fifo
= &isac_fill_fifo
;