1 /* $Id: diva.c,v 1.25.6.2 2000/11/29 16:00:14 kai Exp $
3 * diva.c low level stuff for Eicon.Diehl Diva Family ISDN cards
5 * Author Karsten Keil (keil@isdn4linux.de)
7 * This file is (c) under GNU PUBLIC LICENSE
8 * For changes and modifications please read
9 * ../../../Documentation/isdn/HiSax.cert
11 * Thanks to Eicon Technology for documents and informations
15 #define __NO_VERSION__
16 #include <linux/init.h>
17 #include <linux/config.h>
23 #include <linux/pci.h>
25 extern const char *CardType
[];
27 const char *Diva_revision
= "$Revision: 1.25.6.2 $";
29 #define byteout(addr,val) outb(val,addr)
30 #define bytein(addr) inb(addr)
32 #define DIVA_HSCX_DATA 0
33 #define DIVA_HSCX_ADR 4
34 #define DIVA_ISA_ISAC_DATA 2
35 #define DIVA_ISA_ISAC_ADR 6
36 #define DIVA_ISA_CTRL 7
37 #define DIVA_IPAC_ADR 0
38 #define DIVA_IPAC_DATA 1
40 #define DIVA_PCI_ISAC_DATA 8
41 #define DIVA_PCI_ISAC_ADR 0xc
42 #define DIVA_PCI_CTRL 0x10
47 #define DIVA_IPAC_ISA 3
48 #define DIVA_IPAC_PCI 4
51 #define DIVA_IRQ_STAT 0x01
52 #define DIVA_EEPROM_SDA 0x02
55 #define DIVA_IRQ_REQ 0x01
56 #define DIVA_RESET 0x08
57 #define DIVA_EEPROM_CLK 0x40
58 #define DIVA_PCI_LED_A 0x10
59 #define DIVA_PCI_LED_B 0x20
60 #define DIVA_ISA_LED_A 0x20
61 #define DIVA_ISA_LED_B 0x40
62 #define DIVA_IRQ_CLR 0x80
65 #define PITA_MISC_REG 0x1c
67 #define PITA_PARA_SOFTRESET 0x00000001
68 #define PITA_PARA_MPX_MODE 0x00000004
69 #define PITA_INT0_ENABLE 0x00000200
71 #define PITA_PARA_SOFTRESET 0x01000000
72 #define PITA_PARA_MPX_MODE 0x04000000
73 #define PITA_INT0_ENABLE 0x00020000
75 #define PITA_INT0_STATUS 0x02
78 readreg(unsigned int ale
, unsigned int adr
, u_char off
)
92 readfifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
94 /* fifo read without cli because it's allready done */
97 insb(adr
, data
, size
);
102 writereg(unsigned int ale
, unsigned int adr
, u_char off
, u_char data
)
110 restore_flags(flags
);
114 writefifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
*data
, int size
)
116 /* fifo write without cli because it's allready done */
118 outsb(adr
, data
, size
);
122 memreadreg(unsigned long adr
, u_char off
)
124 return(*((unsigned char *)
125 (((unsigned int *)adr
) + off
)));
129 memwritereg(unsigned long adr
, u_char off
, u_char data
)
133 p
= (unsigned char *)(((unsigned int *)adr
) + off
);
137 /* Interface functions */
140 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
142 return(readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
));
146 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
148 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
, value
);
152 ReadISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
154 readfifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, 0, data
, size
);
158 WriteISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
160 writefifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, 0, data
, size
);
164 ReadISAC_IPAC(struct IsdnCardState
*cs
, u_char offset
)
166 return (readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
+0x80));
170 WriteISAC_IPAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
172 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
|0x80, value
);
176 ReadISACfifo_IPAC(struct IsdnCardState
*cs
, u_char
* data
, int size
)
178 readfifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, 0x80, data
, size
);
182 WriteISACfifo_IPAC(struct IsdnCardState
*cs
, u_char
* data
, int size
)
184 writefifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, 0x80, data
, size
);
188 ReadHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
)
190 return(readreg(cs
->hw
.diva
.hscx_adr
,
191 cs
->hw
.diva
.hscx
, offset
+ (hscx
? 0x40 : 0)));
195 WriteHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
, u_char value
)
197 writereg(cs
->hw
.diva
.hscx_adr
,
198 cs
->hw
.diva
.hscx
, offset
+ (hscx
? 0x40 : 0), value
);
202 MemReadISAC_IPAC(struct IsdnCardState
*cs
, u_char offset
)
204 return (memreadreg(cs
->hw
.diva
.cfg_reg
, offset
+0x80));
208 MemWriteISAC_IPAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
210 memwritereg(cs
->hw
.diva
.cfg_reg
, offset
|0x80, value
);
214 MemReadISACfifo_IPAC(struct IsdnCardState
*cs
, u_char
* data
, int size
)
217 *data
++ = memreadreg(cs
->hw
.diva
.cfg_reg
, 0x80);
221 MemWriteISACfifo_IPAC(struct IsdnCardState
*cs
, u_char
* data
, int size
)
224 memwritereg(cs
->hw
.diva
.cfg_reg
, 0x80, *data
++);
228 MemReadHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
)
230 return(memreadreg(cs
->hw
.diva
.cfg_reg
, offset
+ (hscx
? 0x40 : 0)));
234 MemWriteHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
, u_char value
)
236 memwritereg(cs
->hw
.diva
.cfg_reg
, offset
+ (hscx
? 0x40 : 0), value
);
240 * fast interrupt HSCX stuff goes here
243 #define READHSCX(cs, nr, reg) readreg(cs->hw.diva.hscx_adr, \
244 cs->hw.diva.hscx, reg + (nr ? 0x40 : 0))
245 #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.diva.hscx_adr, \
246 cs->hw.diva.hscx, reg + (nr ? 0x40 : 0), data)
248 #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.diva.hscx_adr, \
249 cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
251 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.diva.hscx_adr, \
252 cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
254 #include "hscx_irq.c"
257 diva_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
259 struct IsdnCardState
*cs
= dev_id
;
264 printk(KERN_WARNING
"Diva: Spurious interrupt!\n");
267 while (((sval
= bytein(cs
->hw
.diva
.ctrl
)) & DIVA_IRQ_REQ
) && cnt
) {
268 val
= readreg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, HSCX_ISTA
+ 0x40);
270 hscx_int_main(cs
, val
);
271 val
= readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, ISAC_ISTA
);
273 isac_interrupt(cs
, val
);
277 printk(KERN_WARNING
"Diva: IRQ LOOP\n");
278 writereg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, HSCX_MASK
, 0xFF);
279 writereg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, HSCX_MASK
+ 0x40, 0xFF);
280 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, ISAC_MASK
, 0xFF);
281 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, ISAC_MASK
, 0x0);
282 writereg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, HSCX_MASK
, 0x0);
283 writereg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, HSCX_MASK
+ 0x40, 0x0);
287 diva_irq_ipac_isa(int intno
, void *dev_id
, struct pt_regs
*regs
)
289 struct IsdnCardState
*cs
= dev_id
;
294 printk(KERN_WARNING
"Diva: Spurious interrupt!\n");
297 ista
= readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_ISTA
);
299 if (cs
->debug
& L1_DEB_IPAC
)
300 debugl1(cs
, "IPAC ISTA %02X", ista
);
302 val
= readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, HSCX_ISTA
+ 0x40);
310 hscx_int_main(cs
, val
);
313 val
= 0xfe & readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, ISAC_ISTA
+ 0x80);
315 isac_interrupt(cs
, val
);
320 isac_interrupt(cs
, val
);
322 ista
= readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_ISTA
);
323 if ((ista
& 0x3f) && icnt
) {
328 printk(KERN_WARNING
"DIVA IPAC IRQ LOOP\n");
329 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_MASK
, 0xFF);
330 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_MASK
, 0xC0);
334 MemwaitforCEC(struct IsdnCardState
*cs
, int hscx
)
338 while ((MemReadHSCX(cs
, hscx
, HSCX_STAR
) & 0x04) && to
) {
343 printk(KERN_WARNING
"HiSax: waitforCEC timeout\n");
348 MemwaitforXFW(struct IsdnCardState
*cs
, int hscx
)
352 while ((!(MemReadHSCX(cs
, hscx
, HSCX_STAR
) & 0x44) == 0x40) && to
) {
357 printk(KERN_WARNING
"HiSax: waitforXFW timeout\n");
361 MemWriteHSCXCMDR(struct IsdnCardState
*cs
, int hscx
, u_char data
)
367 MemwaitforCEC(cs
, hscx
);
368 MemWriteHSCX(cs
, hscx
, HSCX_CMDR
, data
);
369 restore_flags(flags
);
373 Memhscx_empty_fifo(struct BCState
*bcs
, int count
)
376 struct IsdnCardState
*cs
= bcs
->cs
;
380 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
381 debugl1(cs
, "hscx_empty_fifo");
383 if (bcs
->hw
.hscx
.rcvidx
+ count
> HSCX_BUFMAX
) {
384 if (cs
->debug
& L1_DEB_WARN
)
385 debugl1(cs
, "hscx_empty_fifo: incoming packet too large");
386 MemWriteHSCXCMDR(cs
, bcs
->hw
.hscx
.hscx
, 0x80);
387 bcs
->hw
.hscx
.rcvidx
= 0;
392 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
395 *ptr
++ = memreadreg(cs
->hw
.diva
.cfg_reg
, bcs
->hw
.hscx
.hscx
? 0x40 : 0);
396 MemWriteHSCXCMDR(cs
, bcs
->hw
.hscx
.hscx
, 0x80);
397 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
398 bcs
->hw
.hscx
.rcvidx
+= count
;
399 restore_flags(flags
);
400 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
403 t
+= sprintf(t
, "hscx_empty_fifo %c cnt %d",
404 bcs
->hw
.hscx
.hscx
? 'B' : 'A', count
);
405 QuickHex(t
, ptr
, count
);
406 debugl1(cs
, bcs
->blog
);
411 Memhscx_fill_fifo(struct BCState
*bcs
)
413 struct IsdnCardState
*cs
= bcs
->cs
;
414 int more
, count
, cnt
;
415 int fifo_size
= test_bit(HW_IPAC
, &cs
->HW_Flags
)? 64: 32;
420 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
421 debugl1(cs
, "hscx_fill_fifo");
425 if (bcs
->tx_skb
->len
<= 0)
428 more
= (bcs
->mode
== L1_MODE_TRANS
) ? 1 : 0;
429 if (bcs
->tx_skb
->len
> fifo_size
) {
433 count
= bcs
->tx_skb
->len
;
435 MemwaitforXFW(cs
, bcs
->hw
.hscx
.hscx
);
438 p
= ptr
= bcs
->tx_skb
->data
;
439 skb_pull(bcs
->tx_skb
, count
);
440 bcs
->tx_cnt
-= count
;
441 bcs
->hw
.hscx
.count
+= count
;
443 memwritereg(cs
->hw
.diva
.cfg_reg
, bcs
->hw
.hscx
.hscx
? 0x40 : 0,
445 MemWriteHSCXCMDR(cs
, bcs
->hw
.hscx
.hscx
, more
? 0x8 : 0xa);
446 restore_flags(flags
);
447 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
450 t
+= sprintf(t
, "hscx_fill_fifo %c cnt %d",
451 bcs
->hw
.hscx
.hscx
? 'B' : 'A', count
);
452 QuickHex(t
, ptr
, count
);
453 debugl1(cs
, bcs
->blog
);
458 Memhscx_interrupt(struct IsdnCardState
*cs
, u_char val
, u_char hscx
)
461 struct BCState
*bcs
= cs
->bcs
+ hscx
;
463 int fifo_size
= test_bit(HW_IPAC
, &cs
->HW_Flags
)? 64: 32;
466 if (!test_bit(BC_FLG_INIT
, &bcs
->Flag
))
469 if (val
& 0x80) { /* RME */
470 r
= MemReadHSCX(cs
, hscx
, HSCX_RSTA
);
471 if ((r
& 0xf0) != 0xa0) {
473 if (cs
->debug
& L1_DEB_WARN
)
474 debugl1(cs
, "HSCX invalid frame");
475 if ((r
& 0x40) && bcs
->mode
)
476 if (cs
->debug
& L1_DEB_WARN
)
477 debugl1(cs
, "HSCX RDO mode=%d",
480 if (cs
->debug
& L1_DEB_WARN
)
481 debugl1(cs
, "HSCX CRC error");
482 MemWriteHSCXCMDR(cs
, hscx
, 0x80);
484 count
= MemReadHSCX(cs
, hscx
, HSCX_RBCL
) & (
485 test_bit(HW_IPAC
, &cs
->HW_Flags
)? 0x3f: 0x1f);
488 Memhscx_empty_fifo(bcs
, count
);
489 if ((count
= bcs
->hw
.hscx
.rcvidx
- 1) > 0) {
490 if (cs
->debug
& L1_DEB_HSCX_FIFO
)
491 debugl1(cs
, "HX Frame %d", count
);
492 if (!(skb
= dev_alloc_skb(count
)))
493 printk(KERN_WARNING
"HSCX: receive out of memory\n");
495 memcpy(skb_put(skb
, count
), bcs
->hw
.hscx
.rcvbuf
, count
);
496 skb_queue_tail(&bcs
->rqueue
, skb
);
500 bcs
->hw
.hscx
.rcvidx
= 0;
501 hscx_sched_event(bcs
, B_RCVBUFREADY
);
503 if (val
& 0x40) { /* RPF */
504 Memhscx_empty_fifo(bcs
, fifo_size
);
505 if (bcs
->mode
== L1_MODE_TRANS
) {
506 /* receive audio data */
507 if (!(skb
= dev_alloc_skb(fifo_size
)))
508 printk(KERN_WARNING
"HiSax: receive out of memory\n");
510 memcpy(skb_put(skb
, fifo_size
), bcs
->hw
.hscx
.rcvbuf
, fifo_size
);
511 skb_queue_tail(&bcs
->rqueue
, skb
);
513 bcs
->hw
.hscx
.rcvidx
= 0;
514 hscx_sched_event(bcs
, B_RCVBUFREADY
);
517 if (val
& 0x10) { /* XPR */
519 if (bcs
->tx_skb
->len
) {
520 Memhscx_fill_fifo(bcs
);
523 if (bcs
->st
->lli
.l1writewakeup
&&
524 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
))
525 bcs
->st
->lli
.l1writewakeup(bcs
->st
, bcs
->hw
.hscx
.count
);
526 dev_kfree_skb_irq(bcs
->tx_skb
);
527 bcs
->hw
.hscx
.count
= 0;
531 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
532 bcs
->hw
.hscx
.count
= 0;
533 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
534 Memhscx_fill_fifo(bcs
);
536 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
537 hscx_sched_event(bcs
, B_XMTBUFREADY
);
543 Memhscx_int_main(struct IsdnCardState
*cs
, u_char val
)
551 exval
= MemReadHSCX(cs
, 1, HSCX_EXIR
);
554 Memhscx_fill_fifo(bcs
);
556 /* Here we lost an TX interrupt, so
557 * restart transmitting the whole frame.
560 skb_push(bcs
->tx_skb
, bcs
->hw
.hscx
.count
);
561 bcs
->tx_cnt
+= bcs
->hw
.hscx
.count
;
562 bcs
->hw
.hscx
.count
= 0;
564 MemWriteHSCXCMDR(cs
, bcs
->hw
.hscx
.hscx
, 0x01);
565 if (cs
->debug
& L1_DEB_WARN
)
566 debugl1(cs
, "HSCX B EXIR %x Lost TX", exval
);
568 } else if (cs
->debug
& L1_DEB_HSCX
)
569 debugl1(cs
, "HSCX B EXIR %x", exval
);
572 if (cs
->debug
& L1_DEB_HSCX
)
573 debugl1(cs
, "HSCX B interrupt %x", val
);
574 Memhscx_interrupt(cs
, val
, 1);
578 exval
= MemReadHSCX(cs
, 0, HSCX_EXIR
);
580 if (bcs
->mode
== L1_MODE_TRANS
)
581 Memhscx_fill_fifo(bcs
);
583 /* Here we lost an TX interrupt, so
584 * restart transmitting the whole frame.
587 skb_push(bcs
->tx_skb
, bcs
->hw
.hscx
.count
);
588 bcs
->tx_cnt
+= bcs
->hw
.hscx
.count
;
589 bcs
->hw
.hscx
.count
= 0;
591 MemWriteHSCXCMDR(cs
, bcs
->hw
.hscx
.hscx
, 0x01);
592 if (cs
->debug
& L1_DEB_WARN
)
593 debugl1(cs
, "HSCX A EXIR %x Lost TX", exval
);
595 } else if (cs
->debug
& L1_DEB_HSCX
)
596 debugl1(cs
, "HSCX A EXIR %x", exval
);
599 exval
= MemReadHSCX(cs
, 0, HSCX_ISTA
);
600 if (cs
->debug
& L1_DEB_HSCX
)
601 debugl1(cs
, "HSCX A interrupt %x", exval
);
602 Memhscx_interrupt(cs
, exval
, 0);
607 diva_irq_ipac_pci(int intno
, void *dev_id
, struct pt_regs
*regs
)
609 struct IsdnCardState
*cs
= dev_id
;
615 printk(KERN_WARNING
"Diva: Spurious interrupt!\n");
618 cfg
= (u_char
*) cs
->hw
.diva
.pci_cfg
;
620 if (!(val
& PITA_INT0_STATUS
))
621 return; /* other shared IRQ */
622 *cfg
= PITA_INT0_STATUS
; /* Reset pending INT0 */
623 ista
= memreadreg(cs
->hw
.diva
.cfg_reg
, IPAC_ISTA
);
625 if (cs
->debug
& L1_DEB_IPAC
)
626 debugl1(cs
, "IPAC ISTA %02X", ista
);
628 val
= memreadreg(cs
->hw
.diva
.cfg_reg
, HSCX_ISTA
+ 0x40);
636 Memhscx_int_main(cs
, val
);
639 val
= 0xfe & memreadreg(cs
->hw
.diva
.cfg_reg
, ISAC_ISTA
+ 0x80);
641 isac_interrupt(cs
, val
);
646 isac_interrupt(cs
, val
);
648 ista
= memreadreg(cs
->hw
.diva
.cfg_reg
, IPAC_ISTA
);
649 if ((ista
& 0x3f) && icnt
) {
654 printk(KERN_WARNING
"DIVA IPAC PCI IRQ LOOP\n");
655 memwritereg(cs
->hw
.diva
.cfg_reg
, IPAC_MASK
, 0xFF);
656 memwritereg(cs
->hw
.diva
.cfg_reg
, IPAC_MASK
, 0xC0);
660 release_io_diva(struct IsdnCardState
*cs
)
664 if (cs
->subtyp
== DIVA_IPAC_PCI
) {
665 u_int
*cfg
= (unsigned int *)cs
->hw
.diva
.pci_cfg
;
667 *cfg
= 0; /* disable INT0/1 */
668 *cfg
= 2; /* reset pending INT0 */
669 iounmap((void *)cs
->hw
.diva
.cfg_reg
);
670 iounmap((void *)cs
->hw
.diva
.pci_cfg
);
672 } else if (cs
->subtyp
!= DIVA_IPAC_ISA
) {
673 del_timer(&cs
->hw
.diva
.tl
);
674 if (cs
->hw
.diva
.cfg_reg
)
675 byteout(cs
->hw
.diva
.ctrl
, 0); /* LED off, Reset */
677 if ((cs
->subtyp
== DIVA_ISA
) || (cs
->subtyp
== DIVA_IPAC_ISA
))
681 if (cs
->hw
.diva
.cfg_reg
) {
682 release_region(cs
->hw
.diva
.cfg_reg
, bytecnt
);
687 reset_diva(struct IsdnCardState
*cs
)
693 if (cs
->subtyp
== DIVA_IPAC_ISA
) {
694 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_POTA2
, 0x20);
695 set_current_state(TASK_UNINTERRUPTIBLE
);
696 schedule_timeout((10*HZ
)/1000);
697 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_POTA2
, 0x00);
698 set_current_state(TASK_UNINTERRUPTIBLE
);
699 schedule_timeout((10*HZ
)/1000);
700 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_MASK
, 0xc0);
701 } else if (cs
->subtyp
== DIVA_IPAC_PCI
) {
702 unsigned int *ireg
= (unsigned int *)(cs
->hw
.diva
.pci_cfg
+
704 *ireg
= PITA_PARA_SOFTRESET
| PITA_PARA_MPX_MODE
;
705 set_current_state(TASK_UNINTERRUPTIBLE
);
706 schedule_timeout((10*HZ
)/1000);
707 *ireg
= PITA_PARA_MPX_MODE
;
708 set_current_state(TASK_UNINTERRUPTIBLE
);
709 schedule_timeout((10*HZ
)/1000);
710 memwritereg(cs
->hw
.diva
.cfg_reg
, IPAC_MASK
, 0xc0);
711 } else { /* DIVA 2.0 */
712 cs
->hw
.diva
.ctrl_reg
= 0; /* Reset On */
713 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
714 set_current_state(TASK_UNINTERRUPTIBLE
);
715 schedule_timeout((10*HZ
)/1000);
716 cs
->hw
.diva
.ctrl_reg
|= DIVA_RESET
; /* Reset Off */
717 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
718 set_current_state(TASK_UNINTERRUPTIBLE
);
719 schedule_timeout((10*HZ
)/1000);
720 if (cs
->subtyp
== DIVA_ISA
)
721 cs
->hw
.diva
.ctrl_reg
|= DIVA_ISA_LED_A
;
723 /* Workaround PCI9060 */
724 byteout(cs
->hw
.diva
.pci_cfg
+ 0x69, 9);
725 cs
->hw
.diva
.ctrl_reg
|= DIVA_PCI_LED_A
;
727 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
729 restore_flags(flags
);
732 #define DIVA_ASSIGN 1
735 diva_led_handler(struct IsdnCardState
*cs
)
739 if ((cs
->subtyp
== DIVA_IPAC_ISA
) || (cs
->subtyp
== DIVA_IPAC_PCI
))
741 del_timer(&cs
->hw
.diva
.tl
);
742 if (cs
->hw
.diva
.status
& DIVA_ASSIGN
)
743 cs
->hw
.diva
.ctrl_reg
|= (DIVA_ISA
== cs
->subtyp
) ?
744 DIVA_ISA_LED_A
: DIVA_PCI_LED_A
;
746 cs
->hw
.diva
.ctrl_reg
^= (DIVA_ISA
== cs
->subtyp
) ?
747 DIVA_ISA_LED_A
: DIVA_PCI_LED_A
;
750 if (cs
->hw
.diva
.status
& 0xf000)
751 cs
->hw
.diva
.ctrl_reg
|= (DIVA_ISA
== cs
->subtyp
) ?
752 DIVA_ISA_LED_B
: DIVA_PCI_LED_B
;
753 else if (cs
->hw
.diva
.status
& 0x0f00) {
754 cs
->hw
.diva
.ctrl_reg
^= (DIVA_ISA
== cs
->subtyp
) ?
755 DIVA_ISA_LED_B
: DIVA_PCI_LED_B
;
758 cs
->hw
.diva
.ctrl_reg
&= ~((DIVA_ISA
== cs
->subtyp
) ?
759 DIVA_ISA_LED_B
: DIVA_PCI_LED_B
);
761 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
763 init_timer(&cs
->hw
.diva
.tl
);
764 cs
->hw
.diva
.tl
.expires
= jiffies
+ ((blink
* HZ
) / 1000);
765 add_timer(&cs
->hw
.diva
.tl
);
770 Diva_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
782 if (cs
->subtyp
== DIVA_IPAC_PCI
) {
783 ireg
= (unsigned int *)cs
->hw
.diva
.pci_cfg
;
784 *ireg
= PITA_INT0_ENABLE
;
790 case (MDL_REMOVE
| REQUEST
):
791 cs
->hw
.diva
.status
= 0;
793 case (MDL_ASSIGN
| REQUEST
):
794 cs
->hw
.diva
.status
|= DIVA_ASSIGN
;
798 cs
->hw
.diva
.status
|= 0x0200;
800 cs
->hw
.diva
.status
|= 0x0100;
804 cs
->hw
.diva
.status
|= 0x2000;
806 cs
->hw
.diva
.status
|= 0x1000;
810 cs
->hw
.diva
.status
&= ~0x2000;
811 cs
->hw
.diva
.status
&= ~0x0200;
813 cs
->hw
.diva
.status
&= ~0x1000;
814 cs
->hw
.diva
.status
&= ~0x0100;
818 if ((cs
->subtyp
!= DIVA_IPAC_ISA
) && (cs
->subtyp
!= DIVA_IPAC_PCI
))
819 diva_led_handler(cs
);
823 static struct pci_dev
*dev_diva __initdata
= NULL
;
824 static struct pci_dev
*dev_diva_u __initdata
= NULL
;
825 static struct pci_dev
*dev_diva201 __initdata
= NULL
;
828 setup_diva(struct IsdnCard
*card
)
832 struct IsdnCardState
*cs
= card
->cs
;
835 strcpy(tmp
, Diva_revision
);
836 printk(KERN_INFO
"HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp
));
837 if (cs
->typ
!= ISDN_CTYPE_DIEHLDIVA
)
839 cs
->hw
.diva
.status
= 0;
841 cs
->hw
.diva
.ctrl_reg
= 0;
842 cs
->hw
.diva
.cfg_reg
= card
->para
[1];
843 val
= readreg(cs
->hw
.diva
.cfg_reg
+ DIVA_IPAC_ADR
,
844 cs
->hw
.diva
.cfg_reg
+ DIVA_IPAC_DATA
, IPAC_ID
);
845 printk(KERN_INFO
"Diva: IPAC version %x\n", val
);
846 if ((val
== 1) || (val
==2)) {
847 cs
->subtyp
= DIVA_IPAC_ISA
;
848 cs
->hw
.diva
.ctrl
= 0;
849 cs
->hw
.diva
.isac
= card
->para
[1] + DIVA_IPAC_DATA
;
850 cs
->hw
.diva
.hscx
= card
->para
[1] + DIVA_IPAC_DATA
;
851 cs
->hw
.diva
.isac_adr
= card
->para
[1] + DIVA_IPAC_ADR
;
852 cs
->hw
.diva
.hscx_adr
= card
->para
[1] + DIVA_IPAC_ADR
;
853 test_and_set_bit(HW_IPAC
, &cs
->HW_Flags
);
855 cs
->subtyp
= DIVA_ISA
;
856 cs
->hw
.diva
.ctrl
= card
->para
[1] + DIVA_ISA_CTRL
;
857 cs
->hw
.diva
.isac
= card
->para
[1] + DIVA_ISA_ISAC_DATA
;
858 cs
->hw
.diva
.hscx
= card
->para
[1] + DIVA_HSCX_DATA
;
859 cs
->hw
.diva
.isac_adr
= card
->para
[1] + DIVA_ISA_ISAC_ADR
;
860 cs
->hw
.diva
.hscx_adr
= card
->para
[1] + DIVA_HSCX_ADR
;
862 cs
->irq
= card
->para
[0];
866 if (!pci_present()) {
867 printk(KERN_ERR
"Diva: no PCI bus present\n");
872 if ((dev_diva
= pci_find_device(PCI_VENDOR_ID_EICON
,
873 PCI_DEVICE_ID_EICON_DIVA20
, dev_diva
))) {
874 if (pci_enable_device(dev_diva
))
876 cs
->subtyp
= DIVA_PCI
;
877 cs
->irq
= dev_diva
->irq
;
878 cs
->hw
.diva
.cfg_reg
= pci_resource_start(dev_diva
, 2);
879 } else if ((dev_diva_u
= pci_find_device(PCI_VENDOR_ID_EICON
,
880 PCI_DEVICE_ID_EICON_DIVA20_U
, dev_diva_u
))) {
881 if (pci_enable_device(dev_diva_u
))
883 cs
->subtyp
= DIVA_PCI
;
884 cs
->irq
= dev_diva_u
->irq
;
885 cs
->hw
.diva
.cfg_reg
= pci_resource_start(dev_diva_u
, 2);
886 } else if ((dev_diva201
= pci_find_device(PCI_VENDOR_ID_EICON
,
887 PCI_DEVICE_ID_EICON_DIVA201
, dev_diva201
))) {
888 if (pci_enable_device(dev_diva201
))
890 cs
->subtyp
= DIVA_IPAC_PCI
;
891 cs
->irq
= dev_diva201
->irq
;
892 cs
->hw
.diva
.pci_cfg
=
893 (ulong
) ioremap(pci_resource_start(dev_diva201
, 0), 4096);
894 cs
->hw
.diva
.cfg_reg
=
895 (ulong
) ioremap(pci_resource_start(dev_diva201
, 1), 4096);
897 printk(KERN_WARNING
"Diva: No PCI card found\n");
902 printk(KERN_WARNING
"Diva: No IRQ for PCI card found\n");
906 if (!cs
->hw
.diva
.cfg_reg
) {
907 printk(KERN_WARNING
"Diva: No IO-Adr for PCI card found\n");
910 cs
->irq_flags
|= SA_SHIRQ
;
912 printk(KERN_WARNING
"Diva: cfgreg 0 and NO_PCI_BIOS\n");
913 printk(KERN_WARNING
"Diva: unable to config DIVA PCI\n");
915 #endif /* CONFIG_PCI */
916 if (cs
->subtyp
== DIVA_IPAC_PCI
) {
917 cs
->hw
.diva
.ctrl
= 0;
918 cs
->hw
.diva
.isac
= 0;
919 cs
->hw
.diva
.hscx
= 0;
920 cs
->hw
.diva
.isac_adr
= 0;
921 cs
->hw
.diva
.hscx_adr
= 0;
922 test_and_set_bit(HW_IPAC
, &cs
->HW_Flags
);
925 cs
->hw
.diva
.ctrl
= cs
->hw
.diva
.cfg_reg
+ DIVA_PCI_CTRL
;
926 cs
->hw
.diva
.isac
= cs
->hw
.diva
.cfg_reg
+ DIVA_PCI_ISAC_DATA
;
927 cs
->hw
.diva
.hscx
= cs
->hw
.diva
.cfg_reg
+ DIVA_HSCX_DATA
;
928 cs
->hw
.diva
.isac_adr
= cs
->hw
.diva
.cfg_reg
+ DIVA_PCI_ISAC_ADR
;
929 cs
->hw
.diva
.hscx_adr
= cs
->hw
.diva
.cfg_reg
+ DIVA_HSCX_ADR
;
935 "Diva: %s card configured at %#lx IRQ %d\n",
936 (cs
->subtyp
== DIVA_PCI
) ? "PCI" :
937 (cs
->subtyp
== DIVA_ISA
) ? "ISA" :
938 (cs
->subtyp
== DIVA_IPAC_ISA
) ? "IPAC ISA" : "IPAC PCI",
939 cs
->hw
.diva
.cfg_reg
, cs
->irq
);
940 if ((cs
->subtyp
== DIVA_IPAC_PCI
) || (cs
->subtyp
== DIVA_PCI
))
941 printk(KERN_INFO
"Diva: %s PCI space at %#lx\n",
942 (cs
->subtyp
== DIVA_PCI
) ? "PCI" : "IPAC PCI",
943 cs
->hw
.diva
.pci_cfg
);
944 if (cs
->subtyp
!= DIVA_IPAC_PCI
) {
945 if (check_region(cs
->hw
.diva
.cfg_reg
, bytecnt
)) {
947 "HiSax: %s config port %lx-%lx already in use\n",
950 cs
->hw
.diva
.cfg_reg
+ bytecnt
);
953 request_region(cs
->hw
.diva
.cfg_reg
, bytecnt
, "diva isdn");
957 cs
->BC_Read_Reg
= &ReadHSCX
;
958 cs
->BC_Write_Reg
= &WriteHSCX
;
959 cs
->BC_Send_Data
= &hscx_fill_fifo
;
960 cs
->cardmsg
= &Diva_card_msg
;
961 if (cs
->subtyp
== DIVA_IPAC_ISA
) {
962 cs
->readisac
= &ReadISAC_IPAC
;
963 cs
->writeisac
= &WriteISAC_IPAC
;
964 cs
->readisacfifo
= &ReadISACfifo_IPAC
;
965 cs
->writeisacfifo
= &WriteISACfifo_IPAC
;
966 cs
->irq_func
= &diva_irq_ipac_isa
;
967 val
= readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_ID
);
968 printk(KERN_INFO
"Diva: IPAC version %x\n", val
);
969 } else if (cs
->subtyp
== DIVA_IPAC_PCI
) {
970 cs
->readisac
= &MemReadISAC_IPAC
;
971 cs
->writeisac
= &MemWriteISAC_IPAC
;
972 cs
->readisacfifo
= &MemReadISACfifo_IPAC
;
973 cs
->writeisacfifo
= &MemWriteISACfifo_IPAC
;
974 cs
->BC_Read_Reg
= &MemReadHSCX
;
975 cs
->BC_Write_Reg
= &MemWriteHSCX
;
976 cs
->BC_Send_Data
= &Memhscx_fill_fifo
;
977 cs
->irq_func
= &diva_irq_ipac_pci
;
978 val
= memreadreg(cs
->hw
.diva
.cfg_reg
, IPAC_ID
);
979 printk(KERN_INFO
"Diva: IPAC version %x\n", val
);
980 } else { /* DIVA 2.0 */
981 cs
->hw
.diva
.tl
.function
= (void *) diva_led_handler
;
982 cs
->hw
.diva
.tl
.data
= (long) cs
;
983 init_timer(&cs
->hw
.diva
.tl
);
984 cs
->readisac
= &ReadISAC
;
985 cs
->writeisac
= &WriteISAC
;
986 cs
->readisacfifo
= &ReadISACfifo
;
987 cs
->writeisacfifo
= &WriteISACfifo
;
988 cs
->irq_func
= &diva_interrupt
;
989 ISACVersion(cs
, "Diva:");
990 if (HscxVersion(cs
, "Diva:")) {
992 "Diva: wrong HSCX versions check IO address\n");