1 // SPDX-License-Identifier: GPL-2.0-only
4 * Support for cards based on following Infineon ISDN chipsets
11 * - Dialogic Diva 2.0U
12 * - Dialogic Diva 2.01
13 * - Dialogic Diva 2.02
14 * - Sedlbauer Speedwin
16 * - Develo (former ELSA) Microlink PCI (Quickstep 1000)
17 * - Develo (former ELSA) Quickstep 3000
18 * - Berkom Scitel BRIX Quadro
19 * - Dr.Neuhaus (Sagem) Niccy
21 * Author Karsten Keil <keil@isdn4linux.de>
23 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
26 #include <linux/interrupt.h>
27 #include <linux/module.h>
28 #include <linux/pci.h>
29 #include <linux/delay.h>
30 #include <linux/mISDNhw.h>
31 #include <linux/slab.h>
34 #define INFINEON_REV "1.0"
38 static u32 irqloops = 4;
70 enum addr_mode cfg_mode;
71 enum addr_mode addr_mode;
88 resource_size_t start;
93 struct list_head list;
95 const struct inf_cinfo *ci;
96 char name[MISDN_MAX_IDLEN];
100 struct _iohandle addr;
103 spinlock_t lock; /* HW access lock */
105 struct inf_hw *sc[3]; /* slave cards */
109 #define PCI_SUBVENDOR_HST_SAPHIR3 0x52
110 #define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
111 #define PCI_SUB_ID_SEDLBAUER 0x01
113 static struct pci_device_id infineon_ids[] = {
114 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), INF_DIVA20 },
115 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), INF_DIVA20U },
116 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), INF_DIVA201 },
117 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), INF_DIVA202 },
118 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
119 PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
121 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
122 PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3 },
123 { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK), INF_QS1000 },
124 { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000), INF_QS3000 },
125 { PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY), INF_NICCY },
126 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
127 PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
129 { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685), INF_GAZEL_R685 },
130 { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753), INF_GAZEL_R753 },
131 { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO), INF_GAZEL_R753 },
132 { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC), INF_GAZEL_R753 },
135 MODULE_DEVICE_TABLE(pci, infineon_ids);
137 /* PCI interface specific defines */
139 #define DIVA_HSCX_PORT 0x00
140 #define DIVA_HSCX_ALE 0x04
141 #define DIVA_ISAC_PORT 0x08
142 #define DIVA_ISAC_ALE 0x0C
143 #define DIVA_PCI_CTRL 0x10
145 /* DIVA_PCI_CTRL bits */
146 #define DIVA_IRQ_BIT 0x01
147 #define DIVA_RESET_BIT 0x08
148 #define DIVA_EEPROM_CLK 0x40
149 #define DIVA_LED_A 0x10
150 #define DIVA_LED_B 0x20
151 #define DIVA_IRQ_CLR 0x80
155 #define PITA_ICR_REG 0x00
156 #define PITA_INT0_STATUS 0x02
158 #define PITA_MISC_REG 0x1c
159 #define PITA_PARA_SOFTRESET 0x01000000
160 #define PITA_SER_SOFTRESET 0x02000000
161 #define PITA_PARA_MPX_MODE 0x04000000
162 #define PITA_INT0_ENABLE 0x00020000
164 /* TIGER 100 Registers */
165 #define TIGER_RESET_ADDR 0x00
166 #define TIGER_EXTERN_RESET 0x01
167 #define TIGER_AUX_CTRL 0x02
168 #define TIGER_AUX_DATA 0x03
169 #define TIGER_AUX_IRQMASK 0x05
170 #define TIGER_AUX_STATUS 0x07
173 #define TIGER_IOMASK 0xdd /* 1 and 5 are inputs */
174 #define TIGER_IRQ_BIT 0x02
176 #define TIGER_IPAC_ALE 0xC0
177 #define TIGER_IPAC_PORT 0xC8
179 /* ELSA (now Develo) PCI cards */
180 #define ELSA_IRQ_ADDR 0x4c
181 #define ELSA_IRQ_MASK 0x04
182 #define QS1000_IRQ_OFF 0x01
183 #define QS3000_IRQ_OFF 0x03
184 #define QS1000_IRQ_ON 0x41
185 #define QS3000_IRQ_ON 0x43
187 /* Dr Neuhaus/Sagem Niccy */
188 #define NICCY_ISAC_PORT 0x00
189 #define NICCY_HSCX_PORT 0x01
190 #define NICCY_ISAC_ALE 0x02
191 #define NICCY_HSCX_ALE 0x03
193 #define NICCY_IRQ_CTRL_REG 0x38
194 #define NICCY_IRQ_ENABLE 0x001f00
195 #define NICCY_IRQ_DISABLE 0xff0000
196 #define NICCY_IRQ_BIT 0x800000
200 #define SCT_PLX_IRQ_ADDR 0x4c
201 #define SCT_PLX_RESET_ADDR 0x50
202 #define SCT_PLX_IRQ_ENABLE 0x41
203 #define SCT_PLX_RESET_BIT 0x04
206 #define GAZEL_IPAC_DATA_PORT 0x04
208 #define GAZEL_CNTRL 0x50
209 #define GAZEL_RESET 0x04
210 #define GAZEL_RESET_9050 0x40000000
211 #define GAZEL_INCSR 0x4C
212 #define GAZEL_ISAC_EN 0x08
213 #define GAZEL_INT_ISAC 0x20
214 #define GAZEL_HSCX_EN 0x01
215 #define GAZEL_INT_HSCX 0x04
216 #define GAZEL_PCI_EN 0x40
217 #define GAZEL_IPAC_EN 0x03
220 static LIST_HEAD(Cards);
221 static DEFINE_RWLOCK(card_lock); /* protect Cards */
224 _set_debug(struct inf_hw *card)
226 card->ipac.isac.dch.debug = debug;
227 card->ipac.hscx[0].bch.debug = debug;
228 card->ipac.hscx[1].bch.debug = debug;
232 set_debug(const char *val, const struct kernel_param *kp)
237 ret = param_set_uint(val, kp);
239 read_lock(&card_lock);
240 list_for_each_entry(card, &Cards, list)
242 read_unlock(&card_lock);
247 MODULE_AUTHOR("Karsten Keil");
248 MODULE_LICENSE("GPL v2");
249 MODULE_VERSION(INFINEON_REV);
250 module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
251 MODULE_PARM_DESC(debug, "infineon debug mask");
252 module_param(irqloops, uint, S_IRUGO | S_IWUSR);
253 MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)");
255 /* Interface functions */
257 IOFUNC_IO(ISAC, inf_hw, isac.a.io)
258 IOFUNC_IO(IPAC, inf_hw, hscx.a.io)
259 IOFUNC_IND(ISAC, inf_hw, isac.a.io)
260 IOFUNC_IND(IPAC, inf_hw, hscx.a.io)
261 IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p)
262 IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p)
265 diva_irq(int intno, void *dev_id)
267 struct inf_hw *hw = dev_id;
270 spin_lock(&hw->lock);
271 val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL);
272 if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */
273 spin_unlock(&hw->lock);
274 return IRQ_NONE; /* shared */
277 mISDNipac_irq(&hw->ipac, irqloops);
278 spin_unlock(&hw->lock);
283 diva20x_irq(int intno, void *dev_id)
285 struct inf_hw *hw = dev_id;
288 spin_lock(&hw->lock);
289 val = readb(hw->cfg.p);
290 if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */
291 spin_unlock(&hw->lock);
292 return IRQ_NONE; /* shared */
295 mISDNipac_irq(&hw->ipac, irqloops);
296 writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */
297 spin_unlock(&hw->lock);
302 tiger_irq(int intno, void *dev_id)
304 struct inf_hw *hw = dev_id;
307 spin_lock(&hw->lock);
308 val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS);
309 if (val & TIGER_IRQ_BIT) { /* for us or shared ? */
310 spin_unlock(&hw->lock);
311 return IRQ_NONE; /* shared */
314 mISDNipac_irq(&hw->ipac, irqloops);
315 spin_unlock(&hw->lock);
320 elsa_irq(int intno, void *dev_id)
322 struct inf_hw *hw = dev_id;
325 spin_lock(&hw->lock);
326 val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR);
327 if (!(val & ELSA_IRQ_MASK)) {
328 spin_unlock(&hw->lock);
329 return IRQ_NONE; /* shared */
332 mISDNipac_irq(&hw->ipac, irqloops);
333 spin_unlock(&hw->lock);
338 niccy_irq(int intno, void *dev_id)
340 struct inf_hw *hw = dev_id;
343 spin_lock(&hw->lock);
344 val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
345 if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */
346 spin_unlock(&hw->lock);
347 return IRQ_NONE; /* shared */
349 outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
351 mISDNipac_irq(&hw->ipac, irqloops);
352 spin_unlock(&hw->lock);
357 gazel_irq(int intno, void *dev_id)
359 struct inf_hw *hw = dev_id;
362 spin_lock(&hw->lock);
363 ret = mISDNipac_irq(&hw->ipac, irqloops);
364 spin_unlock(&hw->lock);
369 ipac_irq(int intno, void *dev_id)
371 struct inf_hw *hw = dev_id;
374 spin_lock(&hw->lock);
375 val = hw->ipac.read_reg(hw, IPAC_ISTA);
377 spin_unlock(&hw->lock);
378 return IRQ_NONE; /* shared */
381 mISDNipac_irq(&hw->ipac, irqloops);
382 spin_unlock(&hw->lock);
387 enable_hwirq(struct inf_hw *hw)
392 switch (hw->ci->typ) {
395 writel(PITA_INT0_ENABLE, hw->cfg.p);
399 outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
402 outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
405 outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
408 val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
409 val |= NICCY_IRQ_ENABLE;
410 outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
413 w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
414 w |= SCT_PLX_IRQ_ENABLE;
415 outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
418 outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
419 (u32)hw->cfg.start + GAZEL_INCSR);
422 outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
423 (u32)hw->cfg.start + GAZEL_INCSR);
431 disable_hwirq(struct inf_hw *hw)
436 switch (hw->ci->typ) {
439 writel(0, hw->cfg.p);
443 outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
446 outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
449 outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
452 val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
453 val &= NICCY_IRQ_DISABLE;
454 outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
457 w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
458 w &= (~SCT_PLX_IRQ_ENABLE);
459 outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
463 outb(0, (u32)hw->cfg.start + GAZEL_INCSR);
471 ipac_chip_reset(struct inf_hw *hw)
473 hw->ipac.write_reg(hw, IPAC_POTA2, 0x20);
475 hw->ipac.write_reg(hw, IPAC_POTA2, 0x00);
477 hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf);
478 hw->ipac.write_reg(hw, IPAC_MASK, 0xc0);
482 reset_inf(struct inf_hw *hw)
487 if (debug & DEBUG_HW)
488 pr_notice("%s: resetting card\n", hw->name);
489 switch (hw->ci->typ) {
492 outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL);
494 outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL);
496 /* Workaround PCI9060 */
497 outb(9, (u32)hw->cfg.start + 0x69);
498 outb(DIVA_RESET_BIT | DIVA_LED_A,
499 (u32)hw->cfg.start + DIVA_PCI_CTRL);
502 writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
503 hw->cfg.p + PITA_MISC_REG);
505 writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
509 writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
510 hw->cfg.p + PITA_MISC_REG);
512 writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
513 hw->cfg.p + PITA_MISC_REG);
519 hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
520 hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
521 hw->ipac.write_reg(hw, IPAC_PCFG, 0x12);
526 hw->ipac.write_reg(hw, IPAC_ACFG, 0x00);
527 hw->ipac.write_reg(hw, IPAC_AOE, 0x3c);
528 hw->ipac.write_reg(hw, IPAC_ATX, 0xff);
533 w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
534 w &= (~SCT_PLX_RESET_BIT);
535 outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
537 w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
538 w |= SCT_PLX_RESET_BIT;
539 outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
543 val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
544 val |= (GAZEL_RESET_9050 + GAZEL_RESET);
545 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
546 val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
548 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
550 hw->ipac.isac.adf2 = 0x87;
551 hw->ipac.hscx[0].slot = 0x1f;
552 hw->ipac.hscx[1].slot = 0x23;
555 val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
556 val |= (GAZEL_RESET_9050 + GAZEL_RESET);
557 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
558 val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
560 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
563 hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
564 hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
565 hw->ipac.conf = 0x01; /* IOM off */
574 inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
583 pr_info("%s: %s unknown command %x %lx\n",
584 hw->name, __func__, cmd, arg);
592 init_irq(struct inf_hw *hw)
597 if (!hw->ci->irqfunc)
599 ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw);
601 pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq);
605 spin_lock_irqsave(&hw->lock, flags);
607 ret = hw->ipac.init(&hw->ipac);
609 spin_unlock_irqrestore(&hw->lock, flags);
610 pr_info("%s: ISAC init failed with %d\n",
614 spin_unlock_irqrestore(&hw->lock, flags);
615 msleep_interruptible(10);
616 if (debug & DEBUG_HW)
617 pr_notice("%s: IRQ %d count %d\n", hw->name,
618 hw->irq, hw->irqcnt);
620 pr_info("%s: IRQ(%d) got no requests during init %d\n",
621 hw->name, hw->irq, 3 - cnt);
625 free_irq(hw->irq, hw);
630 release_io(struct inf_hw *hw)
633 if (hw->cfg.mode == AM_MEMIO) {
634 release_mem_region(hw->cfg.start, hw->cfg.size);
638 release_region(hw->cfg.start, hw->cfg.size);
639 hw->cfg.mode = AM_NONE;
642 if (hw->addr.mode == AM_MEMIO) {
643 release_mem_region(hw->addr.start, hw->addr.size);
647 release_region(hw->addr.start, hw->addr.size);
648 hw->addr.mode = AM_NONE;
653 setup_io(struct inf_hw *hw)
657 if (hw->ci->cfg_mode) {
658 hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
659 hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
660 if (hw->ci->cfg_mode == AM_MEMIO) {
661 if (!request_mem_region(hw->cfg.start, hw->cfg.size,
665 if (!request_region(hw->cfg.start, hw->cfg.size,
670 pr_info("mISDN: %s config port %lx (%lu bytes)"
671 "already in use\n", hw->name,
672 (ulong)hw->cfg.start, (ulong)hw->cfg.size);
675 hw->cfg.mode = hw->ci->cfg_mode;
676 if (hw->ci->cfg_mode == AM_MEMIO) {
677 hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
681 if (debug & DEBUG_HW)
682 pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
683 hw->name, (ulong)hw->cfg.start,
684 (ulong)hw->cfg.size, hw->ci->cfg_mode);
687 if (hw->ci->addr_mode) {
688 hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
689 hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
690 if (hw->ci->addr_mode == AM_MEMIO) {
691 if (!request_mem_region(hw->addr.start, hw->addr.size,
695 if (!request_region(hw->addr.start, hw->addr.size,
700 pr_info("mISDN: %s address port %lx (%lu bytes)"
701 "already in use\n", hw->name,
702 (ulong)hw->addr.start, (ulong)hw->addr.size);
705 hw->addr.mode = hw->ci->addr_mode;
706 if (hw->ci->addr_mode == AM_MEMIO) {
707 hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
711 if (debug & DEBUG_HW)
712 pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
713 hw->name, (ulong)hw->addr.start,
714 (ulong)hw->addr.size, hw->ci->addr_mode);
718 switch (hw->ci->typ) {
721 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
722 hw->isac.mode = hw->cfg.mode;
723 hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
724 hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
725 hw->hscx.mode = hw->cfg.mode;
726 hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
727 hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
730 hw->ipac.type = IPAC_TYPE_IPAC;
731 hw->ipac.isac.off = 0x80;
732 hw->isac.mode = hw->addr.mode;
733 hw->isac.a.p = hw->addr.p;
734 hw->hscx.mode = hw->addr.mode;
735 hw->hscx.a.p = hw->addr.p;
738 hw->ipac.type = IPAC_TYPE_IPACX;
739 hw->isac.mode = hw->addr.mode;
740 hw->isac.a.p = hw->addr.p;
741 hw->hscx.mode = hw->addr.mode;
742 hw->hscx.a.p = hw->addr.p;
746 hw->ipac.type = IPAC_TYPE_IPAC;
747 hw->ipac.isac.off = 0x80;
748 hw->isac.mode = hw->cfg.mode;
749 hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
750 hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
751 hw->hscx.mode = hw->cfg.mode;
752 hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
753 hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
754 outb(0xff, (ulong)hw->cfg.start);
756 outb(0x00, (ulong)hw->cfg.start);
758 outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
762 hw->ipac.type = IPAC_TYPE_IPAC;
763 hw->ipac.isac.off = 0x80;
764 hw->isac.a.io.ale = (u32)hw->addr.start;
765 hw->isac.a.io.port = (u32)hw->addr.start + 1;
766 hw->isac.mode = hw->addr.mode;
767 hw->hscx.a.io.ale = (u32)hw->addr.start;
768 hw->hscx.a.io.port = (u32)hw->addr.start + 1;
769 hw->hscx.mode = hw->addr.mode;
772 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
773 hw->isac.mode = hw->addr.mode;
774 hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
775 hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
776 hw->hscx.mode = hw->addr.mode;
777 hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
778 hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
781 hw->ipac.type = IPAC_TYPE_IPAC;
782 hw->ipac.isac.off = 0x80;
783 hw->isac.a.io.ale = (u32)hw->addr.start;
784 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
785 hw->isac.mode = hw->addr.mode;
786 hw->hscx.a.io.ale = hw->isac.a.io.ale;
787 hw->hscx.a.io.port = hw->isac.a.io.port;
788 hw->hscx.mode = hw->addr.mode;
791 hw->ipac.type = IPAC_TYPE_IPAC;
792 hw->ipac.isac.off = 0x80;
793 hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
794 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
795 hw->isac.mode = hw->addr.mode;
796 hw->hscx.a.io.ale = hw->isac.a.io.ale;
797 hw->hscx.a.io.port = hw->isac.a.io.port;
798 hw->hscx.mode = hw->addr.mode;
801 hw->ipac.type = IPAC_TYPE_IPAC;
802 hw->ipac.isac.off = 0x80;
803 hw->isac.a.io.ale = (u32)hw->addr.start + 0x10;
804 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
805 hw->isac.mode = hw->addr.mode;
806 hw->hscx.a.io.ale = hw->isac.a.io.ale;
807 hw->hscx.a.io.port = hw->isac.a.io.port;
808 hw->hscx.mode = hw->addr.mode;
811 hw->ipac.type = IPAC_TYPE_IPAC;
812 hw->ipac.isac.off = 0x80;
813 hw->isac.a.io.ale = (u32)hw->addr.start + 0x20;
814 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
815 hw->isac.mode = hw->addr.mode;
816 hw->hscx.a.io.ale = hw->isac.a.io.ale;
817 hw->hscx.a.io.port = hw->isac.a.io.port;
818 hw->hscx.mode = hw->addr.mode;
821 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
822 hw->ipac.isac.off = 0x80;
823 hw->isac.mode = hw->addr.mode;
824 hw->isac.a.io.port = (u32)hw->addr.start;
825 hw->hscx.mode = hw->addr.mode;
826 hw->hscx.a.io.port = hw->isac.a.io.port;
829 hw->ipac.type = IPAC_TYPE_IPAC;
830 hw->ipac.isac.off = 0x80;
831 hw->isac.mode = hw->addr.mode;
832 hw->isac.a.io.ale = (u32)hw->addr.start;
833 hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
834 hw->hscx.mode = hw->addr.mode;
835 hw->hscx.a.io.ale = hw->isac.a.io.ale;
836 hw->hscx.a.io.port = hw->isac.a.io.port;
841 switch (hw->isac.mode) {
843 ASSIGN_FUNC_IPAC(MIO, hw->ipac);
846 ASSIGN_FUNC_IPAC(IND, hw->ipac);
849 ASSIGN_FUNC_IPAC(IO, hw->ipac);
858 release_card(struct inf_hw *card) {
862 spin_lock_irqsave(&card->lock, flags);
864 spin_unlock_irqrestore(&card->lock, flags);
865 card->ipac.isac.release(&card->ipac.isac);
866 free_irq(card->irq, card);
867 mISDN_unregister_device(&card->ipac.isac.dch.dev);
869 write_lock_irqsave(&card_lock, flags);
870 list_del(&card->list);
871 write_unlock_irqrestore(&card_lock, flags);
872 switch (card->ci->typ) {
878 for (i = 0; i < 3; i++) {
880 release_card(card->sc[i]);
885 pci_disable_device(card->pdev);
886 pci_set_drvdata(card->pdev, NULL);
894 setup_instance(struct inf_hw *card)
899 snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
901 write_lock_irqsave(&card_lock, flags);
902 list_add_tail(&card->list, &Cards);
903 write_unlock_irqrestore(&card_lock, flags);
906 card->ipac.isac.name = card->name;
907 card->ipac.name = card->name;
908 card->ipac.owner = THIS_MODULE;
909 spin_lock_init(&card->lock);
910 card->ipac.isac.hwlock = &card->lock;
911 card->ipac.hwlock = &card->lock;
912 card->ipac.ctrl = (void *)&inf_ctrl;
914 err = setup_io(card);
918 card->ipac.isac.dch.dev.Bprotocols =
919 mISDNipac_init(&card->ipac, card);
921 if (card->ipac.isac.dch.dev.Bprotocols == 0)
924 err = mISDN_register_device(&card->ipac.isac.dch.dev,
925 &card->pdev->dev, card->name);
929 err = init_irq(card);
932 pr_notice("Infineon %d cards installed\n", inf_cnt);
935 mISDN_unregister_device(&card->ipac.isac.dch.dev);
937 card->ipac.release(&card->ipac);
940 write_lock_irqsave(&card_lock, flags);
941 list_del(&card->list);
942 write_unlock_irqrestore(&card_lock, flags);
946 static const struct inf_cinfo inf_card_info[] = {
951 AM_IND_IO, AM_NONE, 2, 0,
956 "Dialogic Diva 2.0U",
958 AM_IND_IO, AM_NONE, 2, 0,
963 "Dialogic Diva 2.01",
965 AM_MEMIO, AM_MEMIO, 0, 1,
970 "Dialogic Diva 2.02",
972 AM_MEMIO, AM_MEMIO, 0, 1,
977 "Sedlbauer SpeedWin PCI",
979 AM_IND_IO, AM_NONE, 0, 0,
986 AM_IND_IO, AM_NONE, 0, 0,
991 "Develo Microlink PCI",
993 AM_IO, AM_IND_IO, 1, 3,
998 "Develo QuickStep 3000",
1000 AM_IO, AM_IND_IO, 1, 3,
1007 AM_IO, AM_IND_IO, 0, 1,
1014 AM_IO, AM_IND_IO, 1, 5,
1021 AM_NONE, AM_IND_IO, 0, 4,
1028 AM_NONE, AM_IND_IO, 0, 3,
1035 AM_NONE, AM_IND_IO, 0, 2,
1049 AM_IO, AM_IND_IO, 1, 2,
1057 static const struct inf_cinfo *
1058 get_card_info(enum inf_types typ)
1060 const struct inf_cinfo *ci = inf_card_info;
1062 while (ci->typ != INF_NONE) {
1071 inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1074 struct inf_hw *card;
1076 card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1078 pr_info("No memory for Infineon ISDN card\n");
1082 err = pci_enable_device(pdev);
1087 card->ci = get_card_info(ent->driver_data);
1089 pr_info("mISDN: do not have information about adapter at %s\n",
1092 pci_disable_device(pdev);
1095 pr_notice("mISDN: found adapter %s at %s\n",
1096 card->ci->full, pci_name(pdev));
1098 card->irq = pdev->irq;
1099 pci_set_drvdata(pdev, card);
1100 err = setup_instance(card);
1102 pci_disable_device(pdev);
1104 pci_set_drvdata(pdev, NULL);
1105 } else if (ent->driver_data == INF_SCT_1) {
1109 for (i = 1; i < 4; i++) {
1110 sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1113 pci_disable_device(pdev);
1116 sc->irq = card->irq;
1117 sc->pdev = card->pdev;
1118 sc->ci = card->ci + i;
1119 err = setup_instance(sc);
1121 pci_disable_device(pdev);
1126 card->sc[i - 1] = sc;
1133 inf_remove(struct pci_dev *pdev)
1135 struct inf_hw *card = pci_get_drvdata(pdev);
1140 pr_debug("%s: drvdata already removed\n", __func__);
1143 static struct pci_driver infineon_driver = {
1144 .name = "ISDN Infineon pci",
1146 .remove = inf_remove,
1147 .id_table = infineon_ids,
1155 pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
1156 err = pci_register_driver(&infineon_driver);
1161 infineon_cleanup(void)
1163 pci_unregister_driver(&infineon_driver);
1166 module_init(infineon_init);
1167 module_exit(infineon_cleanup);