Hopefully get the Kconfig PCI stuff right, finally.
[linux-2.6/linux-mips.git] / drivers / isdn / hisax / diva.c
blobb9996317376bca0a974449a013b9e173b4fc71b3
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
5 * Author Karsten Keil
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
7 *
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>
20 #include "hisax.h"
21 #include "isac.h"
22 #include "hscx.h"
23 #include "ipac.h"
24 #include "ipacx.h"
25 #include "isdnl1.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
49 /* SUB Types */
50 #define DIVA_ISA 1
51 #define DIVA_PCI 2
52 #define DIVA_IPAC_ISA 3
53 #define DIVA_IPAC_PCI 4
54 #define DIVA_IPACX_PCI 5
56 /* CTRL (Read) */
57 #define DIVA_IRQ_STAT 0x01
58 #define DIVA_EEPROM_SDA 0x02
60 /* CTRL (Write) */
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
70 /* Siemens PITA */
71 #define PITA_MISC_REG 0x1c
72 #ifdef __BIG_ENDIAN
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
77 #else
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
82 #endif
83 #define PITA_INT0_STATUS 0x02
85 static inline u8
86 readreg(unsigned int ale, unsigned int adr, u8 off)
88 u8 ret;
89 unsigned long flags;
91 spin_lock_irqsave(&diva_lock, flags);
92 byteout(ale, off);
93 ret = bytein(adr);
94 spin_unlock_irqrestore(&diva_lock, flags);
95 return ret;
98 static inline void
99 writereg(unsigned int ale, unsigned int adr, u8 off, u8 data)
101 unsigned long flags;
103 spin_lock_irqsave(&diva_lock, flags);
104 byteout(ale, off);
105 byteout(adr, data);
106 spin_unlock_irqrestore(&diva_lock, flags);
109 static inline void
110 readfifo(unsigned int ale, unsigned int adr, u8 off, u8 * data, int size)
112 byteout(ale, off);
113 insb(adr, data, size);
116 static inline void
117 writefifo(unsigned int ale, unsigned int adr, u8 off, u8 *data, int size)
119 byteout(ale, off);
120 outsb(adr, data, size);
123 static inline u8
124 memreadreg(unsigned long adr, u8 off)
126 return readb(((unsigned int *)adr) + off);
129 static inline void
130 memwritereg(unsigned long adr, u8 off, u8 data)
132 writeb(data, ((unsigned int *)adr) + off);
135 static u8
136 isac_read(struct IsdnCardState *cs, u8 offset)
138 return readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset);
141 static void
142 isac_write(struct IsdnCardState *cs, u8 offset, u8 value)
144 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, value);
147 static void
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);
153 static void
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,
166 static u8
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));
173 static void
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);
180 static void
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);
186 static void
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,
199 static inline u8
200 ipac_read(struct IsdnCardState *cs, u8 offset)
202 return readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset);
205 static inline void
206 ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
208 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, value);
211 static inline void
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);
217 static inline void
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
224 * above */
226 BUILD_IPAC_OPS(ipac);
228 static inline u8
229 mem_ipac_read(struct IsdnCardState *cs, u8 offset)
231 return memreadreg(cs->hw.diva.cfg_reg, offset);
234 static inline void
235 mem_ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
237 memwritereg(cs->hw.diva.cfg_reg, offset, value);
240 static inline void
241 mem_ipac_readfifo(struct IsdnCardState *cs, u8 offset, u8 *data, int size)
243 while(size--)
244 *data++ = memreadreg(cs->hw.diva.cfg_reg, offset);
247 static inline void
248 mem_ipac_writefifo(struct IsdnCardState *cs, u8 offset, u8 *data, int size)
250 while(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
255 * above */
257 BUILD_IPAC_OPS(mem_ipac);
259 /* IO-Functions for IPACX type cards */
260 static u8
261 ipacx_dc_read(struct IsdnCardState *cs, u8 offset)
263 return memreadreg(cs->hw.diva.cfg_reg, offset);
266 static void
267 ipacx_dc_write(struct IsdnCardState *cs, u8 offset, u8 value)
269 memwritereg(cs->hw.diva.cfg_reg, offset, value);
272 static void
273 ipacx_dc_read_fifo(struct IsdnCardState *cs, u8 *data, int size)
275 while(size--)
276 *data++ = memreadreg(cs->hw.diva.cfg_reg, 0);
279 static void
280 ipacx_dc_write_fifo(struct IsdnCardState *cs, u8 *data, int size)
282 while(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,
293 static u8
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));
300 static void
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);
307 static void
308 ipacx_bc_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int len)
310 int i;
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,
322 static irqreturn_t
323 diva_interrupt(int intno, void *dev_id, struct pt_regs *regs)
325 struct IsdnCardState *cs = dev_id;
326 u8 sval;
327 int cnt=5;
329 while (((sval = bytein(cs->hw.diva.ctrl)) & DIVA_IRQ_REQ) && cnt) {
330 hscxisac_irq(intno, dev_id, regs);
332 if (!cnt)
333 printk(KERN_WARNING "Diva: IRQ LOOP\n");
334 return IRQ_HANDLED;
337 static irqreturn_t
338 diva_ipac_pci_irq(int intno, void *dev_id, struct pt_regs *regs)
340 struct IsdnCardState *cs = dev_id;
341 u8 val;
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);
351 static irqreturn_t
352 diva_ipacx_pci_irq(int intno, void *dev_id, struct pt_regs *regs)
354 struct IsdnCardState *cs = dev_id;
355 u8 val;
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
362 return IRQ_HANDLED;
365 static void
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);
375 static void
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);
383 static int
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);
393 return 0;
396 static int
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);
408 return 0;
411 static int
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
423 return 0;
426 static int
427 diva_reset(struct IsdnCardState *cs)
429 /* DIVA 2.0 */
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;
440 } else {
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);
446 return 0;
449 static void
450 diva_led_handler(struct IsdnCardState *cs)
452 int blink = 0;
454 if (cs->status & 0x0001)
455 cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ?
456 DIVA_ISA_LED_A : DIVA_PCI_LED_A;
457 else {
458 cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ?
459 DIVA_ISA_LED_A : DIVA_PCI_LED_A;
460 blink = 250;
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;
468 blink = 500;
469 } else
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);
474 if (blink)
475 mod_timer(&cs->hw.diva.tl, jiffies + (blink * HZ) / 1000);
478 static void
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
485 static void
486 diva_ipac_pci_init(struct IsdnCardState *cs)
488 writel(PITA_INT0_ENABLE, cs->hw.diva.pci_cfg);
489 ipac_init(cs);
492 static struct card_ops diva_ops = {
493 .init = inithscxisac,
494 .reset = diva_reset,
495 .release = diva_release,
496 .led_handler = diva_led_handler,
497 .irq_func = diva_interrupt,
500 static struct card_ops diva_ipac_isa_ops = {
501 .init = ipac_init,
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,
521 static int __init
522 diva_ipac_probe(struct IsdnCardState *cs)
524 u8 val;
526 // request_io
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);
533 static int __init
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"))
544 goto err;
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))
548 goto err;
549 return 0;
550 err:
551 hisax_release_resources(cs);
552 return -EBUSY;
555 static int __init
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"))
569 goto err;
570 diva_reset(cs);
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))
576 goto err;
577 return 0;
578 err:
579 hisax_release_resources(cs);
580 return -EBUSY;
583 static int __init
584 diva_isa_probe(struct IsdnCardState *cs, struct IsdnCard *card)
586 int is_ipac;
587 cs->hw.diva.cfg_reg = card->para[1];
588 if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 8, "diva isdn"))
589 return -EBUSY;
591 is_ipac = diva_ipac_probe(cs);
592 hisax_release_resources(cs);
594 if (is_ipac)
595 return diva_ipac_isa_probe(cs, card);
596 else
597 return diva_isac_isa_probe(cs, card);
600 static int __init
601 diva_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
603 if (pci_enable_device(pdev))
604 goto err;
606 cs->subtyp = DIVA_PCI;
607 cs->irq = pdev->irq;
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"))
620 goto err;
621 return 0;
622 err:
623 hisax_release_resources(cs);
624 return -EBUSY;
627 static int __init
628 diva_ipac_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
630 if (pci_enable_device(pdev))
631 goto err;
633 cs->subtyp = DIVA_IPAC_PCI;
634 cs->irq = pdev->irq;
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))
647 goto err;
648 return 0;
649 err:
650 hisax_release_resources(cs);
651 return -EBUSY;
654 static int __init
655 diva_ipacx_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
657 if (pci_enable_device(pdev))
658 goto err;
660 cs->subtyp = DIVA_IPACX_PCI;
661 cs->irq = pdev->irq;
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))
670 goto err;
671 return 0;
672 err:
673 hisax_release_resources(cs);
674 return -EBUSY;
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;
680 #ifdef __ISAPNP__
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" },
700 { 0, }
703 static struct isapnp_device_id *pdev = &diva_ids[0];
704 static struct pnp_card *pnp_c __devinitdata = NULL;
705 #endif
707 int __init
708 setup_diva(struct IsdnCard *card)
710 char tmp[64];
712 strcpy(tmp, Diva_revision);
713 printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp));
714 if (card->para[1]) {
715 if (diva_isa_probe(card->cs, card) < 0)
716 return 0;
717 return 1;
720 #ifdef __ISAPNP__
721 if (isapnp_present()) {
722 struct pnp_card *pb;
723 struct pnp_dev *pd;
725 while(pdev->card_vendor) {
726 if ((pb = pnp_find_card(pdev->card_vendor,
727 pdev->card_device, pnp_c))) {
728 pnp_c = pb;
729 pd = NULL;
730 if ((pd = pnp_find_dev(pnp_c,
731 pdev->vendor,
732 pdev->function,
733 pd))) {
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");
738 return 0;
740 if (pnp_activate_dev(pd) < 0) {
741 printk(KERN_ERR "Diva PnP: activate failed\n");
742 pnp_device_detach(pd);
743 return 0;
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);
749 return(0);
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))
755 return 0;
756 return 1;
757 } else {
758 if (diva_isac_isa_probe(cs->card, cs))
759 return 0;
760 return 1;
761 } else {
762 printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
763 return(0);
766 pdev++;
767 pnp_c=NULL;
769 if (!pdev->card_vendor) {
770 printk(KERN_INFO "Diva PnP: no ISAPnP card found\n");
774 #endif
775 #ifdef CONFIG_PCI
776 if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON,
777 PCI_DEVICE_ID_EICON_DIVA20,
778 dev_diva))) {
779 if (diva_pci_probe(card->cs, dev_diva))
780 return 0;
781 return 1;
782 } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON,
783 PCI_DEVICE_ID_EICON_DIVA20_U,
784 dev_diva_u))) {
785 if (diva_pci_probe(card->cs, dev_diva_u))
786 return 0;
787 return 1;
788 } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON,
789 PCI_DEVICE_ID_EICON_DIVA201,
790 dev_diva201))) {
791 if (diva_ipac_pci_probe(card->cs, dev_diva201))
792 return 0;
793 return 1;
795 printk(KERN_WARNING "Diva: No PCI card found\n");
796 #endif /* CONFIG_PCI */
797 return 0;