3 * Support for cards based on following Infineon ISDN chipsets
10 * - Dialogic Diva 2.0U
11 * - Dialogic Diva 2.01
12 * - Dialogic Diva 2.02
13 * - Sedlbauer Speedwin
15 * - Develo (former ELSA) Microlink PCI (Quickstep 1000)
16 * - Develo (former ELSA) Quickstep 3000
17 * - Berkom Scitel BRIX Quadro
18 * - Dr.Neuhaus (Sagem) Niccy
22 * Author Karsten Keil <keil@isdn4linux.de>
24 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
26 * This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License version 2 as
28 * published by the Free Software Foundation.
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
41 #include <linux/module.h>
42 #include <linux/pci.h>
43 #include <linux/delay.h>
44 #include <linux/mISDNhw.h>
47 #define INFINEON_REV "1.0"
51 static u32 irqloops = 4;
83 enum addr_mode cfg_mode;
84 enum addr_mode addr_mode;
100 resource_size_t size;
101 resource_size_t start;
106 struct list_head list;
107 struct pci_dev *pdev;
108 const struct inf_cinfo *ci;
109 char name[MISDN_MAX_IDLEN];
112 struct _iohandle cfg;
113 struct _iohandle addr;
116 spinlock_t lock; /* HW access lock */
118 struct inf_hw *sc[3]; /* slave cards */
122 #define PCI_SUBVENDOR_HST_SAPHIR3 0x52
123 #define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
124 #define PCI_SUB_ID_SEDLBAUER 0x01
126 static struct pci_device_id infineon_ids[] __devinitdata = {
127 { PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20,
128 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA20},
129 { PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20_U,
130 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA20U},
131 { PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA201,
132 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA201},
133 { PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA202,
134 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA202},
135 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
136 PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
138 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
139 PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3},
140 { PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_MICROLINK,
141 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_QS1000},
142 { PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_QS3000,
143 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_QS3000},
144 { PCI_VENDOR_ID_SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY,
145 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_NICCY},
146 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
147 PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
149 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_R685,
150 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R685},
151 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_R753,
152 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R753},
153 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO,
154 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R753},
155 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_OLITEC,
156 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R753},
159 MODULE_DEVICE_TABLE(pci, infineon_ids);
161 /* PCI interface specific defines */
163 #define DIVA_HSCX_PORT 0x00
164 #define DIVA_HSCX_ALE 0x04
165 #define DIVA_ISAC_PORT 0x08
166 #define DIVA_ISAC_ALE 0x0C
167 #define DIVA_PCI_CTRL 0x10
169 /* DIVA_PCI_CTRL bits */
170 #define DIVA_IRQ_BIT 0x01
171 #define DIVA_RESET_BIT 0x08
172 #define DIVA_EEPROM_CLK 0x40
173 #define DIVA_LED_A 0x10
174 #define DIVA_LED_B 0x20
175 #define DIVA_IRQ_CLR 0x80
179 #define PITA_ICR_REG 0x00
180 #define PITA_INT0_STATUS 0x02
182 #define PITA_MISC_REG 0x1c
183 #define PITA_PARA_SOFTRESET 0x01000000
184 #define PITA_SER_SOFTRESET 0x02000000
185 #define PITA_PARA_MPX_MODE 0x04000000
186 #define PITA_INT0_ENABLE 0x00020000
188 /* TIGER 100 Registers */
189 #define TIGER_RESET_ADDR 0x00
190 #define TIGER_EXTERN_RESET 0x01
191 #define TIGER_AUX_CTRL 0x02
192 #define TIGER_AUX_DATA 0x03
193 #define TIGER_AUX_IRQMASK 0x05
194 #define TIGER_AUX_STATUS 0x07
197 #define TIGER_IOMASK 0xdd /* 1 and 5 are inputs */
198 #define TIGER_IRQ_BIT 0x02
200 #define TIGER_IPAC_ALE 0xC0
201 #define TIGER_IPAC_PORT 0xC8
203 /* ELSA (now Develo) PCI cards */
204 #define ELSA_IRQ_ADDR 0x4c
205 #define ELSA_IRQ_MASK 0x04
206 #define QS1000_IRQ_OFF 0x01
207 #define QS3000_IRQ_OFF 0x03
208 #define QS1000_IRQ_ON 0x41
209 #define QS3000_IRQ_ON 0x43
211 /* Dr Neuhaus/Sagem Niccy */
212 #define NICCY_ISAC_PORT 0x00
213 #define NICCY_HSCX_PORT 0x01
214 #define NICCY_ISAC_ALE 0x02
215 #define NICCY_HSCX_ALE 0x03
217 #define NICCY_IRQ_CTRL_REG 0x38
218 #define NICCY_IRQ_ENABLE 0x001f00
219 #define NICCY_IRQ_DISABLE 0xff0000
220 #define NICCY_IRQ_BIT 0x800000
224 #define SCT_PLX_IRQ_ADDR 0x4c
225 #define SCT_PLX_RESET_ADDR 0x50
226 #define SCT_PLX_IRQ_ENABLE 0x41
227 #define SCT_PLX_RESET_BIT 0x04
230 #define GAZEL_IPAC_DATA_PORT 0x04
232 #define GAZEL_CNTRL 0x50
233 #define GAZEL_RESET 0x04
234 #define GAZEL_RESET_9050 0x40000000
235 #define GAZEL_INCSR 0x4C
236 #define GAZEL_ISAC_EN 0x08
237 #define GAZEL_INT_ISAC 0x20
238 #define GAZEL_HSCX_EN 0x01
239 #define GAZEL_INT_HSCX 0x04
240 #define GAZEL_PCI_EN 0x40
241 #define GAZEL_IPAC_EN 0x03
244 static LIST_HEAD(Cards);
245 static DEFINE_RWLOCK(card_lock); /* protect Cards */
248 _set_debug(struct inf_hw *card)
250 card->ipac.isac.dch.debug = debug;
251 card->ipac.hscx[0].bch.debug = debug;
252 card->ipac.hscx[1].bch.debug = debug;
256 set_debug(const char *val, struct kernel_param *kp)
261 ret = param_set_uint(val, kp);
263 read_lock(&card_lock);
264 list_for_each_entry(card, &Cards, list)
266 read_unlock(&card_lock);
271 MODULE_AUTHOR("Karsten Keil");
272 MODULE_LICENSE("GPL v2");
273 MODULE_VERSION(INFINEON_REV);
274 module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
275 MODULE_PARM_DESC(debug, "infineon debug mask");
276 module_param(irqloops, uint, S_IRUGO | S_IWUSR);
277 MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)");
279 /* Interface functions */
281 IOFUNC_IO(ISAC, inf_hw, isac.a.io)
282 IOFUNC_IO(IPAC, inf_hw, hscx.a.io)
283 IOFUNC_IND(ISAC, inf_hw, isac.a.io)
284 IOFUNC_IND(IPAC, inf_hw, hscx.a.io)
285 IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p)
286 IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p)
289 diva_irq(int intno, void *dev_id)
291 struct inf_hw *hw = dev_id;
294 spin_lock(&hw->lock);
295 val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL);
296 if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */
297 spin_unlock(&hw->lock);
298 return IRQ_NONE; /* shared */
301 mISDNipac_irq(&hw->ipac, irqloops);
302 spin_unlock(&hw->lock);
307 diva20x_irq(int intno, void *dev_id)
309 struct inf_hw *hw = dev_id;
312 spin_lock(&hw->lock);
313 val = readb(hw->cfg.p);
314 if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */
315 spin_unlock(&hw->lock);
316 return IRQ_NONE; /* shared */
319 mISDNipac_irq(&hw->ipac, irqloops);
320 writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */
321 spin_unlock(&hw->lock);
326 tiger_irq(int intno, void *dev_id)
328 struct inf_hw *hw = dev_id;
331 spin_lock(&hw->lock);
332 val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS);
333 if (val & TIGER_IRQ_BIT) { /* for us or shared ? */
334 spin_unlock(&hw->lock);
335 return IRQ_NONE; /* shared */
338 mISDNipac_irq(&hw->ipac, irqloops);
339 spin_unlock(&hw->lock);
344 elsa_irq(int intno, void *dev_id)
346 struct inf_hw *hw = dev_id;
349 spin_lock(&hw->lock);
350 val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR);
351 if (!(val & ELSA_IRQ_MASK)) {
352 spin_unlock(&hw->lock);
353 return IRQ_NONE; /* shared */
356 mISDNipac_irq(&hw->ipac, irqloops);
357 spin_unlock(&hw->lock);
362 niccy_irq(int intno, void *dev_id)
364 struct inf_hw *hw = dev_id;
367 spin_lock(&hw->lock);
368 val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
369 if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */
370 spin_unlock(&hw->lock);
371 return IRQ_NONE; /* shared */
373 outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
375 mISDNipac_irq(&hw->ipac, irqloops);
376 spin_unlock(&hw->lock);
381 gazel_irq(int intno, void *dev_id)
383 struct inf_hw *hw = dev_id;
386 spin_lock(&hw->lock);
387 ret = mISDNipac_irq(&hw->ipac, irqloops);
388 spin_unlock(&hw->lock);
393 ipac_irq(int intno, void *dev_id)
395 struct inf_hw *hw = dev_id;
398 spin_lock(&hw->lock);
399 val = hw->ipac.read_reg(hw, IPAC_ISTA);
401 spin_unlock(&hw->lock);
402 return IRQ_NONE; /* shared */
405 mISDNipac_irq(&hw->ipac, irqloops);
406 spin_unlock(&hw->lock);
411 enable_hwirq(struct inf_hw *hw)
416 switch (hw->ci->typ) {
419 writel(PITA_INT0_ENABLE, hw->cfg.p);
423 outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
426 outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
429 outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
432 val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
433 val |= NICCY_IRQ_ENABLE;;
434 outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
437 w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
438 w |= SCT_PLX_IRQ_ENABLE;
439 outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
442 outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
443 (u32)hw->cfg.start + GAZEL_INCSR);
446 outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
447 (u32)hw->cfg.start + GAZEL_INCSR);
455 disable_hwirq(struct inf_hw *hw)
460 switch (hw->ci->typ) {
463 writel(0, hw->cfg.p);
467 outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
470 outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
473 outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
476 val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
477 val &= NICCY_IRQ_DISABLE;
478 outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
481 w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
482 w &= (~SCT_PLX_IRQ_ENABLE);
483 outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
487 outb(0, (u32)hw->cfg.start + GAZEL_INCSR);
495 ipac_chip_reset(struct inf_hw *hw)
497 hw->ipac.write_reg(hw, IPAC_POTA2, 0x20);
499 hw->ipac.write_reg(hw, IPAC_POTA2, 0x00);
501 hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf);
502 hw->ipac.write_reg(hw, IPAC_MASK, 0xc0);
506 reset_inf(struct inf_hw *hw)
511 if (debug & DEBUG_HW)
512 pr_notice("%s: resetting card\n", hw->name);
513 switch (hw->ci->typ) {
516 outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL);
518 outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL);
520 /* Workaround PCI9060 */
521 outb(9, (u32)hw->cfg.start + 0x69);
522 outb(DIVA_RESET_BIT | DIVA_LED_A,
523 (u32)hw->cfg.start + DIVA_PCI_CTRL);
526 writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
527 hw->cfg.p + PITA_MISC_REG);
529 writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
533 writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
534 hw->cfg.p + PITA_MISC_REG);
536 writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
537 hw->cfg.p + PITA_MISC_REG);
543 hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
544 hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
545 hw->ipac.write_reg(hw, IPAC_PCFG, 0x12);
550 hw->ipac.write_reg(hw, IPAC_ACFG, 0x00);
551 hw->ipac.write_reg(hw, IPAC_AOE, 0x3c);
552 hw->ipac.write_reg(hw, IPAC_ATX, 0xff);
557 w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
558 w &= (~SCT_PLX_RESET_BIT);
559 outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
561 w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
562 w |= SCT_PLX_RESET_BIT;
563 outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
567 val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
568 val |= (GAZEL_RESET_9050 + GAZEL_RESET);
569 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
570 val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
572 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
574 hw->ipac.isac.adf2 = 0x87;
575 hw->ipac.hscx[0].slot = 0x1f;
576 hw->ipac.hscx[0].slot = 0x23;
579 val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
580 val |= (GAZEL_RESET_9050 + GAZEL_RESET);
581 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
582 val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
584 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
587 hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
588 hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
589 hw->ipac.conf = 0x01; /* IOM off */
598 inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
607 pr_info("%s: %s unknown command %x %lx\n",
608 hw->name, __func__, cmd, arg);
616 init_irq(struct inf_hw *hw)
621 if (!hw->ci->irqfunc)
623 ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw);
625 pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq);
629 spin_lock_irqsave(&hw->lock, flags);
631 ret = hw->ipac.init(&hw->ipac);
633 spin_unlock_irqrestore(&hw->lock, flags);
634 pr_info("%s: ISAC init failed with %d\n",
638 spin_unlock_irqrestore(&hw->lock, flags);
639 msleep_interruptible(10);
640 if (debug & DEBUG_HW)
641 pr_notice("%s: IRQ %d count %d\n", hw->name,
642 hw->irq, hw->irqcnt);
644 pr_info("%s: IRQ(%d) got no requests during init %d\n",
645 hw->name, hw->irq, 3 - cnt);
649 free_irq(hw->irq, hw);
654 release_io(struct inf_hw *hw)
658 release_mem_region(hw->cfg.start, hw->cfg.size);
661 release_region(hw->cfg.start, hw->cfg.size);
662 hw->cfg.mode = AM_NONE;
666 release_mem_region(hw->addr.start, hw->addr.size);
669 release_region(hw->addr.start, hw->addr.size);
670 hw->addr.mode = AM_NONE;
675 setup_io(struct inf_hw *hw)
679 if (hw->ci->cfg_mode) {
680 hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
681 hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
682 if (hw->ci->cfg_mode == AM_MEMIO) {
683 if (!request_mem_region(hw->cfg.start, hw->cfg.size,
687 if (!request_region(hw->cfg.start, hw->cfg.size,
692 pr_info("mISDN: %s config port %lx (%lu bytes)"
693 "already in use\n", hw->name,
694 (ulong)hw->cfg.start, (ulong)hw->cfg.size);
697 if (hw->ci->cfg_mode == AM_MEMIO)
698 hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
699 hw->cfg.mode = hw->ci->cfg_mode;
700 if (debug & DEBUG_HW)
701 pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
702 hw->name, (ulong)hw->cfg.start,
703 (ulong)hw->cfg.size, hw->ci->cfg_mode);
706 if (hw->ci->addr_mode) {
707 hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
708 hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
709 if (hw->ci->addr_mode == AM_MEMIO) {
710 if (!request_mem_region(hw->addr.start, hw->addr.size,
714 if (!request_region(hw->addr.start, hw->addr.size,
719 pr_info("mISDN: %s address port %lx (%lu bytes)"
720 "already in use\n", hw->name,
721 (ulong)hw->addr.start, (ulong)hw->addr.size);
724 if (hw->ci->addr_mode == AM_MEMIO)
725 hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
726 hw->addr.mode = hw->ci->addr_mode;
727 if (debug & DEBUG_HW)
728 pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
729 hw->name, (ulong)hw->addr.start,
730 (ulong)hw->addr.size, hw->ci->addr_mode);
734 switch (hw->ci->typ) {
737 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
738 hw->isac.mode = hw->cfg.mode;
739 hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
740 hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
741 hw->hscx.mode = hw->cfg.mode;
742 hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
743 hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
746 hw->ipac.type = IPAC_TYPE_IPAC;
747 hw->ipac.isac.off = 0x80;
748 hw->isac.mode = hw->addr.mode;
749 hw->isac.a.p = hw->addr.p;
750 hw->hscx.mode = hw->addr.mode;
751 hw->hscx.a.p = hw->addr.p;
754 hw->ipac.type = IPAC_TYPE_IPACX;
755 hw->isac.mode = hw->addr.mode;
756 hw->isac.a.p = hw->addr.p;
757 hw->hscx.mode = hw->addr.mode;
758 hw->hscx.a.p = hw->addr.p;
762 hw->ipac.type = IPAC_TYPE_IPAC;
763 hw->ipac.isac.off = 0x80;
764 hw->isac.mode = hw->cfg.mode;
765 hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
766 hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
767 hw->hscx.mode = hw->cfg.mode;
768 hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
769 hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
770 outb(0xff, (ulong)hw->cfg.start);
772 outb(0x00, (ulong)hw->cfg.start);
774 outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
778 hw->ipac.type = IPAC_TYPE_IPAC;
779 hw->ipac.isac.off = 0x80;
780 hw->isac.a.io.ale = (u32)hw->addr.start;
781 hw->isac.a.io.port = (u32)hw->addr.start + 1;
782 hw->isac.mode = hw->addr.mode;
783 hw->hscx.a.io.ale = (u32)hw->addr.start;
784 hw->hscx.a.io.port = (u32)hw->addr.start + 1;
785 hw->hscx.mode = hw->addr.mode;
788 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
789 hw->isac.mode = hw->addr.mode;
790 hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
791 hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
792 hw->hscx.mode = hw->addr.mode;
793 hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
794 hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
797 hw->ipac.type = IPAC_TYPE_IPAC;
798 hw->ipac.isac.off = 0x80;
799 hw->isac.a.io.ale = (u32)hw->addr.start;
800 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
801 hw->isac.mode = hw->addr.mode;
802 hw->hscx.a.io.ale = hw->isac.a.io.ale;
803 hw->hscx.a.io.port = hw->isac.a.io.port;
804 hw->hscx.mode = hw->addr.mode;
807 hw->ipac.type = IPAC_TYPE_IPAC;
808 hw->ipac.isac.off = 0x80;
809 hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
810 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
811 hw->isac.mode = hw->addr.mode;
812 hw->hscx.a.io.ale = hw->isac.a.io.ale;
813 hw->hscx.a.io.port = hw->isac.a.io.port;
814 hw->hscx.mode = hw->addr.mode;
817 hw->ipac.type = IPAC_TYPE_IPAC;
818 hw->ipac.isac.off = 0x80;
819 hw->isac.a.io.ale = (u32)hw->addr.start + 0x10;
820 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
821 hw->isac.mode = hw->addr.mode;
822 hw->hscx.a.io.ale = hw->isac.a.io.ale;
823 hw->hscx.a.io.port = hw->isac.a.io.port;
824 hw->hscx.mode = hw->addr.mode;
827 hw->ipac.type = IPAC_TYPE_IPAC;
828 hw->ipac.isac.off = 0x80;
829 hw->isac.a.io.ale = (u32)hw->addr.start + 0x20;
830 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
831 hw->isac.mode = hw->addr.mode;
832 hw->hscx.a.io.ale = hw->isac.a.io.ale;
833 hw->hscx.a.io.port = hw->isac.a.io.port;
834 hw->hscx.mode = hw->addr.mode;
837 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
838 hw->ipac.isac.off = 0x80;
839 hw->isac.mode = hw->addr.mode;
840 hw->isac.a.io.port = (u32)hw->addr.start;
841 hw->hscx.mode = hw->addr.mode;
842 hw->hscx.a.io.port = hw->isac.a.io.port;
845 hw->ipac.type = IPAC_TYPE_IPAC;
846 hw->ipac.isac.off = 0x80;
847 hw->isac.mode = hw->addr.mode;
848 hw->isac.a.io.ale = (u32)hw->addr.start;
849 hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
850 hw->hscx.mode = hw->addr.mode;
851 hw->hscx.a.io.ale = hw->isac.a.io.ale;
852 hw->hscx.a.io.port = hw->isac.a.io.port;
857 switch (hw->isac.mode) {
859 ASSIGN_FUNC_IPAC(MIO, hw->ipac);
862 ASSIGN_FUNC_IPAC(IND, hw->ipac);
865 ASSIGN_FUNC_IPAC(IO, hw->ipac);
874 release_card(struct inf_hw *card) {
878 spin_lock_irqsave(&card->lock, flags);
880 spin_unlock_irqrestore(&card->lock, flags);
881 card->ipac.isac.release(&card->ipac.isac);
882 free_irq(card->irq, card);
883 mISDN_unregister_device(&card->ipac.isac.dch.dev);
885 write_lock_irqsave(&card_lock, flags);
886 list_del(&card->list);
887 write_unlock_irqrestore(&card_lock, flags);
888 switch (card->ci->typ) {
894 for (i = 0; i < 3; i++) {
896 release_card(card->sc[i]);
900 pci_disable_device(card->pdev);
901 pci_set_drvdata(card->pdev, NULL);
909 setup_instance(struct inf_hw *card)
914 snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
916 write_lock_irqsave(&card_lock, flags);
917 list_add_tail(&card->list, &Cards);
918 write_unlock_irqrestore(&card_lock, flags);
921 card->ipac.isac.name = card->name;
922 card->ipac.name = card->name;
923 card->ipac.owner = THIS_MODULE;
924 spin_lock_init(&card->lock);
925 card->ipac.isac.hwlock = &card->lock;
926 card->ipac.hwlock = &card->lock;
927 card->ipac.ctrl = (void *)&inf_ctrl;
929 err = setup_io(card);
933 card->ipac.isac.dch.dev.Bprotocols =
934 mISDNipac_init(&card->ipac, card);
936 if (card->ipac.isac.dch.dev.Bprotocols == 0)
939 err = mISDN_register_device(&card->ipac.isac.dch.dev,
940 &card->pdev->dev, card->name);
944 err = init_irq(card);
947 pr_notice("Infineon %d cards installed\n", inf_cnt);
950 mISDN_unregister_device(&card->ipac.isac.dch.dev);
952 card->ipac.release(&card->ipac);
955 write_lock_irqsave(&card_lock, flags);
956 list_del(&card->list);
957 write_unlock_irqrestore(&card_lock, flags);
961 static const struct inf_cinfo inf_card_info[] = {
966 AM_IND_IO, AM_NONE, 2, 0,
971 "Dialogic Diva 2.0U",
973 AM_IND_IO, AM_NONE, 2, 0,
978 "Dialogic Diva 2.01",
980 AM_MEMIO, AM_MEMIO, 0, 1,
985 "Dialogic Diva 2.02",
987 AM_MEMIO, AM_MEMIO, 0, 1,
992 "Sedlbauer SpeedWin PCI",
994 AM_IND_IO, AM_NONE, 0, 0,
1001 AM_IND_IO, AM_NONE, 0, 0,
1006 "Develo Microlink PCI",
1008 AM_IO, AM_IND_IO, 1, 3,
1013 "Develo QuickStep 3000",
1015 AM_IO, AM_IND_IO, 1, 3,
1022 AM_IO, AM_IND_IO, 0, 1,
1029 AM_IO, AM_IND_IO, 1, 5,
1036 AM_NONE, AM_IND_IO, 0, 4,
1043 AM_NONE, AM_IND_IO, 0, 3,
1050 AM_NONE, AM_IND_IO, 0, 2,
1064 AM_IO, AM_IND_IO, 1, 2,
1072 static const struct inf_cinfo * __devinit
1073 get_card_info(enum inf_types typ)
1075 const struct inf_cinfo *ci = inf_card_info;
1077 while (ci->typ != INF_NONE) {
1085 static int __devinit
1086 inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1089 struct inf_hw *card;
1091 card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1093 pr_info("No memory for Infineon ISDN card\n");
1097 err = pci_enable_device(pdev);
1102 card->ci = get_card_info(ent->driver_data);
1104 pr_info("mISDN: do not have informations about adapter at %s\n",
1109 pr_notice("mISDN: found adapter %s at %s\n",
1110 card->ci->full, pci_name(pdev));
1112 card->irq = pdev->irq;
1113 pci_set_drvdata(pdev, card);
1114 err = setup_instance(card);
1116 pci_disable_device(card->pdev);
1118 pci_set_drvdata(pdev, NULL);
1119 } else if (ent->driver_data == INF_SCT_1) {
1123 for (i = 1; i < 4; i++) {
1124 sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1129 sc->irq = card->irq;
1130 sc->pdev = card->pdev;
1131 sc->ci = card->ci + i;
1132 err = setup_instance(sc);
1138 card->sc[i - 1] = sc;
1144 static void __devexit
1145 inf_remove(struct pci_dev *pdev)
1147 struct inf_hw *card = pci_get_drvdata(pdev);
1152 pr_debug("%s: drvdata allready removed\n", __func__);
1155 static struct pci_driver infineon_driver = {
1156 .name = "ISDN Infineon pci",
1158 .remove = __devexit_p(inf_remove),
1159 .id_table = infineon_ids,
1167 pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
1168 err = pci_register_driver(&infineon_driver);
1173 infineon_cleanup(void)
1175 pci_unregister_driver(&infineon_driver);
1178 module_init(infineon_init);
1179 module_exit(infineon_cleanup);