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>
45 #include <linux/slab.h>
48 #define INFINEON_REV "1.0"
52 static u32 irqloops
= 4;
84 enum addr_mode cfg_mode
;
85 enum addr_mode addr_mode
;
101 resource_size_t size
;
102 resource_size_t start
;
107 struct list_head list
;
108 struct pci_dev
*pdev
;
109 const struct inf_cinfo
*ci
;
110 char name
[MISDN_MAX_IDLEN
];
113 struct _iohandle cfg
;
114 struct _iohandle addr
;
117 spinlock_t lock
; /* HW access lock */
119 struct inf_hw
*sc
[3]; /* slave cards */
123 #define PCI_SUBVENDOR_HST_SAPHIR3 0x52
124 #define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
125 #define PCI_SUB_ID_SEDLBAUER 0x01
127 static struct pci_device_id infineon_ids
[] __devinitdata
= {
128 { PCI_VENDOR_ID_EICON
, PCI_DEVICE_ID_EICON_DIVA20
,
129 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_DIVA20
},
130 { PCI_VENDOR_ID_EICON
, PCI_DEVICE_ID_EICON_DIVA20_U
,
131 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_DIVA20U
},
132 { PCI_VENDOR_ID_EICON
, PCI_DEVICE_ID_EICON_DIVA201
,
133 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_DIVA201
},
134 { PCI_VENDOR_ID_EICON
, PCI_DEVICE_ID_EICON_DIVA202
,
135 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_DIVA202
},
136 { PCI_VENDOR_ID_TIGERJET
, PCI_DEVICE_ID_TIGERJET_100
,
137 PCI_SUBVENDOR_SEDLBAUER_PCI
, PCI_SUB_ID_SEDLBAUER
, 0, 0,
139 { PCI_VENDOR_ID_TIGERJET
, PCI_DEVICE_ID_TIGERJET_100
,
140 PCI_SUBVENDOR_HST_SAPHIR3
, PCI_SUB_ID_SEDLBAUER
, 0, 0, INF_SAPHIR3
},
141 { PCI_VENDOR_ID_ELSA
, PCI_DEVICE_ID_ELSA_MICROLINK
,
142 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_QS1000
},
143 { PCI_VENDOR_ID_ELSA
, PCI_DEVICE_ID_ELSA_QS3000
,
144 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_QS3000
},
145 { PCI_VENDOR_ID_SATSAGEM
, PCI_DEVICE_ID_SATSAGEM_NICCY
,
146 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_NICCY
},
147 { PCI_VENDOR_ID_PLX
, PCI_DEVICE_ID_PLX_9050
,
148 PCI_VENDOR_ID_BERKOM
, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO
, 0, 0,
150 { PCI_VENDOR_ID_PLX
, PCI_DEVICE_ID_PLX_R685
,
151 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_GAZEL_R685
},
152 { PCI_VENDOR_ID_PLX
, PCI_DEVICE_ID_PLX_R753
,
153 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_GAZEL_R753
},
154 { PCI_VENDOR_ID_PLX
, PCI_DEVICE_ID_PLX_DJINN_ITOO
,
155 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_GAZEL_R753
},
156 { PCI_VENDOR_ID_PLX
, PCI_DEVICE_ID_PLX_OLITEC
,
157 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, INF_GAZEL_R753
},
160 MODULE_DEVICE_TABLE(pci
, infineon_ids
);
162 /* PCI interface specific defines */
164 #define DIVA_HSCX_PORT 0x00
165 #define DIVA_HSCX_ALE 0x04
166 #define DIVA_ISAC_PORT 0x08
167 #define DIVA_ISAC_ALE 0x0C
168 #define DIVA_PCI_CTRL 0x10
170 /* DIVA_PCI_CTRL bits */
171 #define DIVA_IRQ_BIT 0x01
172 #define DIVA_RESET_BIT 0x08
173 #define DIVA_EEPROM_CLK 0x40
174 #define DIVA_LED_A 0x10
175 #define DIVA_LED_B 0x20
176 #define DIVA_IRQ_CLR 0x80
180 #define PITA_ICR_REG 0x00
181 #define PITA_INT0_STATUS 0x02
183 #define PITA_MISC_REG 0x1c
184 #define PITA_PARA_SOFTRESET 0x01000000
185 #define PITA_SER_SOFTRESET 0x02000000
186 #define PITA_PARA_MPX_MODE 0x04000000
187 #define PITA_INT0_ENABLE 0x00020000
189 /* TIGER 100 Registers */
190 #define TIGER_RESET_ADDR 0x00
191 #define TIGER_EXTERN_RESET 0x01
192 #define TIGER_AUX_CTRL 0x02
193 #define TIGER_AUX_DATA 0x03
194 #define TIGER_AUX_IRQMASK 0x05
195 #define TIGER_AUX_STATUS 0x07
198 #define TIGER_IOMASK 0xdd /* 1 and 5 are inputs */
199 #define TIGER_IRQ_BIT 0x02
201 #define TIGER_IPAC_ALE 0xC0
202 #define TIGER_IPAC_PORT 0xC8
204 /* ELSA (now Develo) PCI cards */
205 #define ELSA_IRQ_ADDR 0x4c
206 #define ELSA_IRQ_MASK 0x04
207 #define QS1000_IRQ_OFF 0x01
208 #define QS3000_IRQ_OFF 0x03
209 #define QS1000_IRQ_ON 0x41
210 #define QS3000_IRQ_ON 0x43
212 /* Dr Neuhaus/Sagem Niccy */
213 #define NICCY_ISAC_PORT 0x00
214 #define NICCY_HSCX_PORT 0x01
215 #define NICCY_ISAC_ALE 0x02
216 #define NICCY_HSCX_ALE 0x03
218 #define NICCY_IRQ_CTRL_REG 0x38
219 #define NICCY_IRQ_ENABLE 0x001f00
220 #define NICCY_IRQ_DISABLE 0xff0000
221 #define NICCY_IRQ_BIT 0x800000
225 #define SCT_PLX_IRQ_ADDR 0x4c
226 #define SCT_PLX_RESET_ADDR 0x50
227 #define SCT_PLX_IRQ_ENABLE 0x41
228 #define SCT_PLX_RESET_BIT 0x04
231 #define GAZEL_IPAC_DATA_PORT 0x04
233 #define GAZEL_CNTRL 0x50
234 #define GAZEL_RESET 0x04
235 #define GAZEL_RESET_9050 0x40000000
236 #define GAZEL_INCSR 0x4C
237 #define GAZEL_ISAC_EN 0x08
238 #define GAZEL_INT_ISAC 0x20
239 #define GAZEL_HSCX_EN 0x01
240 #define GAZEL_INT_HSCX 0x04
241 #define GAZEL_PCI_EN 0x40
242 #define GAZEL_IPAC_EN 0x03
245 static LIST_HEAD(Cards
);
246 static DEFINE_RWLOCK(card_lock
); /* protect Cards */
249 _set_debug(struct inf_hw
*card
)
251 card
->ipac
.isac
.dch
.debug
= debug
;
252 card
->ipac
.hscx
[0].bch
.debug
= debug
;
253 card
->ipac
.hscx
[1].bch
.debug
= debug
;
257 set_debug(const char *val
, struct kernel_param
*kp
)
262 ret
= param_set_uint(val
, kp
);
264 read_lock(&card_lock
);
265 list_for_each_entry(card
, &Cards
, list
)
267 read_unlock(&card_lock
);
272 MODULE_AUTHOR("Karsten Keil");
273 MODULE_LICENSE("GPL v2");
274 MODULE_VERSION(INFINEON_REV
);
275 module_param_call(debug
, set_debug
, param_get_uint
, &debug
, S_IRUGO
| S_IWUSR
);
276 MODULE_PARM_DESC(debug
, "infineon debug mask");
277 module_param(irqloops
, uint
, S_IRUGO
| S_IWUSR
);
278 MODULE_PARM_DESC(irqloops
, "infineon maximal irqloops (default 4)");
280 /* Interface functions */
282 IOFUNC_IO(ISAC
, inf_hw
, isac
.a
.io
)
283 IOFUNC_IO(IPAC
, inf_hw
, hscx
.a
.io
)
284 IOFUNC_IND(ISAC
, inf_hw
, isac
.a
.io
)
285 IOFUNC_IND(IPAC
, inf_hw
, hscx
.a
.io
)
286 IOFUNC_MEMIO(ISAC
, inf_hw
, u32
, isac
.a
.p
)
287 IOFUNC_MEMIO(IPAC
, inf_hw
, u32
, hscx
.a
.p
)
290 diva_irq(int intno
, void *dev_id
)
292 struct inf_hw
*hw
= dev_id
;
295 spin_lock(&hw
->lock
);
296 val
= inb((u32
)hw
->cfg
.start
+ DIVA_PCI_CTRL
);
297 if (!(val
& DIVA_IRQ_BIT
)) { /* for us or shared ? */
298 spin_unlock(&hw
->lock
);
299 return IRQ_NONE
; /* shared */
302 mISDNipac_irq(&hw
->ipac
, irqloops
);
303 spin_unlock(&hw
->lock
);
308 diva20x_irq(int intno
, void *dev_id
)
310 struct inf_hw
*hw
= dev_id
;
313 spin_lock(&hw
->lock
);
314 val
= readb(hw
->cfg
.p
);
315 if (!(val
& PITA_INT0_STATUS
)) { /* for us or shared ? */
316 spin_unlock(&hw
->lock
);
317 return IRQ_NONE
; /* shared */
320 mISDNipac_irq(&hw
->ipac
, irqloops
);
321 writeb(PITA_INT0_STATUS
, hw
->cfg
.p
); /* ACK PITA INT0 */
322 spin_unlock(&hw
->lock
);
327 tiger_irq(int intno
, void *dev_id
)
329 struct inf_hw
*hw
= dev_id
;
332 spin_lock(&hw
->lock
);
333 val
= inb((u32
)hw
->cfg
.start
+ TIGER_AUX_STATUS
);
334 if (val
& TIGER_IRQ_BIT
) { /* for us or shared ? */
335 spin_unlock(&hw
->lock
);
336 return IRQ_NONE
; /* shared */
339 mISDNipac_irq(&hw
->ipac
, irqloops
);
340 spin_unlock(&hw
->lock
);
345 elsa_irq(int intno
, void *dev_id
)
347 struct inf_hw
*hw
= dev_id
;
350 spin_lock(&hw
->lock
);
351 val
= inb((u32
)hw
->cfg
.start
+ ELSA_IRQ_ADDR
);
352 if (!(val
& ELSA_IRQ_MASK
)) {
353 spin_unlock(&hw
->lock
);
354 return IRQ_NONE
; /* shared */
357 mISDNipac_irq(&hw
->ipac
, irqloops
);
358 spin_unlock(&hw
->lock
);
363 niccy_irq(int intno
, void *dev_id
)
365 struct inf_hw
*hw
= dev_id
;
368 spin_lock(&hw
->lock
);
369 val
= inl((u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
370 if (!(val
& NICCY_IRQ_BIT
)) { /* for us or shared ? */
371 spin_unlock(&hw
->lock
);
372 return IRQ_NONE
; /* shared */
374 outl(val
, (u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
376 mISDNipac_irq(&hw
->ipac
, irqloops
);
377 spin_unlock(&hw
->lock
);
382 gazel_irq(int intno
, void *dev_id
)
384 struct inf_hw
*hw
= dev_id
;
387 spin_lock(&hw
->lock
);
388 ret
= mISDNipac_irq(&hw
->ipac
, irqloops
);
389 spin_unlock(&hw
->lock
);
394 ipac_irq(int intno
, void *dev_id
)
396 struct inf_hw
*hw
= dev_id
;
399 spin_lock(&hw
->lock
);
400 val
= hw
->ipac
.read_reg(hw
, IPAC_ISTA
);
402 spin_unlock(&hw
->lock
);
403 return IRQ_NONE
; /* shared */
406 mISDNipac_irq(&hw
->ipac
, irqloops
);
407 spin_unlock(&hw
->lock
);
412 enable_hwirq(struct inf_hw
*hw
)
417 switch (hw
->ci
->typ
) {
420 writel(PITA_INT0_ENABLE
, hw
->cfg
.p
);
424 outb(TIGER_IRQ_BIT
, (u32
)hw
->cfg
.start
+ TIGER_AUX_IRQMASK
);
427 outb(QS1000_IRQ_ON
, (u32
)hw
->cfg
.start
+ ELSA_IRQ_ADDR
);
430 outb(QS3000_IRQ_ON
, (u32
)hw
->cfg
.start
+ ELSA_IRQ_ADDR
);
433 val
= inl((u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
434 val
|= NICCY_IRQ_ENABLE
;;
435 outl(val
, (u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
438 w
= inw((u32
)hw
->cfg
.start
+ SCT_PLX_IRQ_ADDR
);
439 w
|= SCT_PLX_IRQ_ENABLE
;
440 outw(w
, (u32
)hw
->cfg
.start
+ SCT_PLX_IRQ_ADDR
);
443 outb(GAZEL_ISAC_EN
+ GAZEL_HSCX_EN
+ GAZEL_PCI_EN
,
444 (u32
)hw
->cfg
.start
+ GAZEL_INCSR
);
447 outb(GAZEL_IPAC_EN
+ GAZEL_PCI_EN
,
448 (u32
)hw
->cfg
.start
+ GAZEL_INCSR
);
456 disable_hwirq(struct inf_hw
*hw
)
461 switch (hw
->ci
->typ
) {
464 writel(0, hw
->cfg
.p
);
468 outb(0, (u32
)hw
->cfg
.start
+ TIGER_AUX_IRQMASK
);
471 outb(QS1000_IRQ_OFF
, (u32
)hw
->cfg
.start
+ ELSA_IRQ_ADDR
);
474 outb(QS3000_IRQ_OFF
, (u32
)hw
->cfg
.start
+ ELSA_IRQ_ADDR
);
477 val
= inl((u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
478 val
&= NICCY_IRQ_DISABLE
;
479 outl(val
, (u32
)hw
->cfg
.start
+ NICCY_IRQ_CTRL_REG
);
482 w
= inw((u32
)hw
->cfg
.start
+ SCT_PLX_IRQ_ADDR
);
483 w
&= (~SCT_PLX_IRQ_ENABLE
);
484 outw(w
, (u32
)hw
->cfg
.start
+ SCT_PLX_IRQ_ADDR
);
488 outb(0, (u32
)hw
->cfg
.start
+ GAZEL_INCSR
);
496 ipac_chip_reset(struct inf_hw
*hw
)
498 hw
->ipac
.write_reg(hw
, IPAC_POTA2
, 0x20);
500 hw
->ipac
.write_reg(hw
, IPAC_POTA2
, 0x00);
502 hw
->ipac
.write_reg(hw
, IPAC_CONF
, hw
->ipac
.conf
);
503 hw
->ipac
.write_reg(hw
, IPAC_MASK
, 0xc0);
507 reset_inf(struct inf_hw
*hw
)
512 if (debug
& DEBUG_HW
)
513 pr_notice("%s: resetting card\n", hw
->name
);
514 switch (hw
->ci
->typ
) {
517 outb(0, (u32
)hw
->cfg
.start
+ DIVA_PCI_CTRL
);
519 outb(DIVA_RESET_BIT
, (u32
)hw
->cfg
.start
+ DIVA_PCI_CTRL
);
521 /* Workaround PCI9060 */
522 outb(9, (u32
)hw
->cfg
.start
+ 0x69);
523 outb(DIVA_RESET_BIT
| DIVA_LED_A
,
524 (u32
)hw
->cfg
.start
+ DIVA_PCI_CTRL
);
527 writel(PITA_PARA_SOFTRESET
| PITA_PARA_MPX_MODE
,
528 hw
->cfg
.p
+ PITA_MISC_REG
);
530 writel(PITA_PARA_MPX_MODE
, hw
->cfg
.p
+ PITA_MISC_REG
);
534 writel(PITA_PARA_SOFTRESET
| PITA_PARA_MPX_MODE
,
535 hw
->cfg
.p
+ PITA_MISC_REG
);
537 writel(PITA_PARA_MPX_MODE
| PITA_SER_SOFTRESET
,
538 hw
->cfg
.p
+ PITA_MISC_REG
);
544 hw
->ipac
.write_reg(hw
, IPAC_ACFG
, 0xff);
545 hw
->ipac
.write_reg(hw
, IPAC_AOE
, 0x00);
546 hw
->ipac
.write_reg(hw
, IPAC_PCFG
, 0x12);
551 hw
->ipac
.write_reg(hw
, IPAC_ACFG
, 0x00);
552 hw
->ipac
.write_reg(hw
, IPAC_AOE
, 0x3c);
553 hw
->ipac
.write_reg(hw
, IPAC_ATX
, 0xff);
558 w
= inw((u32
)hw
->cfg
.start
+ SCT_PLX_RESET_ADDR
);
559 w
&= (~SCT_PLX_RESET_BIT
);
560 outw(w
, (u32
)hw
->cfg
.start
+ SCT_PLX_RESET_ADDR
);
562 w
= inw((u32
)hw
->cfg
.start
+ SCT_PLX_RESET_ADDR
);
563 w
|= SCT_PLX_RESET_BIT
;
564 outw(w
, (u32
)hw
->cfg
.start
+ SCT_PLX_RESET_ADDR
);
568 val
= inl((u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
569 val
|= (GAZEL_RESET_9050
+ GAZEL_RESET
);
570 outl(val
, (u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
571 val
&= ~(GAZEL_RESET_9050
+ GAZEL_RESET
);
573 outl(val
, (u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
575 hw
->ipac
.isac
.adf2
= 0x87;
576 hw
->ipac
.hscx
[0].slot
= 0x1f;
577 hw
->ipac
.hscx
[0].slot
= 0x23;
580 val
= inl((u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
581 val
|= (GAZEL_RESET_9050
+ GAZEL_RESET
);
582 outl(val
, (u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
583 val
&= ~(GAZEL_RESET_9050
+ GAZEL_RESET
);
585 outl(val
, (u32
)hw
->cfg
.start
+ GAZEL_CNTRL
);
588 hw
->ipac
.write_reg(hw
, IPAC_ACFG
, 0xff);
589 hw
->ipac
.write_reg(hw
, IPAC_AOE
, 0x00);
590 hw
->ipac
.conf
= 0x01; /* IOM off */
599 inf_ctrl(struct inf_hw
*hw
, u32 cmd
, u_long arg
)
608 pr_info("%s: %s unknown command %x %lx\n",
609 hw
->name
, __func__
, cmd
, arg
);
617 init_irq(struct inf_hw
*hw
)
622 if (!hw
->ci
->irqfunc
)
624 ret
= request_irq(hw
->irq
, hw
->ci
->irqfunc
, IRQF_SHARED
, hw
->name
, hw
);
626 pr_info("%s: couldn't get interrupt %d\n", hw
->name
, hw
->irq
);
630 spin_lock_irqsave(&hw
->lock
, flags
);
632 ret
= hw
->ipac
.init(&hw
->ipac
);
634 spin_unlock_irqrestore(&hw
->lock
, flags
);
635 pr_info("%s: ISAC init failed with %d\n",
639 spin_unlock_irqrestore(&hw
->lock
, flags
);
640 msleep_interruptible(10);
641 if (debug
& DEBUG_HW
)
642 pr_notice("%s: IRQ %d count %d\n", hw
->name
,
643 hw
->irq
, hw
->irqcnt
);
645 pr_info("%s: IRQ(%d) got no requests during init %d\n",
646 hw
->name
, hw
->irq
, 3 - cnt
);
650 free_irq(hw
->irq
, hw
);
655 release_io(struct inf_hw
*hw
)
659 release_mem_region(hw
->cfg
.start
, hw
->cfg
.size
);
662 release_region(hw
->cfg
.start
, hw
->cfg
.size
);
663 hw
->cfg
.mode
= AM_NONE
;
667 release_mem_region(hw
->addr
.start
, hw
->addr
.size
);
670 release_region(hw
->addr
.start
, hw
->addr
.size
);
671 hw
->addr
.mode
= AM_NONE
;
676 setup_io(struct inf_hw
*hw
)
680 if (hw
->ci
->cfg_mode
) {
681 hw
->cfg
.start
= pci_resource_start(hw
->pdev
, hw
->ci
->cfg_bar
);
682 hw
->cfg
.size
= pci_resource_len(hw
->pdev
, hw
->ci
->cfg_bar
);
683 if (hw
->ci
->cfg_mode
== AM_MEMIO
) {
684 if (!request_mem_region(hw
->cfg
.start
, hw
->cfg
.size
,
688 if (!request_region(hw
->cfg
.start
, hw
->cfg
.size
,
693 pr_info("mISDN: %s config port %lx (%lu bytes)"
694 "already in use\n", hw
->name
,
695 (ulong
)hw
->cfg
.start
, (ulong
)hw
->cfg
.size
);
698 if (hw
->ci
->cfg_mode
== AM_MEMIO
)
699 hw
->cfg
.p
= ioremap(hw
->cfg
.start
, hw
->cfg
.size
);
700 hw
->cfg
.mode
= hw
->ci
->cfg_mode
;
701 if (debug
& DEBUG_HW
)
702 pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
703 hw
->name
, (ulong
)hw
->cfg
.start
,
704 (ulong
)hw
->cfg
.size
, hw
->ci
->cfg_mode
);
707 if (hw
->ci
->addr_mode
) {
708 hw
->addr
.start
= pci_resource_start(hw
->pdev
, hw
->ci
->addr_bar
);
709 hw
->addr
.size
= pci_resource_len(hw
->pdev
, hw
->ci
->addr_bar
);
710 if (hw
->ci
->addr_mode
== AM_MEMIO
) {
711 if (!request_mem_region(hw
->addr
.start
, hw
->addr
.size
,
715 if (!request_region(hw
->addr
.start
, hw
->addr
.size
,
720 pr_info("mISDN: %s address port %lx (%lu bytes)"
721 "already in use\n", hw
->name
,
722 (ulong
)hw
->addr
.start
, (ulong
)hw
->addr
.size
);
725 if (hw
->ci
->addr_mode
== AM_MEMIO
)
726 hw
->addr
.p
= ioremap(hw
->addr
.start
, hw
->addr
.size
);
727 hw
->addr
.mode
= hw
->ci
->addr_mode
;
728 if (debug
& DEBUG_HW
)
729 pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
730 hw
->name
, (ulong
)hw
->addr
.start
,
731 (ulong
)hw
->addr
.size
, hw
->ci
->addr_mode
);
735 switch (hw
->ci
->typ
) {
738 hw
->ipac
.type
= IPAC_TYPE_ISAC
| IPAC_TYPE_HSCX
;
739 hw
->isac
.mode
= hw
->cfg
.mode
;
740 hw
->isac
.a
.io
.ale
= (u32
)hw
->cfg
.start
+ DIVA_ISAC_ALE
;
741 hw
->isac
.a
.io
.port
= (u32
)hw
->cfg
.start
+ DIVA_ISAC_PORT
;
742 hw
->hscx
.mode
= hw
->cfg
.mode
;
743 hw
->hscx
.a
.io
.ale
= (u32
)hw
->cfg
.start
+ DIVA_HSCX_ALE
;
744 hw
->hscx
.a
.io
.port
= (u32
)hw
->cfg
.start
+ DIVA_HSCX_PORT
;
747 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
748 hw
->ipac
.isac
.off
= 0x80;
749 hw
->isac
.mode
= hw
->addr
.mode
;
750 hw
->isac
.a
.p
= hw
->addr
.p
;
751 hw
->hscx
.mode
= hw
->addr
.mode
;
752 hw
->hscx
.a
.p
= hw
->addr
.p
;
755 hw
->ipac
.type
= IPAC_TYPE_IPACX
;
756 hw
->isac
.mode
= hw
->addr
.mode
;
757 hw
->isac
.a
.p
= hw
->addr
.p
;
758 hw
->hscx
.mode
= hw
->addr
.mode
;
759 hw
->hscx
.a
.p
= hw
->addr
.p
;
763 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
764 hw
->ipac
.isac
.off
= 0x80;
765 hw
->isac
.mode
= hw
->cfg
.mode
;
766 hw
->isac
.a
.io
.ale
= (u32
)hw
->cfg
.start
+ TIGER_IPAC_ALE
;
767 hw
->isac
.a
.io
.port
= (u32
)hw
->cfg
.start
+ TIGER_IPAC_PORT
;
768 hw
->hscx
.mode
= hw
->cfg
.mode
;
769 hw
->hscx
.a
.io
.ale
= (u32
)hw
->cfg
.start
+ TIGER_IPAC_ALE
;
770 hw
->hscx
.a
.io
.port
= (u32
)hw
->cfg
.start
+ TIGER_IPAC_PORT
;
771 outb(0xff, (ulong
)hw
->cfg
.start
);
773 outb(0x00, (ulong
)hw
->cfg
.start
);
775 outb(TIGER_IOMASK
, (ulong
)hw
->cfg
.start
+ TIGER_AUX_CTRL
);
779 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
780 hw
->ipac
.isac
.off
= 0x80;
781 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
;
782 hw
->isac
.a
.io
.port
= (u32
)hw
->addr
.start
+ 1;
783 hw
->isac
.mode
= hw
->addr
.mode
;
784 hw
->hscx
.a
.io
.ale
= (u32
)hw
->addr
.start
;
785 hw
->hscx
.a
.io
.port
= (u32
)hw
->addr
.start
+ 1;
786 hw
->hscx
.mode
= hw
->addr
.mode
;
789 hw
->ipac
.type
= IPAC_TYPE_ISAC
| IPAC_TYPE_HSCX
;
790 hw
->isac
.mode
= hw
->addr
.mode
;
791 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
+ NICCY_ISAC_ALE
;
792 hw
->isac
.a
.io
.port
= (u32
)hw
->addr
.start
+ NICCY_ISAC_PORT
;
793 hw
->hscx
.mode
= hw
->addr
.mode
;
794 hw
->hscx
.a
.io
.ale
= (u32
)hw
->addr
.start
+ NICCY_HSCX_ALE
;
795 hw
->hscx
.a
.io
.port
= (u32
)hw
->addr
.start
+ NICCY_HSCX_PORT
;
798 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
799 hw
->ipac
.isac
.off
= 0x80;
800 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
;
801 hw
->isac
.a
.io
.port
= hw
->isac
.a
.io
.ale
+ 4;
802 hw
->isac
.mode
= hw
->addr
.mode
;
803 hw
->hscx
.a
.io
.ale
= hw
->isac
.a
.io
.ale
;
804 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
805 hw
->hscx
.mode
= hw
->addr
.mode
;
808 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
809 hw
->ipac
.isac
.off
= 0x80;
810 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
+ 0x08;
811 hw
->isac
.a
.io
.port
= hw
->isac
.a
.io
.ale
+ 4;
812 hw
->isac
.mode
= hw
->addr
.mode
;
813 hw
->hscx
.a
.io
.ale
= hw
->isac
.a
.io
.ale
;
814 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
815 hw
->hscx
.mode
= hw
->addr
.mode
;
818 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
819 hw
->ipac
.isac
.off
= 0x80;
820 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
+ 0x10;
821 hw
->isac
.a
.io
.port
= hw
->isac
.a
.io
.ale
+ 4;
822 hw
->isac
.mode
= hw
->addr
.mode
;
823 hw
->hscx
.a
.io
.ale
= hw
->isac
.a
.io
.ale
;
824 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
825 hw
->hscx
.mode
= hw
->addr
.mode
;
828 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
829 hw
->ipac
.isac
.off
= 0x80;
830 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
+ 0x20;
831 hw
->isac
.a
.io
.port
= hw
->isac
.a
.io
.ale
+ 4;
832 hw
->isac
.mode
= hw
->addr
.mode
;
833 hw
->hscx
.a
.io
.ale
= hw
->isac
.a
.io
.ale
;
834 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
835 hw
->hscx
.mode
= hw
->addr
.mode
;
838 hw
->ipac
.type
= IPAC_TYPE_ISAC
| IPAC_TYPE_HSCX
;
839 hw
->ipac
.isac
.off
= 0x80;
840 hw
->isac
.mode
= hw
->addr
.mode
;
841 hw
->isac
.a
.io
.port
= (u32
)hw
->addr
.start
;
842 hw
->hscx
.mode
= hw
->addr
.mode
;
843 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
846 hw
->ipac
.type
= IPAC_TYPE_IPAC
;
847 hw
->ipac
.isac
.off
= 0x80;
848 hw
->isac
.mode
= hw
->addr
.mode
;
849 hw
->isac
.a
.io
.ale
= (u32
)hw
->addr
.start
;
850 hw
->isac
.a
.io
.port
= (u32
)hw
->addr
.start
+ GAZEL_IPAC_DATA_PORT
;
851 hw
->hscx
.mode
= hw
->addr
.mode
;
852 hw
->hscx
.a
.io
.ale
= hw
->isac
.a
.io
.ale
;
853 hw
->hscx
.a
.io
.port
= hw
->isac
.a
.io
.port
;
858 switch (hw
->isac
.mode
) {
860 ASSIGN_FUNC_IPAC(MIO
, hw
->ipac
);
863 ASSIGN_FUNC_IPAC(IND
, hw
->ipac
);
866 ASSIGN_FUNC_IPAC(IO
, hw
->ipac
);
875 release_card(struct inf_hw
*card
) {
879 spin_lock_irqsave(&card
->lock
, flags
);
881 spin_unlock_irqrestore(&card
->lock
, flags
);
882 card
->ipac
.isac
.release(&card
->ipac
.isac
);
883 free_irq(card
->irq
, card
);
884 mISDN_unregister_device(&card
->ipac
.isac
.dch
.dev
);
886 write_lock_irqsave(&card_lock
, flags
);
887 list_del(&card
->list
);
888 write_unlock_irqrestore(&card_lock
, flags
);
889 switch (card
->ci
->typ
) {
895 for (i
= 0; i
< 3; i
++) {
897 release_card(card
->sc
[i
]);
901 pci_disable_device(card
->pdev
);
902 pci_set_drvdata(card
->pdev
, NULL
);
910 setup_instance(struct inf_hw
*card
)
915 snprintf(card
->name
, MISDN_MAX_IDLEN
- 1, "%s.%d", card
->ci
->name
,
917 write_lock_irqsave(&card_lock
, flags
);
918 list_add_tail(&card
->list
, &Cards
);
919 write_unlock_irqrestore(&card_lock
, flags
);
922 card
->ipac
.isac
.name
= card
->name
;
923 card
->ipac
.name
= card
->name
;
924 card
->ipac
.owner
= THIS_MODULE
;
925 spin_lock_init(&card
->lock
);
926 card
->ipac
.isac
.hwlock
= &card
->lock
;
927 card
->ipac
.hwlock
= &card
->lock
;
928 card
->ipac
.ctrl
= (void *)&inf_ctrl
;
930 err
= setup_io(card
);
934 card
->ipac
.isac
.dch
.dev
.Bprotocols
=
935 mISDNipac_init(&card
->ipac
, card
);
937 if (card
->ipac
.isac
.dch
.dev
.Bprotocols
== 0)
940 err
= mISDN_register_device(&card
->ipac
.isac
.dch
.dev
,
941 &card
->pdev
->dev
, card
->name
);
945 err
= init_irq(card
);
948 pr_notice("Infineon %d cards installed\n", inf_cnt
);
951 mISDN_unregister_device(&card
->ipac
.isac
.dch
.dev
);
953 card
->ipac
.release(&card
->ipac
);
956 write_lock_irqsave(&card_lock
, flags
);
957 list_del(&card
->list
);
958 write_unlock_irqrestore(&card_lock
, flags
);
962 static const struct inf_cinfo inf_card_info
[] = {
967 AM_IND_IO
, AM_NONE
, 2, 0,
972 "Dialogic Diva 2.0U",
974 AM_IND_IO
, AM_NONE
, 2, 0,
979 "Dialogic Diva 2.01",
981 AM_MEMIO
, AM_MEMIO
, 0, 1,
986 "Dialogic Diva 2.02",
988 AM_MEMIO
, AM_MEMIO
, 0, 1,
993 "Sedlbauer SpeedWin PCI",
995 AM_IND_IO
, AM_NONE
, 0, 0,
1002 AM_IND_IO
, AM_NONE
, 0, 0,
1007 "Develo Microlink PCI",
1009 AM_IO
, AM_IND_IO
, 1, 3,
1014 "Develo QuickStep 3000",
1016 AM_IO
, AM_IND_IO
, 1, 3,
1023 AM_IO
, AM_IND_IO
, 0, 1,
1030 AM_IO
, AM_IND_IO
, 1, 5,
1037 AM_NONE
, AM_IND_IO
, 0, 4,
1044 AM_NONE
, AM_IND_IO
, 0, 3,
1051 AM_NONE
, AM_IND_IO
, 0, 2,
1065 AM_IO
, AM_IND_IO
, 1, 2,
1073 static const struct inf_cinfo
* __devinit
1074 get_card_info(enum inf_types typ
)
1076 const struct inf_cinfo
*ci
= inf_card_info
;
1078 while (ci
->typ
!= INF_NONE
) {
1086 static int __devinit
1087 inf_probe(struct pci_dev
*pdev
, const struct pci_device_id
*ent
)
1090 struct inf_hw
*card
;
1092 card
= kzalloc(sizeof(struct inf_hw
), GFP_KERNEL
);
1094 pr_info("No memory for Infineon ISDN card\n");
1098 err
= pci_enable_device(pdev
);
1103 card
->ci
= get_card_info(ent
->driver_data
);
1105 pr_info("mISDN: do not have informations about adapter at %s\n",
1110 pr_notice("mISDN: found adapter %s at %s\n",
1111 card
->ci
->full
, pci_name(pdev
));
1113 card
->irq
= pdev
->irq
;
1114 pci_set_drvdata(pdev
, card
);
1115 err
= setup_instance(card
);
1117 pci_disable_device(card
->pdev
);
1119 pci_set_drvdata(pdev
, NULL
);
1120 } else if (ent
->driver_data
== INF_SCT_1
) {
1124 for (i
= 1; i
< 4; i
++) {
1125 sc
= kzalloc(sizeof(struct inf_hw
), GFP_KERNEL
);
1130 sc
->irq
= card
->irq
;
1131 sc
->pdev
= card
->pdev
;
1132 sc
->ci
= card
->ci
+ i
;
1133 err
= setup_instance(sc
);
1139 card
->sc
[i
- 1] = sc
;
1145 static void __devexit
1146 inf_remove(struct pci_dev
*pdev
)
1148 struct inf_hw
*card
= pci_get_drvdata(pdev
);
1153 pr_debug("%s: drvdata allready removed\n", __func__
);
1156 static struct pci_driver infineon_driver
= {
1157 .name
= "ISDN Infineon pci",
1159 .remove
= __devexit_p(inf_remove
),
1160 .id_table
= infineon_ids
,
1168 pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV
);
1169 err
= pci_register_driver(&infineon_driver
);
1174 infineon_cleanup(void)
1176 pci_unregister_driver(&infineon_driver
);
1179 module_init(infineon_init
);
1180 module_exit(infineon_cleanup
);