1 /* $Id: diva.c,v 1.25.6.5 2001/09/23 22:24:47 kai Exp $
3 * low level stuff for Eicon.Diehl Diva Family 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.
11 * For changes and modifications please read
12 * ../../../Documentation/isdn/HiSax.cert
14 * Thanks to Eicon Technology for documents and information
18 #include <linux/init.h>
19 #include <linux/config.h>
26 #include <linux/pci.h>
27 #include <linux/isapnp.h>
29 extern const char *CardType
[];
31 const char *Diva_revision
= "$Revision: 1.25.6.5 $";
32 static spinlock_t diva_lock
= SPIN_LOCK_UNLOCKED
;
34 #define byteout(addr,val) outb(val,addr)
35 #define bytein(addr) inb(addr)
37 #define DIVA_HSCX_DATA 0
38 #define DIVA_HSCX_ADR 4
39 #define DIVA_ISA_ISAC_DATA 2
40 #define DIVA_ISA_ISAC_ADR 6
41 #define DIVA_ISA_CTRL 7
42 #define DIVA_IPAC_ADR 0
43 #define DIVA_IPAC_DATA 1
45 #define DIVA_PCI_ISAC_DATA 8
46 #define DIVA_PCI_ISAC_ADR 0xc
47 #define DIVA_PCI_CTRL 0x10
52 #define DIVA_IPAC_ISA 3
53 #define DIVA_IPAC_PCI 4
54 #define DIVA_IPACX_PCI 5
57 #define DIVA_IRQ_STAT 0x01
58 #define DIVA_EEPROM_SDA 0x02
61 #define DIVA_IRQ_REQ 0x01
62 #define DIVA_RESET 0x08
63 #define DIVA_EEPROM_CLK 0x40
64 #define DIVA_PCI_LED_A 0x10
65 #define DIVA_PCI_LED_B 0x20
66 #define DIVA_ISA_LED_A 0x20
67 #define DIVA_ISA_LED_B 0x40
68 #define DIVA_IRQ_CLR 0x80
71 #define PITA_MISC_REG 0x1c
73 #define PITA_PARA_SOFTRESET 0x00000001
74 #define PITA_SER_SOFTRESET 0x00000002
75 #define PITA_PARA_MPX_MODE 0x00000004
76 #define PITA_INT0_ENABLE 0x00000200
78 #define PITA_PARA_SOFTRESET 0x01000000
79 #define PITA_SER_SOFTRESET 0x02000000
80 #define PITA_PARA_MPX_MODE 0x04000000
81 #define PITA_INT0_ENABLE 0x00020000
83 #define PITA_INT0_STATUS 0x02
86 readreg(unsigned int ale
, unsigned int adr
, u8 off
)
91 spin_lock_irqsave(&diva_lock
, flags
);
94 spin_unlock_irqrestore(&diva_lock
, flags
);
99 writereg(unsigned int ale
, unsigned int adr
, u8 off
, u8 data
)
103 spin_lock_irqsave(&diva_lock
, flags
);
106 spin_unlock_irqrestore(&diva_lock
, flags
);
110 readfifo(unsigned int ale
, unsigned int adr
, u8 off
, u8
* data
, int size
)
113 insb(adr
, data
, size
);
117 writefifo(unsigned int ale
, unsigned int adr
, u8 off
, u8
*data
, int size
)
120 outsb(adr
, data
, size
);
124 memreadreg(unsigned long adr
, u8 off
)
126 return readb(((unsigned int *)adr
) + off
);
130 memwritereg(unsigned long adr
, u8 off
, u8 data
)
132 writeb(data
, ((unsigned int *)adr
) + off
);
136 isac_read(struct IsdnCardState
*cs
, u8 offset
)
138 return readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
);
142 isac_write(struct IsdnCardState
*cs
, u8 offset
, u8 value
)
144 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
, value
);
148 isac_read_fifo(struct IsdnCardState
*cs
, u8
*data
, int size
)
150 readfifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, 0, data
, size
);
154 isac_write_fifo(struct IsdnCardState
*cs
, u8
*data
, int size
)
156 writefifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, 0, data
, size
);
159 static struct dc_hw_ops isac_ops
= {
160 .read_reg
= isac_read
,
161 .write_reg
= isac_write
,
162 .read_fifo
= isac_read_fifo
,
163 .write_fifo
= isac_write_fifo
,
167 hscx_read(struct IsdnCardState
*cs
, int hscx
, u8 offset
)
169 return readreg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
,
170 offset
+ (hscx
? 0x40 : 0));
174 hscx_write(struct IsdnCardState
*cs
, int hscx
, u8 offset
, u8 value
)
176 writereg(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
,
177 offset
+ (hscx
? 0x40 : 0), value
);
181 hscx_read_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int size
)
183 readfifo(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, hscx
? 0x40 : 0, data
, size
);
187 hscx_write_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int size
)
189 writefifo(cs
->hw
.diva
.hscx_adr
, cs
->hw
.diva
.hscx
, hscx
? 0x40 : 0, data
, size
);
192 static struct bc_hw_ops hscx_ops
= {
193 .read_reg
= hscx_read
,
194 .write_reg
= hscx_write
,
195 .read_fifo
= hscx_read_fifo
,
196 .write_fifo
= hscx_write_fifo
,
200 ipac_read(struct IsdnCardState
*cs
, u8 offset
)
202 return readreg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
);
206 ipac_write(struct IsdnCardState
*cs
, u8 offset
, u8 value
)
208 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
, value
);
212 ipac_readfifo(struct IsdnCardState
*cs
, u8 offset
, u8
*data
, int size
)
214 readfifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
, data
, size
);
218 ipac_writefifo(struct IsdnCardState
*cs
, u8 offset
, u8
*data
, int size
)
220 writefifo(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, offset
, data
, size
);
223 /* This will generate ipac_dc_ops and ipac_bc_ops using the functions
226 BUILD_IPAC_OPS(ipac
);
229 mem_ipac_read(struct IsdnCardState
*cs
, u8 offset
)
231 return memreadreg(cs
->hw
.diva
.cfg_reg
, offset
);
235 mem_ipac_write(struct IsdnCardState
*cs
, u8 offset
, u8 value
)
237 memwritereg(cs
->hw
.diva
.cfg_reg
, offset
, value
);
241 mem_ipac_readfifo(struct IsdnCardState
*cs
, u8 offset
, u8
*data
, int size
)
244 *data
++ = memreadreg(cs
->hw
.diva
.cfg_reg
, offset
);
248 mem_ipac_writefifo(struct IsdnCardState
*cs
, u8 offset
, u8
*data
, int size
)
251 memwritereg(cs
->hw
.diva
.cfg_reg
, offset
, *data
++);
254 /* This will generate mem_ipac_dc_ops and mem_ipac_bc_ops using the functions
257 BUILD_IPAC_OPS(mem_ipac
);
259 /* IO-Functions for IPACX type cards */
261 ipacx_dc_read(struct IsdnCardState
*cs
, u8 offset
)
263 return memreadreg(cs
->hw
.diva
.cfg_reg
, offset
);
267 ipacx_dc_write(struct IsdnCardState
*cs
, u8 offset
, u8 value
)
269 memwritereg(cs
->hw
.diva
.cfg_reg
, offset
, value
);
273 ipacx_dc_read_fifo(struct IsdnCardState
*cs
, u8
*data
, int size
)
276 *data
++ = memreadreg(cs
->hw
.diva
.cfg_reg
, 0);
280 ipacx_dc_write_fifo(struct IsdnCardState
*cs
, u8
*data
, int size
)
283 memwritereg(cs
->hw
.diva
.cfg_reg
, 0, *data
++);
286 static struct dc_hw_ops ipacx_dc_ops
= {
287 .read_reg
= ipacx_dc_read
,
288 .write_reg
= ipacx_dc_write
,
289 .read_fifo
= ipacx_dc_read_fifo
,
290 .write_fifo
= ipacx_dc_write_fifo
,
294 ipacx_bc_read(struct IsdnCardState
*cs
, int hscx
, u8 offset
)
296 return memreadreg(cs
->hw
.diva
.cfg_reg
, offset
+
297 (hscx
? IPACX_OFF_B2
: IPACX_OFF_B1
));
301 ipacx_bc_write(struct IsdnCardState
*cs
, int hscx
, u8 offset
, u8 value
)
303 memwritereg(cs
->hw
.diva
.cfg_reg
, offset
+
304 (hscx
? IPACX_OFF_B2
: IPACX_OFF_B1
), value
);
308 ipacx_bc_read_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int len
)
312 for (i
= 0; i
< len
; i
++)
313 *data
++ = ipacx_bc_read(cs
, hscx
, IPACX_RFIFOB
);
316 static struct bc_hw_ops ipacx_bc_ops
= {
317 .read_reg
= ipacx_bc_read
,
318 .write_reg
= ipacx_bc_write
,
319 .read_fifo
= ipacx_bc_read_fifo
,
323 diva_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
325 struct IsdnCardState
*cs
= dev_id
;
329 while (((sval
= bytein(cs
->hw
.diva
.ctrl
)) & DIVA_IRQ_REQ
) && cnt
) {
330 hscxisac_irq(intno
, dev_id
, regs
);
333 printk(KERN_WARNING
"Diva: IRQ LOOP\n");
338 diva_ipac_pci_irq(int intno
, void *dev_id
, struct pt_regs
*regs
)
340 struct IsdnCardState
*cs
= dev_id
;
343 val
= readb(cs
->hw
.diva
.pci_cfg
);
344 if (!(val
& PITA_INT0_STATUS
))
345 return IRQ_NONE
; /* other shared IRQ */
346 writeb(PITA_INT0_STATUS
, cs
->hw
.diva
.pci_cfg
); /* Reset pending INT0 */
348 return ipac_irq(intno
, dev_id
, regs
);
352 diva_ipacx_pci_irq(int intno
, void *dev_id
, struct pt_regs
*regs
)
354 struct IsdnCardState
*cs
= dev_id
;
357 val
= readb(cs
->hw
.diva
.pci_cfg
);
358 if (!(val
&PITA_INT0_STATUS
))
359 return IRQ_NONE
; // other shared IRQ
360 interrupt_ipacx(cs
); // handler for chip
361 writeb(PITA_INT0_STATUS
, cs
->hw
.diva
.pci_cfg
); // Reset PLX interrupt
366 diva_release(struct IsdnCardState
*cs
)
368 del_timer_sync(&cs
->hw
.diva
.tl
);
369 if (cs
->hw
.diva
.cfg_reg
)
370 byteout(cs
->hw
.diva
.ctrl
, 0); /* LED off, Reset */
372 hisax_release_resources(cs
);
376 diva_ipac_pci_release(struct IsdnCardState
*cs
)
378 writel(0, cs
->hw
.diva
.pci_cfg
); /* disable INT0/1 */
379 writel(2, cs
->hw
.diva
.pci_cfg
); /* reset pending INT0 */
380 hisax_release_resources(cs
);
384 diva_ipac_isa_reset(struct IsdnCardState
*cs
)
386 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_POTA2
, 0x20);
387 set_current_state(TASK_UNINTERRUPTIBLE
);
388 schedule_timeout((10*HZ
)/1000);
389 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_POTA2
, 0x00);
390 set_current_state(TASK_UNINTERRUPTIBLE
);
391 schedule_timeout((10*HZ
)/1000);
392 writereg(cs
->hw
.diva
.isac_adr
, cs
->hw
.diva
.isac
, IPAC_MASK
, 0xc0);
397 diva_ipac_pci_reset(struct IsdnCardState
*cs
)
399 unsigned long misc_reg
= cs
->hw
.diva
.pci_cfg
+ PITA_MISC_REG
;
401 writel(PITA_PARA_SOFTRESET
| PITA_PARA_MPX_MODE
, misc_reg
);
402 set_current_state(TASK_UNINTERRUPTIBLE
);
403 schedule_timeout((10*HZ
)/1000);
404 writel(PITA_PARA_MPX_MODE
, misc_reg
);
405 set_current_state(TASK_UNINTERRUPTIBLE
);
406 schedule_timeout((10*HZ
)/1000);
407 memwritereg(cs
->hw
.diva
.cfg_reg
, IPAC_MASK
, 0xc0);
412 diva_ipacx_pci_reset(struct IsdnCardState
*cs
)
414 unsigned long misc_reg
= cs
->hw
.diva
.pci_cfg
+ PITA_MISC_REG
;
416 writel(PITA_PARA_SOFTRESET
| PITA_PARA_MPX_MODE
, misc_reg
);
417 set_current_state(TASK_UNINTERRUPTIBLE
);
418 schedule_timeout((10*HZ
)/1000);
419 writel(PITA_PARA_MPX_MODE
| PITA_SER_SOFTRESET
, misc_reg
);
420 set_current_state(TASK_UNINTERRUPTIBLE
);
421 schedule_timeout((10*HZ
)/1000);
422 ipacx_dc_write(cs
, IPACX_MASK
, 0xff); // Interrupts off
427 diva_reset(struct IsdnCardState
*cs
)
430 cs
->hw
.diva
.ctrl_reg
= 0; /* Reset On */
431 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
432 set_current_state(TASK_UNINTERRUPTIBLE
);
433 schedule_timeout((10*HZ
)/1000);
434 cs
->hw
.diva
.ctrl_reg
|= DIVA_RESET
; /* Reset Off */
435 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
436 set_current_state(TASK_UNINTERRUPTIBLE
);
437 schedule_timeout((10*HZ
)/1000);
438 if (cs
->subtyp
== DIVA_ISA
) {
439 cs
->hw
.diva
.ctrl_reg
|= DIVA_ISA_LED_A
;
441 /* Workaround PCI9060 */
442 byteout(cs
->hw
.diva
.pci_cfg
+ 0x69, 9);
443 cs
->hw
.diva
.ctrl_reg
|= DIVA_PCI_LED_A
;
445 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
450 diva_led_handler(struct IsdnCardState
*cs
)
454 if (cs
->status
& 0x0001)
455 cs
->hw
.diva
.ctrl_reg
|= (DIVA_ISA
== cs
->subtyp
) ?
456 DIVA_ISA_LED_A
: DIVA_PCI_LED_A
;
458 cs
->hw
.diva
.ctrl_reg
^= (DIVA_ISA
== cs
->subtyp
) ?
459 DIVA_ISA_LED_A
: DIVA_PCI_LED_A
;
462 if (cs
->status
& 0xf000)
463 cs
->hw
.diva
.ctrl_reg
|= (DIVA_ISA
== cs
->subtyp
) ?
464 DIVA_ISA_LED_B
: DIVA_PCI_LED_B
;
465 else if (cs
->status
& 0x0f00) {
466 cs
->hw
.diva
.ctrl_reg
^= (DIVA_ISA
== cs
->subtyp
) ?
467 DIVA_ISA_LED_B
: DIVA_PCI_LED_B
;
470 cs
->hw
.diva
.ctrl_reg
&= ~((DIVA_ISA
== cs
->subtyp
) ?
471 DIVA_ISA_LED_B
: DIVA_PCI_LED_B
);
473 byteout(cs
->hw
.diva
.ctrl
, cs
->hw
.diva
.ctrl_reg
);
475 mod_timer(&cs
->hw
.diva
.tl
, jiffies
+ (blink
* HZ
) / 1000);
479 diva_ipacx_pci_init(struct IsdnCardState
*cs
)
481 writel(PITA_INT0_ENABLE
, cs
->hw
.diva
.pci_cfg
);
482 init_ipacx(cs
, 3); // init chip and enable interrupts
486 diva_ipac_pci_init(struct IsdnCardState
*cs
)
488 writel(PITA_INT0_ENABLE
, cs
->hw
.diva
.pci_cfg
);
492 static struct card_ops diva_ops
= {
493 .init
= inithscxisac
,
495 .release
= diva_release
,
496 .led_handler
= diva_led_handler
,
497 .irq_func
= diva_interrupt
,
500 static struct card_ops diva_ipac_isa_ops
= {
502 .reset
= diva_ipac_isa_reset
,
503 .release
= hisax_release_resources
,
504 .irq_func
= ipac_irq
,
507 static struct card_ops diva_ipac_pci_ops
= {
508 .init
= diva_ipac_pci_init
,
509 .reset
= diva_ipac_pci_reset
,
510 .release
= diva_ipac_pci_release
,
511 .irq_func
= diva_ipac_pci_irq
,
514 static struct card_ops diva_ipacx_pci_ops
= {
515 .init
= diva_ipacx_pci_init
,
516 .reset
= diva_ipacx_pci_reset
,
517 .release
= diva_ipac_pci_release
,
518 .irq_func
= diva_ipacx_pci_irq
,
522 diva_ipac_probe(struct IsdnCardState
*cs
)
527 val
= readreg(cs
->hw
.diva
.cfg_reg
+ DIVA_IPAC_ADR
,
528 cs
->hw
.diva
.cfg_reg
+ DIVA_IPAC_DATA
, IPAC_ID
);
529 printk(KERN_INFO
"Diva: IPAC version %x\n", val
);
530 return (val
== 1 || val
== 2);
534 diva_ipac_isa_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
536 cs
->subtyp
= DIVA_IPAC_ISA
;
537 cs
->irq
= card
->para
[0];
538 cs
->hw
.diva
.cfg_reg
= card
->para
[1];
539 cs
->hw
.diva
.isac
= card
->para
[1] + DIVA_IPAC_DATA
;
540 cs
->hw
.diva
.isac_adr
= card
->para
[1] + DIVA_IPAC_ADR
;
541 printk(KERN_INFO
"Diva: %s card configured at %#lx IRQ %d\n",
542 "IPAC ISA", cs
->hw
.diva
.cfg_reg
, cs
->irq
);
543 if (!request_io(&cs
->rs
, cs
->hw
.diva
.cfg_reg
, 8, "diva isdn"))
545 diva_ipac_isa_reset(cs
);
546 cs
->card_ops
= &diva_ipac_isa_ops
;
547 if (ipac_setup(cs
, &ipac_dc_ops
, &ipac_bc_ops
))
551 hisax_release_resources(cs
);
556 diva_isac_isa_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
558 cs
->subtyp
= DIVA_ISA
;
559 cs
->irq
= card
->para
[0];
560 cs
->hw
.diva
.cfg_reg
= card
->para
[1];
561 cs
->hw
.diva
.ctrl
= card
->para
[1] + DIVA_ISA_CTRL
;
562 cs
->hw
.diva
.isac
= card
->para
[1] + DIVA_ISA_ISAC_DATA
;
563 cs
->hw
.diva
.hscx
= card
->para
[1] + DIVA_HSCX_DATA
;
564 cs
->hw
.diva
.isac_adr
= card
->para
[1] + DIVA_ISA_ISAC_ADR
;
565 cs
->hw
.diva
.hscx_adr
= card
->para
[1] + DIVA_HSCX_ADR
;
566 printk(KERN_INFO
"Diva: %s card configured at %#lx IRQ %d\n",
567 "ISA", cs
->hw
.diva
.cfg_reg
, cs
->irq
);
568 if (!request_io(&cs
->rs
, cs
->hw
.diva
.cfg_reg
, 8, "diva isdn"))
571 init_timer(&cs
->hw
.diva
.tl
);
572 cs
->hw
.diva
.tl
.function
= (void *) diva_led_handler
;
573 cs
->hw
.diva
.tl
.data
= (long) cs
;
574 cs
->card_ops
= &diva_ops
;
575 if (hscxisac_setup(cs
, &isac_ops
, &hscx_ops
))
579 hisax_release_resources(cs
);
584 diva_isa_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
587 cs
->hw
.diva
.cfg_reg
= card
->para
[1];
588 if (!request_io(&cs
->rs
, cs
->hw
.diva
.cfg_reg
, 8, "diva isdn"))
591 is_ipac
= diva_ipac_probe(cs
);
592 hisax_release_resources(cs
);
595 return diva_ipac_isa_probe(cs
, card
);
597 return diva_isac_isa_probe(cs
, card
);
601 diva_pci_probe(struct IsdnCardState
*cs
, struct pci_dev
*pdev
)
603 if (pci_enable_device(pdev
))
606 cs
->subtyp
= DIVA_PCI
;
608 cs
->irq_flags
|= SA_SHIRQ
;
609 cs
->hw
.diva
.cfg_reg
= pci_resource_start(pdev
, 2);
610 cs
->hw
.diva
.ctrl
= cs
->hw
.diva
.cfg_reg
+ DIVA_PCI_CTRL
;
611 cs
->hw
.diva
.isac
= cs
->hw
.diva
.cfg_reg
+ DIVA_PCI_ISAC_DATA
;
612 cs
->hw
.diva
.hscx
= cs
->hw
.diva
.cfg_reg
+ DIVA_HSCX_DATA
;
613 cs
->hw
.diva
.isac_adr
= cs
->hw
.diva
.cfg_reg
+ DIVA_PCI_ISAC_ADR
;
614 cs
->hw
.diva
.hscx_adr
= cs
->hw
.diva
.cfg_reg
+ DIVA_HSCX_ADR
;
615 printk(KERN_INFO
"Diva: %s card configured at %#lx IRQ %d\n",
616 "PCI", cs
->hw
.diva
.cfg_reg
, cs
->irq
);
617 printk(KERN_INFO
"Diva: %s space at %#lx\n",
618 "PCI", cs
->hw
.diva
.pci_cfg
);
619 if (!request_io(&cs
->rs
, cs
->hw
.diva
.cfg_reg
, 32, "diva isdn"))
623 hisax_release_resources(cs
);
628 diva_ipac_pci_probe(struct IsdnCardState
*cs
, struct pci_dev
*pdev
)
630 if (pci_enable_device(pdev
))
633 cs
->subtyp
= DIVA_IPAC_PCI
;
635 cs
->irq_flags
|= SA_SHIRQ
;
636 cs
->hw
.diva
.pci_cfg
= (unsigned long)request_mmio(
637 &cs
->rs
, pci_resource_start(pdev
, 0), 4096, "diva");
638 cs
->hw
.diva
.cfg_reg
= (unsigned long)request_mmio(
639 &cs
->rs
, pci_resource_start(pdev
, 1), 4096, "diva");
640 printk(KERN_INFO
"Diva: %s card configured at %#lx IRQ %d\n",
641 "IPAC PCI", cs
->hw
.diva
.cfg_reg
, cs
->irq
);
642 printk(KERN_INFO
"Diva: %s space at %#lx\n",
643 "IPAC PCI", cs
->hw
.diva
.pci_cfg
);
644 diva_ipac_pci_reset(cs
);
645 cs
->card_ops
= &diva_ipac_pci_ops
;
646 if (ipac_setup(cs
, &mem_ipac_dc_ops
, &mem_ipac_bc_ops
))
650 hisax_release_resources(cs
);
655 diva_ipacx_pci_probe(struct IsdnCardState
*cs
, struct pci_dev
*pdev
)
657 if (pci_enable_device(pdev
))
660 cs
->subtyp
= DIVA_IPACX_PCI
;
662 cs
->irq_flags
|= SA_SHIRQ
;
663 printk(KERN_INFO
"Diva: %s card configured at %#lx IRQ %d\n",
664 "IPACX PCI", cs
->hw
.diva
.cfg_reg
, cs
->irq
);
665 printk(KERN_INFO
"Diva: %s space at %#lx\n",
666 "IPACX PCI", cs
->hw
.diva
.pci_cfg
);
667 diva_ipacx_pci_reset(cs
);
668 cs
->card_ops
= &diva_ipacx_pci_ops
;
669 if (ipacx_setup(cs
, &ipacx_dc_ops
, &ipacx_bc_ops
))
673 hisax_release_resources(cs
);
677 static struct pci_dev
*dev_diva __initdata
= NULL
;
678 static struct pci_dev
*dev_diva_u __initdata
= NULL
;
679 static struct pci_dev
*dev_diva201 __initdata
= NULL
;
681 static struct isapnp_device_id diva_ids
[] __initdata
= {
682 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
683 ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
684 (unsigned long) "Diva picola" },
685 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
686 ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51),
687 (unsigned long) "Diva picola" },
688 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
689 ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
690 (unsigned long) "Diva 2.0" },
691 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
692 ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71),
693 (unsigned long) "Diva 2.0" },
694 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
695 ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
696 (unsigned long) "Diva 2.01" },
697 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
698 ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1),
699 (unsigned long) "Diva 2.01" },
703 static struct isapnp_device_id
*pdev
= &diva_ids
[0];
704 static struct pnp_card
*pnp_c __devinitdata
= NULL
;
708 setup_diva(struct IsdnCard
*card
)
712 strcpy(tmp
, Diva_revision
);
713 printk(KERN_INFO
"HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp
));
715 if (diva_isa_probe(card
->cs
, card
) < 0)
721 if (isapnp_present()) {
725 while(pdev
->card_vendor
) {
726 if ((pb
= pnp_find_card(pdev
->card_vendor
,
727 pdev
->card_device
, pnp_c
))) {
730 if ((pd
= pnp_find_dev(pnp_c
,
734 printk(KERN_INFO
"HiSax: %s detected\n",
735 (char *)pdev
->driver_data
);
736 if (pnp_device_attach(pd
) < 0) {
737 printk(KERN_ERR
"Diva PnP: attach failed\n");
740 if (pnp_activate_dev(pd
) < 0) {
741 printk(KERN_ERR
"Diva PnP: activate failed\n");
742 pnp_device_detach(pd
);
745 if (!pnp_irq_valid(pd
, 0) || !pnp_port_valid(pd
, 0)) {
746 printk(KERN_ERR
"Diva PnP:some resources are missing %ld/%lx\n",
747 pnp_irq(pd
, 0), pnp_port_start(pd
, 0));
748 pnp_device_detach(pd
);
751 card
->para
[1] = pnp_port_start(pd
, 0);
752 card
->para
[0] = pnp_irq(pd
, 0);
753 if (pdev
->function
== ISAPNP_FUNCTION(0xA1)) {
754 if (diva_ipac_isa_probe(cs
->card
, cs
))
758 if (diva_isac_isa_probe(cs
->card
, cs
))
762 printk(KERN_ERR
"Diva PnP: PnP error card found, no device\n");
769 if (!pdev
->card_vendor
) {
770 printk(KERN_INFO
"Diva PnP: no ISAPnP card found\n");
776 if ((dev_diva
= pci_find_device(PCI_VENDOR_ID_EICON
,
777 PCI_DEVICE_ID_EICON_DIVA20
,
779 if (diva_pci_probe(card
->cs
, dev_diva
))
782 } else if ((dev_diva_u
= pci_find_device(PCI_VENDOR_ID_EICON
,
783 PCI_DEVICE_ID_EICON_DIVA20_U
,
785 if (diva_pci_probe(card
->cs
, dev_diva_u
))
788 } else if ((dev_diva201
= pci_find_device(PCI_VENDOR_ID_EICON
,
789 PCI_DEVICE_ID_EICON_DIVA201
,
791 if (diva_ipac_pci_probe(card
->cs
, dev_diva201
))
795 printk(KERN_WARNING
"Diva: No PCI card found\n");
796 #endif /* CONFIG_PCI */