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_DESCRIPTION("mISDN driver for cards based on Infineon ISDN chipsets");
249 MODULE_LICENSE("GPL v2");
250 MODULE_VERSION(INFINEON_REV
);
251 module_param_call(debug
, set_debug
, param_get_uint
, &debug
, S_IRUGO
| S_IWUSR
);
252 MODULE_PARM_DESC(debug
, "infineon debug mask");
253 module_param(irqloops
, uint
, S_IRUGO
| S_IWUSR
);
254 MODULE_PARM_DESC(irqloops
, "infineon maximal irqloops (default 4)");
256 /* Interface functions */
258 IOFUNC_IO(ISAC
, inf_hw
, isac
.a
.io
)
259 IOFUNC_IO(IPAC
, inf_hw
, hscx
.a
.io
)
260 IOFUNC_IND(ISAC
, inf_hw
, isac
.a
.io
)
261 IOFUNC_IND(IPAC
, inf_hw
, hscx
.a
.io
)
262 IOFUNC_MEMIO(ISAC
, inf_hw
, u32
, isac
.a
.p
)
263 IOFUNC_MEMIO(IPAC
, inf_hw
, u32
, hscx
.a
.p
)
266 diva_irq(int intno
, void *dev_id
)
268 struct inf_hw
*hw
= dev_id
;
271 spin_lock(&hw
->lock
);
272 val
= inb((u32
)hw
->cfg
.start
+ DIVA_PCI_CTRL
);
273 if (!(val
& DIVA_IRQ_BIT
)) { /* for us or shared ? */
274 spin_unlock(&hw
->lock
);
275 return IRQ_NONE
; /* shared */
278 mISDNipac_irq(&hw
->ipac
, irqloops
);
279 spin_unlock(&hw
->lock
);
284 diva20x_irq(int intno
, void *dev_id
)
286 struct inf_hw
*hw
= dev_id
;
289 spin_lock(&hw
->lock
);
290 val
= readb(hw
->cfg
.p
);
291 if (!(val
& PITA_INT0_STATUS
)) { /* for us or shared ? */
292 spin_unlock(&hw
->lock
);
293 return IRQ_NONE
; /* shared */
296 mISDNipac_irq(&hw
->ipac
, irqloops
);
297 writeb(PITA_INT0_STATUS
, hw
->cfg
.p
); /* ACK PITA INT0 */
298 spin_unlock(&hw
->lock
);
303 tiger_irq(int intno
, void *dev_id
)
305 struct inf_hw
*hw
= dev_id
;
308 spin_lock(&hw
->lock
);
309 val
= inb((u32
)hw
->cfg
.start
+ TIGER_AUX_STATUS
);
310 if (val
& TIGER_IRQ_BIT
) { /* for us or shared ? */
311 spin_unlock(&hw
->lock
);
312 return IRQ_NONE
; /* shared */
315 mISDNipac_irq(&hw
->ipac
, irqloops
);
316 spin_unlock(&hw
->lock
);
321 elsa_irq(int intno
, void *dev_id
)
323 struct inf_hw
*hw
= dev_id
;
326 spin_lock(&hw
->lock
);
327 val
= inb((u32
)hw
->cfg
.start
+ ELSA_IRQ_ADDR
);
328 if (!(val
& ELSA_IRQ_MASK
)) {
329 spin_unlock(&hw
->lock
);
330 return IRQ_NONE
; /* shared */
333 mISDNipac_irq(&hw
->ipac
, irqloops
);
334 spin_unlock(&hw
->lock
);
339 niccy_irq(int intno
, void *dev_id
)
341 struct inf_hw
*hw
= dev_id
;
344 spin_lock(&hw
->lock
);
345 val
= inl((u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
346 if (!(val
& NICCY_IRQ_BIT
)) { /* for us or shared ? */
347 spin_unlock(&hw
->lock
);
348 return IRQ_NONE
; /* shared */
350 outl(val
, (u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
352 mISDNipac_irq(&hw
->ipac
, irqloops
);
353 spin_unlock(&hw
->lock
);
358 gazel_irq(int intno
, void *dev_id
)
360 struct inf_hw
*hw
= dev_id
;
363 spin_lock(&hw
->lock
);
364 ret
= mISDNipac_irq(&hw
->ipac
, irqloops
);
365 spin_unlock(&hw
->lock
);
370 ipac_irq(int intno
, void *dev_id
)
372 struct inf_hw
*hw
= dev_id
;
375 spin_lock(&hw
->lock
);
376 val
= hw
->ipac
.read_reg(hw
, IPAC_ISTA
);
378 spin_unlock(&hw
->lock
);
379 return IRQ_NONE
; /* shared */
382 mISDNipac_irq(&hw
->ipac
, irqloops
);
383 spin_unlock(&hw
->lock
);
388 enable_hwirq(struct inf_hw
*hw
)
393 switch (hw
->ci
->typ
) {
396 writel(PITA_INT0_ENABLE
, hw
->cfg
.p
);
400 outb(TIGER_IRQ_BIT
, (u32
)hw
->cfg
.start
+ TIGER_AUX_IRQMASK
);
403 outb(QS1000_IRQ_ON
, (u32
)hw
->cfg
.start
+ ELSA_IRQ_ADDR
);
406 outb(QS3000_IRQ_ON
, (u32
)hw
->cfg
.start
+ ELSA_IRQ_ADDR
);
409 val
= inl((u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
410 val
|= NICCY_IRQ_ENABLE
;
411 outl(val
, (u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
414 w
= inw((u32
)hw
->cfg
.start
+ SCT_PLX_IRQ_ADDR
);
415 w
|= SCT_PLX_IRQ_ENABLE
;
416 outw(w
, (u32
)hw
->cfg
.start
+ SCT_PLX_IRQ_ADDR
);
419 outb(GAZEL_ISAC_EN
+ GAZEL_HSCX_EN
+ GAZEL_PCI_EN
,
420 (u32
)hw
->cfg
.start
+ GAZEL_INCSR
);
423 outb(GAZEL_IPAC_EN
+ GAZEL_PCI_EN
,
424 (u32
)hw
->cfg
.start
+ GAZEL_INCSR
);
432 disable_hwirq(struct inf_hw
*hw
)
437 switch (hw
->ci
->typ
) {
440 writel(0, hw
->cfg
.p
);
444 outb(0, (u32
)hw
->cfg
.start
+ TIGER_AUX_IRQMASK
);
447 outb(QS1000_IRQ_OFF
, (u32
)hw
->cfg
.start
+ ELSA_IRQ_ADDR
);
450 outb(QS3000_IRQ_OFF
, (u32
)hw
->cfg
.start
+ ELSA_IRQ_ADDR
);
453 val
= inl((u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
454 val
&= NICCY_IRQ_DISABLE
;
455 outl(val
, (u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
458 w
= inw((u32
)hw
->cfg
.start
+ SCT_PLX_IRQ_ADDR
);
459 w
&= (~SCT_PLX_IRQ_ENABLE
);
460 outw(w
, (u32
)hw
->cfg
.start
+ SCT_PLX_IRQ_ADDR
);
464 outb(0, (u32
)hw
->cfg
.start
+ GAZEL_INCSR
);
472 ipac_chip_reset(struct inf_hw
*hw
)
474 hw
->ipac
.write_reg(hw
, IPAC_POTA2
, 0x20);
476 hw
->ipac
.write_reg(hw
, IPAC_POTA2
, 0x00);
478 hw
->ipac
.write_reg(hw
, IPAC_CONF
, hw
->ipac
.conf
);
479 hw
->ipac
.write_reg(hw
, IPAC_MASK
, 0xc0);
483 reset_inf(struct inf_hw
*hw
)
488 if (debug
& DEBUG_HW
)
489 pr_notice("%s: resetting card\n", hw
->name
);
490 switch (hw
->ci
->typ
) {
493 outb(0, (u32
)hw
->cfg
.start
+ DIVA_PCI_CTRL
);
495 outb(DIVA_RESET_BIT
, (u32
)hw
->cfg
.start
+ DIVA_PCI_CTRL
);
497 /* Workaround PCI9060 */
498 outb(9, (u32
)hw
->cfg
.start
+ 0x69);
499 outb(DIVA_RESET_BIT
| DIVA_LED_A
,
500 (u32
)hw
->cfg
.start
+ DIVA_PCI_CTRL
);
503 writel(PITA_PARA_SOFTRESET
| PITA_PARA_MPX_MODE
,
504 hw
->cfg
.p
+ PITA_MISC_REG
);
506 writel(PITA_PARA_MPX_MODE
, hw
->cfg
.p
+ PITA_MISC_REG
);
510 writel(PITA_PARA_SOFTRESET
| PITA_PARA_MPX_MODE
,
511 hw
->cfg
.p
+ PITA_MISC_REG
);
513 writel(PITA_PARA_MPX_MODE
| PITA_SER_SOFTRESET
,
514 hw
->cfg
.p
+ PITA_MISC_REG
);
520 hw
->ipac
.write_reg(hw
, IPAC_ACFG
, 0xff);
521 hw
->ipac
.write_reg(hw
, IPAC_AOE
, 0x00);
522 hw
->ipac
.write_reg(hw
, IPAC_PCFG
, 0x12);
527 hw
->ipac
.write_reg(hw
, IPAC_ACFG
, 0x00);
528 hw
->ipac
.write_reg(hw
, IPAC_AOE
, 0x3c);
529 hw
->ipac
.write_reg(hw
, IPAC_ATX
, 0xff);
534 w
= inw((u32
)hw
->cfg
.start
+ SCT_PLX_RESET_ADDR
);
535 w
&= (~SCT_PLX_RESET_BIT
);
536 outw(w
, (u32
)hw
->cfg
.start
+ SCT_PLX_RESET_ADDR
);
538 w
= inw((u32
)hw
->cfg
.start
+ SCT_PLX_RESET_ADDR
);
539 w
|= SCT_PLX_RESET_BIT
;
540 outw(w
, (u32
)hw
->cfg
.start
+ SCT_PLX_RESET_ADDR
);
544 val
= inl((u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
545 val
|= (GAZEL_RESET_9050
+ GAZEL_RESET
);
546 outl(val
, (u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
547 val
&= ~(GAZEL_RESET_9050
+ GAZEL_RESET
);
549 outl(val
, (u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
551 hw
->ipac
.isac
.adf2
= 0x87;
552 hw
->ipac
.hscx
[0].slot
= 0x1f;
553 hw
->ipac
.hscx
[1].slot
= 0x23;
556 val
= inl((u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
557 val
|= (GAZEL_RESET_9050
+ GAZEL_RESET
);
558 outl(val
, (u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
559 val
&= ~(GAZEL_RESET_9050
+ GAZEL_RESET
);
561 outl(val
, (u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
564 hw
->ipac
.write_reg(hw
, IPAC_ACFG
, 0xff);
565 hw
->ipac
.write_reg(hw
, IPAC_AOE
, 0x00);
566 hw
->ipac
.conf
= 0x01; /* IOM off */
575 inf_ctrl(struct inf_hw
*hw
, u32 cmd
, u_long arg
)
584 pr_info("%s: %s unknown command %x %lx\n",
585 hw
->name
, __func__
, cmd
, arg
);
593 init_irq(struct inf_hw
*hw
)
598 if (!hw
->ci
->irqfunc
)
600 ret
= request_irq(hw
->irq
, hw
->ci
->irqfunc
, IRQF_SHARED
, hw
->name
, hw
);
602 pr_info("%s: couldn't get interrupt %d\n", hw
->name
, hw
->irq
);
606 spin_lock_irqsave(&hw
->lock
, flags
);
608 ret
= hw
->ipac
.init(&hw
->ipac
);
610 spin_unlock_irqrestore(&hw
->lock
, flags
);
611 pr_info("%s: ISAC init failed with %d\n",
615 spin_unlock_irqrestore(&hw
->lock
, flags
);
616 msleep_interruptible(10);
617 if (debug
& DEBUG_HW
)
618 pr_notice("%s: IRQ %d count %d\n", hw
->name
,
619 hw
->irq
, hw
->irqcnt
);
621 pr_info("%s: IRQ(%d) got no requests during init %d\n",
622 hw
->name
, hw
->irq
, 3 - cnt
);
626 free_irq(hw
->irq
, hw
);
631 release_io(struct inf_hw
*hw
)
634 if (hw
->cfg
.mode
== AM_MEMIO
) {
635 release_mem_region(hw
->cfg
.start
, hw
->cfg
.size
);
639 release_region(hw
->cfg
.start
, hw
->cfg
.size
);
640 hw
->cfg
.mode
= AM_NONE
;
643 if (hw
->addr
.mode
== AM_MEMIO
) {
644 release_mem_region(hw
->addr
.start
, hw
->addr
.size
);
648 release_region(hw
->addr
.start
, hw
->addr
.size
);
649 hw
->addr
.mode
= AM_NONE
;
654 setup_io(struct inf_hw
*hw
)
658 if (hw
->ci
->cfg_mode
) {
659 hw
->cfg
.start
= pci_resource_start(hw
->pdev
, hw
->ci
->cfg_bar
);
660 hw
->cfg
.size
= pci_resource_len(hw
->pdev
, hw
->ci
->cfg_bar
);
661 if (hw
->ci
->cfg_mode
== AM_MEMIO
) {
662 if (!request_mem_region(hw
->cfg
.start
, hw
->cfg
.size
,
666 if (!request_region(hw
->cfg
.start
, hw
->cfg
.size
,
671 pr_info("mISDN: %s config port %lx (%lu bytes)"
672 "already in use\n", hw
->name
,
673 (ulong
)hw
->cfg
.start
, (ulong
)hw
->cfg
.size
);
676 hw
->cfg
.mode
= hw
->ci
->cfg_mode
;
677 if (hw
->ci
->cfg_mode
== AM_MEMIO
) {
678 hw
->cfg
.p
= ioremap(hw
->cfg
.start
, hw
->cfg
.size
);
682 if (debug
& DEBUG_HW
)
683 pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
684 hw
->name
, (ulong
)hw
->cfg
.start
,
685 (ulong
)hw
->cfg
.size
, hw
->ci
->cfg_mode
);
688 if (hw
->ci
->addr_mode
) {
689 hw
->addr
.start
= pci_resource_start(hw
->pdev
, hw
->ci
->addr_bar
);
690 hw
->addr
.size
= pci_resource_len(hw
->pdev
, hw
->ci
->addr_bar
);
691 if (hw
->ci
->addr_mode
== AM_MEMIO
) {
692 if (!request_mem_region(hw
->addr
.start
, hw
->addr
.size
,
696 if (!request_region(hw
->addr
.start
, hw
->addr
.size
,
701 pr_info("mISDN: %s address port %lx (%lu bytes)"
702 "already in use\n", hw
->name
,
703 (ulong
)hw
->addr
.start
, (ulong
)hw
->addr
.size
);
706 hw
->addr
.mode
= hw
->ci
->addr_mode
;
707 if (hw
->ci
->addr_mode
== AM_MEMIO
) {
708 hw
->addr
.p
= ioremap(hw
->addr
.start
, hw
->addr
.size
);
712 if (debug
& DEBUG_HW
)
713 pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
714 hw
->name
, (ulong
)hw
->addr
.start
,
715 (ulong
)hw
->addr
.size
, hw
->ci
->addr_mode
);
719 switch (hw
->ci
->typ
) {
722 hw
->ipac
.type
= IPAC_TYPE_ISAC
| IPAC_TYPE_HSCX
;
723 hw
->isac
.mode
= hw
->cfg
.mode
;
724 hw
->isac
.a
.io
.ale
= (u32
)hw
->cfg
.start
+ DIVA_ISAC_ALE
;
725 hw
->isac
.a
.io
.port
= (u32
)hw
->cfg
.start
+ DIVA_ISAC_PORT
;
726 hw
->hscx
.mode
= hw
->cfg
.mode
;
727 hw
->hscx
.a
.io
.ale
= (u32
)hw
->cfg
.start
+ DIVA_HSCX_ALE
;
728 hw
->hscx
.a
.io
.port
= (u32
)hw
->cfg
.start
+ DIVA_HSCX_PORT
;
731 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
732 hw
->ipac
.isac
.off
= 0x80;
733 hw
->isac
.mode
= hw
->addr
.mode
;
734 hw
->isac
.a
.p
= hw
->addr
.p
;
735 hw
->hscx
.mode
= hw
->addr
.mode
;
736 hw
->hscx
.a
.p
= hw
->addr
.p
;
739 hw
->ipac
.type
= IPAC_TYPE_IPACX
;
740 hw
->isac
.mode
= hw
->addr
.mode
;
741 hw
->isac
.a
.p
= hw
->addr
.p
;
742 hw
->hscx
.mode
= hw
->addr
.mode
;
743 hw
->hscx
.a
.p
= hw
->addr
.p
;
747 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
748 hw
->ipac
.isac
.off
= 0x80;
749 hw
->isac
.mode
= hw
->cfg
.mode
;
750 hw
->isac
.a
.io
.ale
= (u32
)hw
->cfg
.start
+ TIGER_IPAC_ALE
;
751 hw
->isac
.a
.io
.port
= (u32
)hw
->cfg
.start
+ TIGER_IPAC_PORT
;
752 hw
->hscx
.mode
= hw
->cfg
.mode
;
753 hw
->hscx
.a
.io
.ale
= (u32
)hw
->cfg
.start
+ TIGER_IPAC_ALE
;
754 hw
->hscx
.a
.io
.port
= (u32
)hw
->cfg
.start
+ TIGER_IPAC_PORT
;
755 outb(0xff, (ulong
)hw
->cfg
.start
);
757 outb(0x00, (ulong
)hw
->cfg
.start
);
759 outb(TIGER_IOMASK
, (ulong
)hw
->cfg
.start
+ TIGER_AUX_CTRL
);
763 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
764 hw
->ipac
.isac
.off
= 0x80;
765 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
;
766 hw
->isac
.a
.io
.port
= (u32
)hw
->addr
.start
+ 1;
767 hw
->isac
.mode
= hw
->addr
.mode
;
768 hw
->hscx
.a
.io
.ale
= (u32
)hw
->addr
.start
;
769 hw
->hscx
.a
.io
.port
= (u32
)hw
->addr
.start
+ 1;
770 hw
->hscx
.mode
= hw
->addr
.mode
;
773 hw
->ipac
.type
= IPAC_TYPE_ISAC
| IPAC_TYPE_HSCX
;
774 hw
->isac
.mode
= hw
->addr
.mode
;
775 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
+ NICCY_ISAC_ALE
;
776 hw
->isac
.a
.io
.port
= (u32
)hw
->addr
.start
+ NICCY_ISAC_PORT
;
777 hw
->hscx
.mode
= hw
->addr
.mode
;
778 hw
->hscx
.a
.io
.ale
= (u32
)hw
->addr
.start
+ NICCY_HSCX_ALE
;
779 hw
->hscx
.a
.io
.port
= (u32
)hw
->addr
.start
+ NICCY_HSCX_PORT
;
782 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
783 hw
->ipac
.isac
.off
= 0x80;
784 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
;
785 hw
->isac
.a
.io
.port
= hw
->isac
.a
.io
.ale
+ 4;
786 hw
->isac
.mode
= hw
->addr
.mode
;
787 hw
->hscx
.a
.io
.ale
= hw
->isac
.a
.io
.ale
;
788 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
789 hw
->hscx
.mode
= hw
->addr
.mode
;
792 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
793 hw
->ipac
.isac
.off
= 0x80;
794 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
+ 0x08;
795 hw
->isac
.a
.io
.port
= hw
->isac
.a
.io
.ale
+ 4;
796 hw
->isac
.mode
= hw
->addr
.mode
;
797 hw
->hscx
.a
.io
.ale
= hw
->isac
.a
.io
.ale
;
798 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
799 hw
->hscx
.mode
= hw
->addr
.mode
;
802 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
803 hw
->ipac
.isac
.off
= 0x80;
804 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
+ 0x10;
805 hw
->isac
.a
.io
.port
= hw
->isac
.a
.io
.ale
+ 4;
806 hw
->isac
.mode
= hw
->addr
.mode
;
807 hw
->hscx
.a
.io
.ale
= hw
->isac
.a
.io
.ale
;
808 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
809 hw
->hscx
.mode
= hw
->addr
.mode
;
812 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
813 hw
->ipac
.isac
.off
= 0x80;
814 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
+ 0x20;
815 hw
->isac
.a
.io
.port
= hw
->isac
.a
.io
.ale
+ 4;
816 hw
->isac
.mode
= hw
->addr
.mode
;
817 hw
->hscx
.a
.io
.ale
= hw
->isac
.a
.io
.ale
;
818 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
819 hw
->hscx
.mode
= hw
->addr
.mode
;
822 hw
->ipac
.type
= IPAC_TYPE_ISAC
| IPAC_TYPE_HSCX
;
823 hw
->ipac
.isac
.off
= 0x80;
824 hw
->isac
.mode
= hw
->addr
.mode
;
825 hw
->isac
.a
.io
.port
= (u32
)hw
->addr
.start
;
826 hw
->hscx
.mode
= hw
->addr
.mode
;
827 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
830 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
831 hw
->ipac
.isac
.off
= 0x80;
832 hw
->isac
.mode
= hw
->addr
.mode
;
833 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
;
834 hw
->isac
.a
.io
.port
= (u32
)hw
->addr
.start
+ GAZEL_IPAC_DATA_PORT
;
835 hw
->hscx
.mode
= hw
->addr
.mode
;
836 hw
->hscx
.a
.io
.ale
= hw
->isac
.a
.io
.ale
;
837 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
842 switch (hw
->isac
.mode
) {
844 ASSIGN_FUNC_IPAC(MIO
, hw
->ipac
);
847 ASSIGN_FUNC_IPAC(IND
, hw
->ipac
);
850 ASSIGN_FUNC_IPAC(IO
, hw
->ipac
);
859 release_card(struct inf_hw
*card
) {
863 spin_lock_irqsave(&card
->lock
, flags
);
865 spin_unlock_irqrestore(&card
->lock
, flags
);
866 card
->ipac
.isac
.release(&card
->ipac
.isac
);
867 free_irq(card
->irq
, card
);
868 mISDN_unregister_device(&card
->ipac
.isac
.dch
.dev
);
870 write_lock_irqsave(&card_lock
, flags
);
871 list_del(&card
->list
);
872 write_unlock_irqrestore(&card_lock
, flags
);
873 switch (card
->ci
->typ
) {
879 for (i
= 0; i
< 3; i
++) {
881 release_card(card
->sc
[i
]);
886 pci_disable_device(card
->pdev
);
887 pci_set_drvdata(card
->pdev
, NULL
);
895 setup_instance(struct inf_hw
*card
)
900 snprintf(card
->name
, MISDN_MAX_IDLEN
- 1, "%s.%d", card
->ci
->name
,
902 write_lock_irqsave(&card_lock
, flags
);
903 list_add_tail(&card
->list
, &Cards
);
904 write_unlock_irqrestore(&card_lock
, flags
);
907 card
->ipac
.isac
.name
= card
->name
;
908 card
->ipac
.name
= card
->name
;
909 card
->ipac
.owner
= THIS_MODULE
;
910 spin_lock_init(&card
->lock
);
911 card
->ipac
.isac
.hwlock
= &card
->lock
;
912 card
->ipac
.hwlock
= &card
->lock
;
913 card
->ipac
.ctrl
= (void *)&inf_ctrl
;
915 err
= setup_io(card
);
919 card
->ipac
.isac
.dch
.dev
.Bprotocols
=
920 mISDNipac_init(&card
->ipac
, card
);
922 if (card
->ipac
.isac
.dch
.dev
.Bprotocols
== 0)
925 err
= mISDN_register_device(&card
->ipac
.isac
.dch
.dev
,
926 &card
->pdev
->dev
, card
->name
);
930 err
= init_irq(card
);
933 pr_notice("Infineon %d cards installed\n", inf_cnt
);
936 mISDN_unregister_device(&card
->ipac
.isac
.dch
.dev
);
938 card
->ipac
.release(&card
->ipac
);
941 write_lock_irqsave(&card_lock
, flags
);
942 list_del(&card
->list
);
943 write_unlock_irqrestore(&card_lock
, flags
);
947 static const struct inf_cinfo inf_card_info
[] = {
952 AM_IND_IO
, AM_NONE
, 2, 0,
957 "Dialogic Diva 2.0U",
959 AM_IND_IO
, AM_NONE
, 2, 0,
964 "Dialogic Diva 2.01",
966 AM_MEMIO
, AM_MEMIO
, 0, 1,
971 "Dialogic Diva 2.02",
973 AM_MEMIO
, AM_MEMIO
, 0, 1,
978 "Sedlbauer SpeedWin PCI",
980 AM_IND_IO
, AM_NONE
, 0, 0,
987 AM_IND_IO
, AM_NONE
, 0, 0,
992 "Develo Microlink PCI",
994 AM_IO
, AM_IND_IO
, 1, 3,
999 "Develo QuickStep 3000",
1001 AM_IO
, AM_IND_IO
, 1, 3,
1008 AM_IO
, AM_IND_IO
, 0, 1,
1015 AM_IO
, AM_IND_IO
, 1, 5,
1022 AM_NONE
, AM_IND_IO
, 0, 4,
1029 AM_NONE
, AM_IND_IO
, 0, 3,
1036 AM_NONE
, AM_IND_IO
, 0, 2,
1050 AM_IO
, AM_IND_IO
, 1, 2,
1058 static const struct inf_cinfo
*
1059 get_card_info(enum inf_types typ
)
1061 const struct inf_cinfo
*ci
= inf_card_info
;
1063 while (ci
->typ
!= INF_NONE
) {
1072 inf_probe(struct pci_dev
*pdev
, const struct pci_device_id
*ent
)
1075 struct inf_hw
*card
;
1077 card
= kzalloc(sizeof(struct inf_hw
), GFP_KERNEL
);
1079 pr_info("No memory for Infineon ISDN card\n");
1083 err
= pci_enable_device(pdev
);
1088 card
->ci
= get_card_info(ent
->driver_data
);
1090 pr_info("mISDN: do not have information about adapter at %s\n",
1093 pci_disable_device(pdev
);
1096 pr_notice("mISDN: found adapter %s at %s\n",
1097 card
->ci
->full
, pci_name(pdev
));
1099 card
->irq
= pdev
->irq
;
1100 pci_set_drvdata(pdev
, card
);
1101 err
= setup_instance(card
);
1103 pci_disable_device(pdev
);
1105 pci_set_drvdata(pdev
, NULL
);
1106 } else if (ent
->driver_data
== INF_SCT_1
) {
1110 for (i
= 1; i
< 4; i
++) {
1111 sc
= kzalloc(sizeof(struct inf_hw
), GFP_KERNEL
);
1114 pci_disable_device(pdev
);
1117 sc
->irq
= card
->irq
;
1118 sc
->pdev
= card
->pdev
;
1119 sc
->ci
= card
->ci
+ i
;
1120 err
= setup_instance(sc
);
1122 pci_disable_device(pdev
);
1127 card
->sc
[i
- 1] = sc
;
1134 inf_remove(struct pci_dev
*pdev
)
1136 struct inf_hw
*card
= pci_get_drvdata(pdev
);
1141 pr_debug("%s: drvdata already removed\n", __func__
);
1144 static struct pci_driver infineon_driver
= {
1145 .name
= "ISDN Infineon pci",
1147 .remove
= inf_remove
,
1148 .id_table
= infineon_ids
,
1156 pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV
);
1157 err
= pci_register_driver(&infineon_driver
);
1162 infineon_cleanup(void)
1164 pci_unregister_driver(&infineon_driver
);
1167 module_init(infineon_init
);
1168 module_exit(infineon_cleanup
);