1 /* $Id: diva.c,v 1.21 2000/06/26 08:59:12 keil 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/config.h>
22 #include <linux/pci.h>
24 extern const char *CardType
[];
26 const char *Diva_revision
= "$Revision: 1.21 $";
28 #define byteout(addr,val) outb(val,addr)
29 #define bytein(addr) inb(addr)
31 #define DIVA_HSCX_DATA 0
32 #define DIVA_HSCX_ADR 4
33 #define DIVA_ISA_ISAC_DATA 2
34 #define DIVA_ISA_ISAC_ADR 6
35 #define DIVA_ISA_CTRL 7
36 #define DIVA_IPAC_ADR 0
37 #define DIVA_IPAC_DATA 1
39 #define DIVA_PCI_ISAC_DATA 8
40 #define DIVA_PCI_ISAC_ADR 0xc
41 #define DIVA_PCI_CTRL 0x10
46 #define DIVA_IPAC_ISA 3
47 #define DIVA_IPAC_PCI 4
50 #ifndef PCI_VENDOR_ID_EICON
51 #define PCI_VENDOR_ID_EICON 0x1133
53 #ifndef PCI_DEVICE_ID_EICON_DIVA20
54 #define PCI_DEVICE_ID_EICON_DIVA20 0xe002
56 #ifndef PCI_DEVICE_ID_EICON_DIVA20_U
57 #define PCI_DEVICE_ID_EICON_DIVA20_U 0xe004
59 #ifndef PCI_DEVICE_ID_EICON_DIVA201
60 #define PCI_DEVICE_ID_EICON_DIVA201 0xe005
64 #define DIVA_IRQ_STAT 0x01
65 #define DIVA_EEPROM_SDA 0x02
68 #define DIVA_IRQ_REQ 0x01
69 #define DIVA_RESET 0x08
70 #define DIVA_EEPROM_CLK 0x40
71 #define DIVA_PCI_LED_A 0x10
72 #define DIVA_PCI_LED_B 0x20
73 #define DIVA_ISA_LED_A 0x20
74 #define DIVA_ISA_LED_B 0x40
75 #define DIVA_IRQ_CLR 0x80
78 #define PITA_MISC_REG 0x1c
80 #define PITA_PARA_SOFTRESET 0x00000001
81 #define PITA_PARA_MPX_MODE 0x00000004
82 #define PITA_INT0_ENABLE 0x00000200
84 #define PITA_PARA_SOFTRESET 0x01000000
85 #define PITA_PARA_MPX_MODE 0x04000000
86 #define PITA_INT0_ENABLE 0x00020000
88 #define PITA_INT0_STATUS 0x02
91 readreg(unsigned int ale
, unsigned int adr
, u_char off
)
100 restore_flags(flags
);
105 readfifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
107 /* fifo read without cli because it's allready done */
110 insb(adr
, data
, size
);
115 writereg(unsigned int ale
, unsigned int adr
, u_char off
, u_char data
)
123 restore_flags(flags
);
127 writefifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
*data
, int size
)
129 /* fifo write without cli because it's allready done */
131 outsb(adr
, data
, size
);
135 memreadreg(unsigned long adr
, u_char off
)
137 return(*((unsigned char *)
138 (((unsigned int *)adr
) + off
)));
142 memwritereg(unsigned long adr
, u_char off
, u_char data
)
146 p
= (unsigned char *)(((unsigned int *)adr
) + off
);
150 /* Interface functions */
153 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
155 return(readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
));
159 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
161 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
, value
);
165 ReadISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
167 readfifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, 0, data
, size
);
171 WriteISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
173 writefifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, 0, data
, size
);
177 ReadISAC_IPAC(struct IsdnCardState
*cs
, u_char offset
)
179 return (readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
+0x80));
183 WriteISAC_IPAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
185 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
|0x80, value
);
189 ReadISACfifo_IPAC(struct IsdnCardState
*cs
, u_char
* data
, int size
)
191 readfifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, 0x80, data
, size
);
195 WriteISACfifo_IPAC(struct IsdnCardState
*cs
, u_char
* data
, int size
)
197 writefifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, 0x80, data
, size
);
201 ReadHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
)
203 return(readreg(cs
->hw
.diva
.hscx_adr
,
204 cs
->hw
.diva
.hscx
, offset
+ (hscx
? 0x40 : 0)));
208 WriteHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
, u_char value
)
210 writereg(cs
->hw
.diva
.hscx_adr
,
211 cs
->hw
.diva
.hscx
, offset
+ (hscx
? 0x40 : 0), value
);
215 MemReadISAC_IPAC(struct IsdnCardState
*cs
, u_char offset
)
217 return (memreadreg(cs
->hw
.diva
.cfg_reg
, offset
+0x80));
221 MemWriteISAC_IPAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
223 memwritereg(cs
->hw
.diva
.cfg_reg
, offset
|0x80, value
);
227 MemReadISACfifo_IPAC(struct IsdnCardState
*cs
, u_char
* data
, int size
)
230 *data
++ = memreadreg(cs
->hw
.diva
.cfg_reg
, 0x80);
234 MemWriteISACfifo_IPAC(struct IsdnCardState
*cs
, u_char
* data
, int size
)
237 memwritereg(cs
->hw
.diva
.cfg_reg
, 0x80, *data
++);
241 MemReadHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
)
243 return(memreadreg(cs
->hw
.diva
.cfg_reg
, offset
+ (hscx
? 0x40 : 0)));
247 MemWriteHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
, u_char value
)
249 memwritereg(cs
->hw
.diva
.cfg_reg
, offset
+ (hscx
? 0x40 : 0), value
);
253 * fast interrupt HSCX stuff goes here
256 #define READHSCX(cs, nr, reg) readreg(cs->hw.diva.hscx_adr, \
257 cs->hw.diva.hscx, reg + (nr ? 0x40 : 0))
258 #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.diva.hscx_adr, \
259 cs->hw.diva.hscx, reg + (nr ? 0x40 : 0), data)
261 #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.diva.hscx_adr, \
262 cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
264 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.diva.hscx_adr, \
265 cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
267 #include "hscx_irq.c"
270 diva_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
272 struct IsdnCardState
*cs
= dev_id
;
277 printk(KERN_WARNING
"Diva: Spurious interrupt!\n");
280 while (((sval
= bytein(cs
->hw
.diva
.ctrl
)) & DIVA_IRQ_REQ
) && cnt
) {
281 val
= readreg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, HSCX_ISTA
+ 0x40);
283 hscx_int_main(cs
, val
);
284 val
= readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, ISAC_ISTA
);
286 isac_interrupt(cs
, val
);
290 printk(KERN_WARNING
"Diva: IRQ LOOP\n");
291 writereg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, HSCX_MASK
, 0xFF);
292 writereg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, HSCX_MASK
+ 0x40, 0xFF);
293 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, ISAC_MASK
, 0xFF);
294 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, ISAC_MASK
, 0x0);
295 writereg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, HSCX_MASK
, 0x0);
296 writereg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, HSCX_MASK
+ 0x40, 0x0);
300 diva_irq_ipac_isa(int intno
, void *dev_id
, struct pt_regs
*regs
)
302 struct IsdnCardState
*cs
= dev_id
;
307 printk(KERN_WARNING
"Diva: Spurious interrupt!\n");
310 ista
= readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_ISTA
);
312 if (cs
->debug
& L1_DEB_IPAC
)
313 debugl1(cs
, "IPAC ISTA %02X", ista
);
315 val
= readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, HSCX_ISTA
+ 0x40);
323 hscx_int_main(cs
, val
);
326 val
= 0xfe & readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, ISAC_ISTA
+ 0x80);
328 isac_interrupt(cs
, val
);
333 isac_interrupt(cs
, val
);
335 ista
= readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_ISTA
);
336 if ((ista
& 0x3f) && icnt
) {
341 printk(KERN_WARNING
"DIVA IPAC IRQ LOOP\n");
342 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_MASK
, 0xFF);
343 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_MASK
, 0xC0);
347 MemwaitforCEC(struct IsdnCardState
*cs
, int hscx
)
351 while ((MemReadHSCX(cs
, hscx
, HSCX_STAR
) & 0x04) && to
) {
356 printk(KERN_WARNING
"HiSax: waitforCEC timeout\n");
361 MemwaitforXFW(struct IsdnCardState
*cs
, int hscx
)
365 while ((!(MemReadHSCX(cs
, hscx
, HSCX_STAR
) & 0x44) == 0x40) && to
) {
370 printk(KERN_WARNING
"HiSax: waitforXFW timeout\n");
374 MemWriteHSCXCMDR(struct IsdnCardState
*cs
, int hscx
, u_char data
)
380 MemwaitforCEC(cs
, hscx
);
381 MemWriteHSCX(cs
, hscx
, HSCX_CMDR
, data
);
382 restore_flags(flags
);
386 Memhscx_empty_fifo(struct BCState
*bcs
, int count
)
389 struct IsdnCardState
*cs
= bcs
->cs
;
393 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
394 debugl1(cs
, "hscx_empty_fifo");
396 if (bcs
->hw
.hscx
.rcvidx
+ count
> HSCX_BUFMAX
) {
397 if (cs
->debug
& L1_DEB_WARN
)
398 debugl1(cs
, "hscx_empty_fifo: incoming packet too large");
399 MemWriteHSCXCMDR(cs
, bcs
->hw
.hscx
.hscx
, 0x80);
400 bcs
->hw
.hscx
.rcvidx
= 0;
405 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
408 *ptr
++ = memreadreg(cs
->hw
.diva
.cfg_reg
, bcs
->hw
.hscx
.hscx
? 0x40 : 0);
409 MemWriteHSCXCMDR(cs
, bcs
->hw
.hscx
.hscx
, 0x80);
410 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
411 bcs
->hw
.hscx
.rcvidx
+= count
;
412 restore_flags(flags
);
413 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
416 t
+= sprintf(t
, "hscx_empty_fifo %c cnt %d",
417 bcs
->hw
.hscx
.hscx
? 'B' : 'A', count
);
418 QuickHex(t
, ptr
, count
);
419 debugl1(cs
, bcs
->blog
);
424 Memhscx_fill_fifo(struct BCState
*bcs
)
426 struct IsdnCardState
*cs
= bcs
->cs
;
427 int more
, count
, cnt
;
428 int fifo_size
= test_bit(HW_IPAC
, &cs
->HW_Flags
)? 64: 32;
433 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
434 debugl1(cs
, "hscx_fill_fifo");
438 if (bcs
->tx_skb
->len
<= 0)
441 more
= (bcs
->mode
== L1_MODE_TRANS
) ? 1 : 0;
442 if (bcs
->tx_skb
->len
> fifo_size
) {
446 count
= bcs
->tx_skb
->len
;
448 MemwaitforXFW(cs
, bcs
->hw
.hscx
.hscx
);
451 p
= ptr
= bcs
->tx_skb
->data
;
452 skb_pull(bcs
->tx_skb
, count
);
453 bcs
->tx_cnt
-= count
;
454 bcs
->hw
.hscx
.count
+= count
;
456 memwritereg(cs
->hw
.diva
.cfg_reg
, bcs
->hw
.hscx
.hscx
? 0x40 : 0,
458 MemWriteHSCXCMDR(cs
, bcs
->hw
.hscx
.hscx
, more
? 0x8 : 0xa);
459 restore_flags(flags
);
460 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
463 t
+= sprintf(t
, "hscx_fill_fifo %c cnt %d",
464 bcs
->hw
.hscx
.hscx
? 'B' : 'A', count
);
465 QuickHex(t
, ptr
, count
);
466 debugl1(cs
, bcs
->blog
);
471 Memhscx_interrupt(struct IsdnCardState
*cs
, u_char val
, u_char hscx
)
474 struct BCState
*bcs
= cs
->bcs
+ hscx
;
476 int fifo_size
= test_bit(HW_IPAC
, &cs
->HW_Flags
)? 64: 32;
479 if (!test_bit(BC_FLG_INIT
, &bcs
->Flag
))
482 if (val
& 0x80) { /* RME */
483 r
= MemReadHSCX(cs
, hscx
, HSCX_RSTA
);
484 if ((r
& 0xf0) != 0xa0) {
486 if (cs
->debug
& L1_DEB_WARN
)
487 debugl1(cs
, "HSCX invalid frame");
488 if ((r
& 0x40) && bcs
->mode
)
489 if (cs
->debug
& L1_DEB_WARN
)
490 debugl1(cs
, "HSCX RDO mode=%d",
493 if (cs
->debug
& L1_DEB_WARN
)
494 debugl1(cs
, "HSCX CRC error");
495 MemWriteHSCXCMDR(cs
, hscx
, 0x80);
497 count
= MemReadHSCX(cs
, hscx
, HSCX_RBCL
) & (
498 test_bit(HW_IPAC
, &cs
->HW_Flags
)? 0x3f: 0x1f);
501 Memhscx_empty_fifo(bcs
, count
);
502 if ((count
= bcs
->hw
.hscx
.rcvidx
- 1) > 0) {
503 if (cs
->debug
& L1_DEB_HSCX_FIFO
)
504 debugl1(cs
, "HX Frame %d", count
);
505 if (!(skb
= dev_alloc_skb(count
)))
506 printk(KERN_WARNING
"HSCX: receive out of memory\n");
508 memcpy(skb_put(skb
, count
), bcs
->hw
.hscx
.rcvbuf
, count
);
509 skb_queue_tail(&bcs
->rqueue
, skb
);
513 bcs
->hw
.hscx
.rcvidx
= 0;
514 hscx_sched_event(bcs
, B_RCVBUFREADY
);
516 if (val
& 0x40) { /* RPF */
517 Memhscx_empty_fifo(bcs
, fifo_size
);
518 if (bcs
->mode
== L1_MODE_TRANS
) {
519 /* receive audio data */
520 if (!(skb
= dev_alloc_skb(fifo_size
)))
521 printk(KERN_WARNING
"HiSax: receive out of memory\n");
523 memcpy(skb_put(skb
, fifo_size
), bcs
->hw
.hscx
.rcvbuf
, fifo_size
);
524 skb_queue_tail(&bcs
->rqueue
, skb
);
526 bcs
->hw
.hscx
.rcvidx
= 0;
527 hscx_sched_event(bcs
, B_RCVBUFREADY
);
530 if (val
& 0x10) { /* XPR */
532 if (bcs
->tx_skb
->len
) {
533 Memhscx_fill_fifo(bcs
);
536 if (bcs
->st
->lli
.l1writewakeup
&&
537 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
))
538 bcs
->st
->lli
.l1writewakeup(bcs
->st
, bcs
->hw
.hscx
.count
);
539 dev_kfree_skb_irq(bcs
->tx_skb
);
540 bcs
->hw
.hscx
.count
= 0;
544 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
545 bcs
->hw
.hscx
.count
= 0;
546 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
547 Memhscx_fill_fifo(bcs
);
549 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
550 hscx_sched_event(bcs
, B_XMTBUFREADY
);
556 Memhscx_int_main(struct IsdnCardState
*cs
, u_char val
)
564 exval
= MemReadHSCX(cs
, 1, HSCX_EXIR
);
567 Memhscx_fill_fifo(bcs
);
569 /* Here we lost an TX interrupt, so
570 * restart transmitting the whole frame.
573 skb_push(bcs
->tx_skb
, bcs
->hw
.hscx
.count
);
574 bcs
->tx_cnt
+= bcs
->hw
.hscx
.count
;
575 bcs
->hw
.hscx
.count
= 0;
577 MemWriteHSCXCMDR(cs
, bcs
->hw
.hscx
.hscx
, 0x01);
578 if (cs
->debug
& L1_DEB_WARN
)
579 debugl1(cs
, "HSCX B EXIR %x Lost TX", exval
);
581 } else if (cs
->debug
& L1_DEB_HSCX
)
582 debugl1(cs
, "HSCX B EXIR %x", exval
);
585 if (cs
->debug
& L1_DEB_HSCX
)
586 debugl1(cs
, "HSCX B interrupt %x", val
);
587 Memhscx_interrupt(cs
, val
, 1);
591 exval
= MemReadHSCX(cs
, 0, HSCX_EXIR
);
593 if (bcs
->mode
== L1_MODE_TRANS
)
594 Memhscx_fill_fifo(bcs
);
596 /* Here we lost an TX interrupt, so
597 * restart transmitting the whole frame.
600 skb_push(bcs
->tx_skb
, bcs
->hw
.hscx
.count
);
601 bcs
->tx_cnt
+= bcs
->hw
.hscx
.count
;
602 bcs
->hw
.hscx
.count
= 0;
604 MemWriteHSCXCMDR(cs
, bcs
->hw
.hscx
.hscx
, 0x01);
605 if (cs
->debug
& L1_DEB_WARN
)
606 debugl1(cs
, "HSCX A EXIR %x Lost TX", exval
);
608 } else if (cs
->debug
& L1_DEB_HSCX
)
609 debugl1(cs
, "HSCX A EXIR %x", exval
);
612 exval
= MemReadHSCX(cs
, 0, HSCX_ISTA
);
613 if (cs
->debug
& L1_DEB_HSCX
)
614 debugl1(cs
, "HSCX A interrupt %x", exval
);
615 Memhscx_interrupt(cs
, exval
, 0);
620 diva_irq_ipac_pci(int intno
, void *dev_id
, struct pt_regs
*regs
)
622 struct IsdnCardState
*cs
= dev_id
;
628 printk(KERN_WARNING
"Diva: Spurious interrupt!\n");
631 cfg
= (u_char
*) cs
->hw
.diva
.pci_cfg
;
633 if (!(val
& PITA_INT0_STATUS
))
634 return; /* other shared IRQ */
635 *cfg
= PITA_INT0_STATUS
; /* Reset pending INT0 */
636 ista
= memreadreg(cs
->hw
.diva
.cfg_reg
, IPAC_ISTA
);
638 if (cs
->debug
& L1_DEB_IPAC
)
639 debugl1(cs
, "IPAC ISTA %02X", ista
);
641 val
= memreadreg(cs
->hw
.diva
.cfg_reg
, HSCX_ISTA
+ 0x40);
649 Memhscx_int_main(cs
, val
);
652 val
= 0xfe & memreadreg(cs
->hw
.diva
.cfg_reg
, ISAC_ISTA
+ 0x80);
654 isac_interrupt(cs
, val
);
659 isac_interrupt(cs
, val
);
661 ista
= memreadreg(cs
->hw
.diva
.cfg_reg
, IPAC_ISTA
);
662 if ((ista
& 0x3f) && icnt
) {
667 printk(KERN_WARNING
"DIVA IPAC PCI IRQ LOOP\n");
668 memwritereg(cs
->hw
.diva
.cfg_reg
, IPAC_MASK
, 0xFF);
669 memwritereg(cs
->hw
.diva
.cfg_reg
, IPAC_MASK
, 0xC0);
673 release_io_diva(struct IsdnCardState
*cs
)
677 if (cs
->subtyp
== DIVA_IPAC_PCI
) {
678 u_int
*cfg
= (unsigned int *)cs
->hw
.diva
.pci_cfg
;
680 *cfg
= 0; /* disable INT0/1 */
681 *cfg
= 2; /* reset pending INT0 */
682 iounmap((void *)cs
->hw
.diva
.cfg_reg
);
683 iounmap((void *)cs
->hw
.diva
.pci_cfg
);
685 } else if (cs
->subtyp
!= DIVA_IPAC_ISA
) {
686 del_timer(&cs
->hw
.diva
.tl
);
687 if (cs
->hw
.diva
.cfg_reg
)
688 byteout(cs
->hw
.diva
.ctrl
, 0); /* LED off, Reset */
690 if ((cs
->subtyp
== DIVA_ISA
) || (cs
->subtyp
== DIVA_IPAC_ISA
))
694 if (cs
->hw
.diva
.cfg_reg
) {
695 release_region(cs
->hw
.diva
.cfg_reg
, bytecnt
);
700 reset_diva(struct IsdnCardState
*cs
)
706 if (cs
->subtyp
== DIVA_IPAC_ISA
) {
707 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_POTA2
, 0x20);
708 set_current_state(TASK_UNINTERRUPTIBLE
);
709 schedule_timeout((10*HZ
)/1000);
710 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_POTA2
, 0x00);
711 set_current_state(TASK_UNINTERRUPTIBLE
);
712 schedule_timeout((10*HZ
)/1000);
713 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_MASK
, 0xc0);
714 } else if (cs
->subtyp
== DIVA_IPAC_PCI
) {
715 unsigned int *ireg
= (unsigned int *)(cs
->hw
.diva
.pci_cfg
+
717 *ireg
= PITA_PARA_SOFTRESET
| PITA_PARA_MPX_MODE
;
718 set_current_state(TASK_UNINTERRUPTIBLE
);
719 schedule_timeout((10*HZ
)/1000);
720 *ireg
= PITA_PARA_MPX_MODE
;
721 set_current_state(TASK_UNINTERRUPTIBLE
);
722 schedule_timeout((10*HZ
)/1000);
723 memwritereg(cs
->hw
.diva
.cfg_reg
, IPAC_MASK
, 0xc0);
724 } else { /* DIVA 2.0 */
725 cs
->hw
.diva
.ctrl_reg
= 0; /* Reset On */
726 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
727 set_current_state(TASK_UNINTERRUPTIBLE
);
728 schedule_timeout((10*HZ
)/1000);
729 cs
->hw
.diva
.ctrl_reg
|= DIVA_RESET
; /* Reset Off */
730 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
731 set_current_state(TASK_UNINTERRUPTIBLE
);
732 schedule_timeout((10*HZ
)/1000);
733 if (cs
->subtyp
== DIVA_ISA
)
734 cs
->hw
.diva
.ctrl_reg
|= DIVA_ISA_LED_A
;
736 /* Workaround PCI9060 */
737 byteout(cs
->hw
.diva
.pci_cfg
+ 0x69, 9);
738 cs
->hw
.diva
.ctrl_reg
|= DIVA_PCI_LED_A
;
740 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
742 restore_flags(flags
);
745 #define DIVA_ASSIGN 1
748 diva_led_handler(struct IsdnCardState
*cs
)
752 if ((cs
->subtyp
== DIVA_IPAC_ISA
) || (cs
->subtyp
== DIVA_IPAC_PCI
))
754 del_timer(&cs
->hw
.diva
.tl
);
755 if (cs
->hw
.diva
.status
& DIVA_ASSIGN
)
756 cs
->hw
.diva
.ctrl_reg
|= (DIVA_ISA
== cs
->subtyp
) ?
757 DIVA_ISA_LED_A
: DIVA_PCI_LED_A
;
759 cs
->hw
.diva
.ctrl_reg
^= (DIVA_ISA
== cs
->subtyp
) ?
760 DIVA_ISA_LED_A
: DIVA_PCI_LED_A
;
763 if (cs
->hw
.diva
.status
& 0xf000)
764 cs
->hw
.diva
.ctrl_reg
|= (DIVA_ISA
== cs
->subtyp
) ?
765 DIVA_ISA_LED_B
: DIVA_PCI_LED_B
;
766 else if (cs
->hw
.diva
.status
& 0x0f00) {
767 cs
->hw
.diva
.ctrl_reg
^= (DIVA_ISA
== cs
->subtyp
) ?
768 DIVA_ISA_LED_B
: DIVA_PCI_LED_B
;
771 cs
->hw
.diva
.ctrl_reg
&= ~((DIVA_ISA
== cs
->subtyp
) ?
772 DIVA_ISA_LED_B
: DIVA_PCI_LED_B
);
774 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
776 init_timer(&cs
->hw
.diva
.tl
);
777 cs
->hw
.diva
.tl
.expires
= jiffies
+ ((blink
* HZ
) / 1000);
778 add_timer(&cs
->hw
.diva
.tl
);
783 Diva_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
795 if (cs
->subtyp
== DIVA_IPAC_PCI
) {
796 ireg
= (unsigned int *)cs
->hw
.diva
.pci_cfg
;
797 *ireg
= PITA_INT0_ENABLE
;
803 case (MDL_REMOVE
| REQUEST
):
804 cs
->hw
.diva
.status
= 0;
806 case (MDL_ASSIGN
| REQUEST
):
807 cs
->hw
.diva
.status
|= DIVA_ASSIGN
;
811 cs
->hw
.diva
.status
|= 0x0200;
813 cs
->hw
.diva
.status
|= 0x0100;
817 cs
->hw
.diva
.status
|= 0x2000;
819 cs
->hw
.diva
.status
|= 0x1000;
823 cs
->hw
.diva
.status
&= ~0x2000;
824 cs
->hw
.diva
.status
&= ~0x0200;
826 cs
->hw
.diva
.status
&= ~0x1000;
827 cs
->hw
.diva
.status
&= ~0x0100;
831 if ((cs
->subtyp
!= DIVA_IPAC_ISA
) && (cs
->subtyp
!= DIVA_IPAC_PCI
))
832 diva_led_handler(cs
);
836 static struct pci_dev
*dev_diva __initdata
= NULL
;
837 static struct pci_dev
*dev_diva_u __initdata
= NULL
;
838 static struct pci_dev
*dev_diva201 __initdata
= NULL
;
841 setup_diva(struct IsdnCard
*card
))
845 struct IsdnCardState
*cs
= card
->cs
;
848 strcpy(tmp
, Diva_revision
);
849 printk(KERN_INFO
"HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp
));
850 if (cs
->typ
!= ISDN_CTYPE_DIEHLDIVA
)
852 cs
->hw
.diva
.status
= 0;
854 cs
->hw
.diva
.ctrl_reg
= 0;
855 cs
->hw
.diva
.cfg_reg
= card
->para
[1];
856 val
= readreg(cs
->hw
.diva
.cfg_reg
+ DIVA_IPAC_ADR
,
857 cs
->hw
.diva
.cfg_reg
+ DIVA_IPAC_DATA
, IPAC_ID
);
858 printk(KERN_INFO
"Diva: IPAC version %x\n", val
);
859 if ((val
== 1) || (val
==2)) {
860 cs
->subtyp
= DIVA_IPAC_ISA
;
861 cs
->hw
.diva
.ctrl
= 0;
862 cs
->hw
.diva
.isac
= card
->para
[1] + DIVA_IPAC_DATA
;
863 cs
->hw
.diva
.hscx
= card
->para
[1] + DIVA_IPAC_DATA
;
864 cs
->hw
.diva
.isac_adr
= card
->para
[1] + DIVA_IPAC_ADR
;
865 cs
->hw
.diva
.hscx_adr
= card
->para
[1] + DIVA_IPAC_ADR
;
866 test_and_set_bit(HW_IPAC
, &cs
->HW_Flags
);
868 cs
->subtyp
= DIVA_ISA
;
869 cs
->hw
.diva
.ctrl
= card
->para
[1] + DIVA_ISA_CTRL
;
870 cs
->hw
.diva
.isac
= card
->para
[1] + DIVA_ISA_ISAC_DATA
;
871 cs
->hw
.diva
.hscx
= card
->para
[1] + DIVA_HSCX_DATA
;
872 cs
->hw
.diva
.isac_adr
= card
->para
[1] + DIVA_ISA_ISAC_ADR
;
873 cs
->hw
.diva
.hscx_adr
= card
->para
[1] + DIVA_HSCX_ADR
;
875 cs
->irq
= card
->para
[0];
879 if (!pci_present()) {
880 printk(KERN_ERR
"Diva: no PCI bus present\n");
885 if ((dev_diva
= pci_find_device(PCI_VENDOR_ID_EICON
,
886 PCI_DEVICE_ID_EICON_DIVA20
, dev_diva
))) {
887 if (pci_enable_device(dev_diva
))
889 cs
->subtyp
= DIVA_PCI
;
890 cs
->irq
= dev_diva
->irq
;
891 cs
->hw
.diva
.cfg_reg
= pci_resource_start(dev_diva
, 2);
892 } else if ((dev_diva_u
= pci_find_device(PCI_VENDOR_ID_EICON
,
893 PCI_DEVICE_ID_EICON_DIVA20_U
, dev_diva_u
))) {
894 if (pci_enable_device(dev_diva_u
))
896 cs
->subtyp
= DIVA_PCI
;
897 cs
->irq
= dev_diva_u
->irq
;
898 cs
->hw
.diva
.cfg_reg
= pci_resource_start(dev_diva_u
, 2);
899 } else if ((dev_diva201
= pci_find_device(PCI_VENDOR_ID_EICON
,
900 PCI_DEVICE_ID_EICON_DIVA201
, dev_diva201
))) {
901 if (pci_enable_device(dev_diva201
))
903 cs
->subtyp
= DIVA_IPAC_PCI
;
904 cs
->irq
= dev_diva201
->irq
;
905 cs
->hw
.diva
.pci_cfg
=
906 (ulong
) ioremap(pci_resource_start(dev_diva201
, 0), 4096);
907 cs
->hw
.diva
.cfg_reg
=
908 (ulong
) ioremap(pci_resource_start(dev_diva201
, 1), 4096);
910 printk(KERN_WARNING
"Diva: No PCI card found\n");
915 printk(KERN_WARNING
"Diva: No IRQ for PCI card found\n");
919 if (!cs
->hw
.diva
.cfg_reg
) {
920 printk(KERN_WARNING
"Diva: No IO-Adr for PCI card found\n");
923 cs
->irq_flags
|= SA_SHIRQ
;
925 printk(KERN_WARNING
"Diva: cfgreg 0 and NO_PCI_BIOS\n");
926 printk(KERN_WARNING
"Diva: unable to config DIVA PCI\n");
928 #endif /* CONFIG_PCI */
929 if (cs
->subtyp
== DIVA_IPAC_PCI
) {
930 cs
->hw
.diva
.ctrl
= 0;
931 cs
->hw
.diva
.isac
= 0;
932 cs
->hw
.diva
.hscx
= 0;
933 cs
->hw
.diva
.isac_adr
= 0;
934 cs
->hw
.diva
.hscx_adr
= 0;
935 test_and_set_bit(HW_IPAC
, &cs
->HW_Flags
);
938 cs
->hw
.diva
.ctrl
= cs
->hw
.diva
.cfg_reg
+ DIVA_PCI_CTRL
;
939 cs
->hw
.diva
.isac
= cs
->hw
.diva
.cfg_reg
+ DIVA_PCI_ISAC_DATA
;
940 cs
->hw
.diva
.hscx
= cs
->hw
.diva
.cfg_reg
+ DIVA_HSCX_DATA
;
941 cs
->hw
.diva
.isac_adr
= cs
->hw
.diva
.cfg_reg
+ DIVA_PCI_ISAC_ADR
;
942 cs
->hw
.diva
.hscx_adr
= cs
->hw
.diva
.cfg_reg
+ DIVA_HSCX_ADR
;
948 "Diva: %s card configured at %#lx IRQ %d\n",
949 (cs
->subtyp
== DIVA_PCI
) ? "PCI" :
950 (cs
->subtyp
== DIVA_ISA
) ? "ISA" :
951 (cs
->subtyp
== DIVA_IPAC_ISA
) ? "IPAC ISA" : "IPAC PCI",
952 cs
->hw
.diva
.cfg_reg
, cs
->irq
);
953 if ((cs
->subtyp
== DIVA_IPAC_PCI
) || (cs
->subtyp
== DIVA_PCI
))
954 printk(KERN_INFO
"Diva: %s PCI space at %#lx\n",
955 (cs
->subtyp
== DIVA_PCI
) ? "PCI" : "IPAC PCI",
956 cs
->hw
.diva
.pci_cfg
);
957 if (cs
->subtyp
!= DIVA_IPAC_PCI
) {
958 if (check_region(cs
->hw
.diva
.cfg_reg
, bytecnt
)) {
960 "HiSax: %s config port %lx-%lx already in use\n",
963 cs
->hw
.diva
.cfg_reg
+ bytecnt
);
966 request_region(cs
->hw
.diva
.cfg_reg
, bytecnt
, "diva isdn");
970 cs
->BC_Read_Reg
= &ReadHSCX
;
971 cs
->BC_Write_Reg
= &WriteHSCX
;
972 cs
->BC_Send_Data
= &hscx_fill_fifo
;
973 cs
->cardmsg
= &Diva_card_msg
;
974 if (cs
->subtyp
== DIVA_IPAC_ISA
) {
975 cs
->readisac
= &ReadISAC_IPAC
;
976 cs
->writeisac
= &WriteISAC_IPAC
;
977 cs
->readisacfifo
= &ReadISACfifo_IPAC
;
978 cs
->writeisacfifo
= &WriteISACfifo_IPAC
;
979 cs
->irq_func
= &diva_irq_ipac_isa
;
980 val
= readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_ID
);
981 printk(KERN_INFO
"Diva: IPAC version %x\n", val
);
982 } else if (cs
->subtyp
== DIVA_IPAC_PCI
) {
983 cs
->readisac
= &MemReadISAC_IPAC
;
984 cs
->writeisac
= &MemWriteISAC_IPAC
;
985 cs
->readisacfifo
= &MemReadISACfifo_IPAC
;
986 cs
->writeisacfifo
= &MemWriteISACfifo_IPAC
;
987 cs
->BC_Read_Reg
= &MemReadHSCX
;
988 cs
->BC_Write_Reg
= &MemWriteHSCX
;
989 cs
->BC_Send_Data
= &Memhscx_fill_fifo
;
990 cs
->irq_func
= &diva_irq_ipac_pci
;
991 val
= memreadreg(cs
->hw
.diva
.cfg_reg
, IPAC_ID
);
992 printk(KERN_INFO
"Diva: IPAC version %x\n", val
);
993 } else { /* DIVA 2.0 */
994 cs
->hw
.diva
.tl
.function
= (void *) diva_led_handler
;
995 cs
->hw
.diva
.tl
.data
= (long) cs
;
996 init_timer(&cs
->hw
.diva
.tl
);
997 cs
->readisac
= &ReadISAC
;
998 cs
->writeisac
= &WriteISAC
;
999 cs
->readisacfifo
= &ReadISACfifo
;
1000 cs
->writeisacfifo
= &WriteISACfifo
;
1001 cs
->irq_func
= &diva_interrupt
;
1002 ISACVersion(cs
, "Diva:");
1003 if (HscxVersion(cs
, "Diva:")) {
1005 "Diva: wrong HSCX versions check IO address\n");
1006 release_io_diva(cs
);