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/interrupt.h>
42
#include <linux/module.h>
43
#include <linux/pci.h>
44
#include <linux/delay.h>
45
#include <linux/mISDNhw.h>
46
#include <linux/slab.h>
49
#define INFINEON_REV "1.0"
53
static u32 irqloops = 4;
85
enum addr_mode cfg_mode;
86
enum addr_mode addr_mode;
102
resource_size_t size;
103
resource_size_t start;
108
struct list_head list;
109
struct pci_dev *pdev;
110
const struct inf_cinfo *ci;
111
char name[MISDN_MAX_IDLEN];
114
struct _iohandle cfg;
115
struct _iohandle addr;
118
spinlock_t lock; /* HW access lock */
120
struct inf_hw *sc[3]; /* slave cards */
124
#define PCI_SUBVENDOR_HST_SAPHIR3 0x52
125
#define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
126
#define PCI_SUB_ID_SEDLBAUER 0x01
128
static struct pci_device_id infineon_ids[] __devinitdata = {
129
{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), INF_DIVA20 },
130
{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), INF_DIVA20U },
131
{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), INF_DIVA201 },
132
{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), INF_DIVA202 },
133
{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
134
PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
136
{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
137
PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3 },
138
{ PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK), INF_QS1000 },
139
{ PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000), INF_QS3000 },
140
{ PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY), INF_NICCY },
141
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
142
PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
144
{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685), INF_GAZEL_R685 },
145
{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753), INF_GAZEL_R753 },
146
{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO), INF_GAZEL_R753 },
147
{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC), INF_GAZEL_R753 },
150
MODULE_DEVICE_TABLE(pci, infineon_ids);
152
/* PCI interface specific defines */
154
#define DIVA_HSCX_PORT 0x00
155
#define DIVA_HSCX_ALE 0x04
156
#define DIVA_ISAC_PORT 0x08
157
#define DIVA_ISAC_ALE 0x0C
158
#define DIVA_PCI_CTRL 0x10
160
/* DIVA_PCI_CTRL bits */
161
#define DIVA_IRQ_BIT 0x01
162
#define DIVA_RESET_BIT 0x08
163
#define DIVA_EEPROM_CLK 0x40
164
#define DIVA_LED_A 0x10
165
#define DIVA_LED_B 0x20
166
#define DIVA_IRQ_CLR 0x80
170
#define PITA_ICR_REG 0x00
171
#define PITA_INT0_STATUS 0x02
173
#define PITA_MISC_REG 0x1c
174
#define PITA_PARA_SOFTRESET 0x01000000
175
#define PITA_SER_SOFTRESET 0x02000000
176
#define PITA_PARA_MPX_MODE 0x04000000
177
#define PITA_INT0_ENABLE 0x00020000
179
/* TIGER 100 Registers */
180
#define TIGER_RESET_ADDR 0x00
181
#define TIGER_EXTERN_RESET 0x01
182
#define TIGER_AUX_CTRL 0x02
183
#define TIGER_AUX_DATA 0x03
184
#define TIGER_AUX_IRQMASK 0x05
185
#define TIGER_AUX_STATUS 0x07
188
#define TIGER_IOMASK 0xdd /* 1 and 5 are inputs */
189
#define TIGER_IRQ_BIT 0x02
191
#define TIGER_IPAC_ALE 0xC0
192
#define TIGER_IPAC_PORT 0xC8
194
/* ELSA (now Develo) PCI cards */
195
#define ELSA_IRQ_ADDR 0x4c
196
#define ELSA_IRQ_MASK 0x04
197
#define QS1000_IRQ_OFF 0x01
198
#define QS3000_IRQ_OFF 0x03
199
#define QS1000_IRQ_ON 0x41
200
#define QS3000_IRQ_ON 0x43
202
/* Dr Neuhaus/Sagem Niccy */
203
#define NICCY_ISAC_PORT 0x00
204
#define NICCY_HSCX_PORT 0x01
205
#define NICCY_ISAC_ALE 0x02
206
#define NICCY_HSCX_ALE 0x03
208
#define NICCY_IRQ_CTRL_REG 0x38
209
#define NICCY_IRQ_ENABLE 0x001f00
210
#define NICCY_IRQ_DISABLE 0xff0000
211
#define NICCY_IRQ_BIT 0x800000
215
#define SCT_PLX_IRQ_ADDR 0x4c
216
#define SCT_PLX_RESET_ADDR 0x50
217
#define SCT_PLX_IRQ_ENABLE 0x41
218
#define SCT_PLX_RESET_BIT 0x04
221
#define GAZEL_IPAC_DATA_PORT 0x04
223
#define GAZEL_CNTRL 0x50
224
#define GAZEL_RESET 0x04
225
#define GAZEL_RESET_9050 0x40000000
226
#define GAZEL_INCSR 0x4C
227
#define GAZEL_ISAC_EN 0x08
228
#define GAZEL_INT_ISAC 0x20
229
#define GAZEL_HSCX_EN 0x01
230
#define GAZEL_INT_HSCX 0x04
231
#define GAZEL_PCI_EN 0x40
232
#define GAZEL_IPAC_EN 0x03
235
static LIST_HEAD(Cards);
236
static DEFINE_RWLOCK(card_lock); /* protect Cards */
239
_set_debug(struct inf_hw *card)
241
card->ipac.isac.dch.debug = debug;
242
card->ipac.hscx[0].bch.debug = debug;
243
card->ipac.hscx[1].bch.debug = debug;
247
set_debug(const char *val, struct kernel_param *kp)
252
ret = param_set_uint(val, kp);
254
read_lock(&card_lock);
255
list_for_each_entry(card, &Cards, list)
257
read_unlock(&card_lock);
262
MODULE_AUTHOR("Karsten Keil");
263
MODULE_LICENSE("GPL v2");
264
MODULE_VERSION(INFINEON_REV);
265
module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
266
MODULE_PARM_DESC(debug, "infineon debug mask");
267
module_param(irqloops, uint, S_IRUGO | S_IWUSR);
268
MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)");
270
/* Interface functions */
272
IOFUNC_IO(ISAC, inf_hw, isac.a.io)
273
IOFUNC_IO(IPAC, inf_hw, hscx.a.io)
274
IOFUNC_IND(ISAC, inf_hw, isac.a.io)
275
IOFUNC_IND(IPAC, inf_hw, hscx.a.io)
276
IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p)
277
IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p)
280
diva_irq(int intno, void *dev_id)
282
struct inf_hw *hw = dev_id;
285
spin_lock(&hw->lock);
286
val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL);
287
if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */
288
spin_unlock(&hw->lock);
289
return IRQ_NONE; /* shared */
292
mISDNipac_irq(&hw->ipac, irqloops);
293
spin_unlock(&hw->lock);
298
diva20x_irq(int intno, void *dev_id)
300
struct inf_hw *hw = dev_id;
303
spin_lock(&hw->lock);
304
val = readb(hw->cfg.p);
305
if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */
306
spin_unlock(&hw->lock);
307
return IRQ_NONE; /* shared */
310
mISDNipac_irq(&hw->ipac, irqloops);
311
writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */
312
spin_unlock(&hw->lock);
317
tiger_irq(int intno, void *dev_id)
319
struct inf_hw *hw = dev_id;
322
spin_lock(&hw->lock);
323
val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS);
324
if (val & TIGER_IRQ_BIT) { /* for us or shared ? */
325
spin_unlock(&hw->lock);
326
return IRQ_NONE; /* shared */
329
mISDNipac_irq(&hw->ipac, irqloops);
330
spin_unlock(&hw->lock);
335
elsa_irq(int intno, void *dev_id)
337
struct inf_hw *hw = dev_id;
340
spin_lock(&hw->lock);
341
val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR);
342
if (!(val & ELSA_IRQ_MASK)) {
343
spin_unlock(&hw->lock);
344
return IRQ_NONE; /* shared */
347
mISDNipac_irq(&hw->ipac, irqloops);
348
spin_unlock(&hw->lock);
353
niccy_irq(int intno, void *dev_id)
355
struct inf_hw *hw = dev_id;
358
spin_lock(&hw->lock);
359
val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
360
if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */
361
spin_unlock(&hw->lock);
362
return IRQ_NONE; /* shared */
364
outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
366
mISDNipac_irq(&hw->ipac, irqloops);
367
spin_unlock(&hw->lock);
372
gazel_irq(int intno, void *dev_id)
374
struct inf_hw *hw = dev_id;
377
spin_lock(&hw->lock);
378
ret = mISDNipac_irq(&hw->ipac, irqloops);
379
spin_unlock(&hw->lock);
384
ipac_irq(int intno, void *dev_id)
386
struct inf_hw *hw = dev_id;
389
spin_lock(&hw->lock);
390
val = hw->ipac.read_reg(hw, IPAC_ISTA);
392
spin_unlock(&hw->lock);
393
return IRQ_NONE; /* shared */
396
mISDNipac_irq(&hw->ipac, irqloops);
397
spin_unlock(&hw->lock);
402
enable_hwirq(struct inf_hw *hw)
407
switch (hw->ci->typ) {
410
writel(PITA_INT0_ENABLE, hw->cfg.p);
414
outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
417
outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
420
outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
423
val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
424
val |= NICCY_IRQ_ENABLE;
425
outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
428
w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
429
w |= SCT_PLX_IRQ_ENABLE;
430
outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
433
outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
434
(u32)hw->cfg.start + GAZEL_INCSR);
437
outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
438
(u32)hw->cfg.start + GAZEL_INCSR);
446
disable_hwirq(struct inf_hw *hw)
451
switch (hw->ci->typ) {
454
writel(0, hw->cfg.p);
458
outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
461
outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
464
outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
467
val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
468
val &= NICCY_IRQ_DISABLE;
469
outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
472
w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
473
w &= (~SCT_PLX_IRQ_ENABLE);
474
outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
478
outb(0, (u32)hw->cfg.start + GAZEL_INCSR);
486
ipac_chip_reset(struct inf_hw *hw)
488
hw->ipac.write_reg(hw, IPAC_POTA2, 0x20);
490
hw->ipac.write_reg(hw, IPAC_POTA2, 0x00);
492
hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf);
493
hw->ipac.write_reg(hw, IPAC_MASK, 0xc0);
497
reset_inf(struct inf_hw *hw)
502
if (debug & DEBUG_HW)
503
pr_notice("%s: resetting card\n", hw->name);
504
switch (hw->ci->typ) {
507
outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL);
509
outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL);
511
/* Workaround PCI9060 */
512
outb(9, (u32)hw->cfg.start + 0x69);
513
outb(DIVA_RESET_BIT | DIVA_LED_A,
514
(u32)hw->cfg.start + DIVA_PCI_CTRL);
517
writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
518
hw->cfg.p + PITA_MISC_REG);
520
writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
524
writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
525
hw->cfg.p + PITA_MISC_REG);
527
writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
528
hw->cfg.p + PITA_MISC_REG);
534
hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
535
hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
536
hw->ipac.write_reg(hw, IPAC_PCFG, 0x12);
541
hw->ipac.write_reg(hw, IPAC_ACFG, 0x00);
542
hw->ipac.write_reg(hw, IPAC_AOE, 0x3c);
543
hw->ipac.write_reg(hw, IPAC_ATX, 0xff);
548
w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
549
w &= (~SCT_PLX_RESET_BIT);
550
outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
552
w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
553
w |= SCT_PLX_RESET_BIT;
554
outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
558
val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
559
val |= (GAZEL_RESET_9050 + GAZEL_RESET);
560
outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
561
val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
563
outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
565
hw->ipac.isac.adf2 = 0x87;
566
hw->ipac.hscx[0].slot = 0x1f;
567
hw->ipac.hscx[1].slot = 0x23;
570
val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
571
val |= (GAZEL_RESET_9050 + GAZEL_RESET);
572
outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
573
val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
575
outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
578
hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
579
hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
580
hw->ipac.conf = 0x01; /* IOM off */
589
inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
598
pr_info("%s: %s unknown command %x %lx\n",
599
hw->name, __func__, cmd, arg);
607
init_irq(struct inf_hw *hw)
612
if (!hw->ci->irqfunc)
614
ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw);
616
pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq);
620
spin_lock_irqsave(&hw->lock, flags);
622
ret = hw->ipac.init(&hw->ipac);
624
spin_unlock_irqrestore(&hw->lock, flags);
625
pr_info("%s: ISAC init failed with %d\n",
629
spin_unlock_irqrestore(&hw->lock, flags);
630
msleep_interruptible(10);
631
if (debug & DEBUG_HW)
632
pr_notice("%s: IRQ %d count %d\n", hw->name,
633
hw->irq, hw->irqcnt);
635
pr_info("%s: IRQ(%d) got no requests during init %d\n",
636
hw->name, hw->irq, 3 - cnt);
640
free_irq(hw->irq, hw);
645
release_io(struct inf_hw *hw)
649
release_mem_region(hw->cfg.start, hw->cfg.size);
652
release_region(hw->cfg.start, hw->cfg.size);
653
hw->cfg.mode = AM_NONE;
657
release_mem_region(hw->addr.start, hw->addr.size);
660
release_region(hw->addr.start, hw->addr.size);
661
hw->addr.mode = AM_NONE;
666
setup_io(struct inf_hw *hw)
670
if (hw->ci->cfg_mode) {
671
hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
672
hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
673
if (hw->ci->cfg_mode == AM_MEMIO) {
674
if (!request_mem_region(hw->cfg.start, hw->cfg.size,
678
if (!request_region(hw->cfg.start, hw->cfg.size,
683
pr_info("mISDN: %s config port %lx (%lu bytes)"
684
"already in use\n", hw->name,
685
(ulong)hw->cfg.start, (ulong)hw->cfg.size);
688
if (hw->ci->cfg_mode == AM_MEMIO)
689
hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
690
hw->cfg.mode = hw->ci->cfg_mode;
691
if (debug & DEBUG_HW)
692
pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
693
hw->name, (ulong)hw->cfg.start,
694
(ulong)hw->cfg.size, hw->ci->cfg_mode);
697
if (hw->ci->addr_mode) {
698
hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
699
hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
700
if (hw->ci->addr_mode == AM_MEMIO) {
701
if (!request_mem_region(hw->addr.start, hw->addr.size,
705
if (!request_region(hw->addr.start, hw->addr.size,
710
pr_info("mISDN: %s address port %lx (%lu bytes)"
711
"already in use\n", hw->name,
712
(ulong)hw->addr.start, (ulong)hw->addr.size);
715
if (hw->ci->addr_mode == AM_MEMIO)
716
hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
717
hw->addr.mode = hw->ci->addr_mode;
718
if (debug & DEBUG_HW)
719
pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
720
hw->name, (ulong)hw->addr.start,
721
(ulong)hw->addr.size, hw->ci->addr_mode);
725
switch (hw->ci->typ) {
728
hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
729
hw->isac.mode = hw->cfg.mode;
730
hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
731
hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
732
hw->hscx.mode = hw->cfg.mode;
733
hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
734
hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
737
hw->ipac.type = IPAC_TYPE_IPAC;
738
hw->ipac.isac.off = 0x80;
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;
745
hw->ipac.type = IPAC_TYPE_IPACX;
746
hw->isac.mode = hw->addr.mode;
747
hw->isac.a.p = hw->addr.p;
748
hw->hscx.mode = hw->addr.mode;
749
hw->hscx.a.p = hw->addr.p;
753
hw->ipac.type = IPAC_TYPE_IPAC;
754
hw->ipac.isac.off = 0x80;
755
hw->isac.mode = hw->cfg.mode;
756
hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
757
hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
758
hw->hscx.mode = hw->cfg.mode;
759
hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
760
hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
761
outb(0xff, (ulong)hw->cfg.start);
763
outb(0x00, (ulong)hw->cfg.start);
765
outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
769
hw->ipac.type = IPAC_TYPE_IPAC;
770
hw->ipac.isac.off = 0x80;
771
hw->isac.a.io.ale = (u32)hw->addr.start;
772
hw->isac.a.io.port = (u32)hw->addr.start + 1;
773
hw->isac.mode = hw->addr.mode;
774
hw->hscx.a.io.ale = (u32)hw->addr.start;
775
hw->hscx.a.io.port = (u32)hw->addr.start + 1;
776
hw->hscx.mode = hw->addr.mode;
779
hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
780
hw->isac.mode = hw->addr.mode;
781
hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
782
hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
783
hw->hscx.mode = hw->addr.mode;
784
hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
785
hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
788
hw->ipac.type = IPAC_TYPE_IPAC;
789
hw->ipac.isac.off = 0x80;
790
hw->isac.a.io.ale = (u32)hw->addr.start;
791
hw->isac.a.io.port = hw->isac.a.io.ale + 4;
792
hw->isac.mode = hw->addr.mode;
793
hw->hscx.a.io.ale = hw->isac.a.io.ale;
794
hw->hscx.a.io.port = hw->isac.a.io.port;
795
hw->hscx.mode = hw->addr.mode;
798
hw->ipac.type = IPAC_TYPE_IPAC;
799
hw->ipac.isac.off = 0x80;
800
hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
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 + 0x10;
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 + 0x20;
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_ISAC | IPAC_TYPE_HSCX;
829
hw->ipac.isac.off = 0x80;
830
hw->isac.mode = hw->addr.mode;
831
hw->isac.a.io.port = (u32)hw->addr.start;
832
hw->hscx.mode = hw->addr.mode;
833
hw->hscx.a.io.port = hw->isac.a.io.port;
836
hw->ipac.type = IPAC_TYPE_IPAC;
837
hw->ipac.isac.off = 0x80;
838
hw->isac.mode = hw->addr.mode;
839
hw->isac.a.io.ale = (u32)hw->addr.start;
840
hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
841
hw->hscx.mode = hw->addr.mode;
842
hw->hscx.a.io.ale = hw->isac.a.io.ale;
843
hw->hscx.a.io.port = hw->isac.a.io.port;
848
switch (hw->isac.mode) {
850
ASSIGN_FUNC_IPAC(MIO, hw->ipac);
853
ASSIGN_FUNC_IPAC(IND, hw->ipac);
856
ASSIGN_FUNC_IPAC(IO, hw->ipac);
865
release_card(struct inf_hw *card) {
869
spin_lock_irqsave(&card->lock, flags);
871
spin_unlock_irqrestore(&card->lock, flags);
872
card->ipac.isac.release(&card->ipac.isac);
873
free_irq(card->irq, card);
874
mISDN_unregister_device(&card->ipac.isac.dch.dev);
876
write_lock_irqsave(&card_lock, flags);
877
list_del(&card->list);
878
write_unlock_irqrestore(&card_lock, flags);
879
switch (card->ci->typ) {
885
for (i = 0; i < 3; i++) {
887
release_card(card->sc[i]);
891
pci_disable_device(card->pdev);
892
pci_set_drvdata(card->pdev, NULL);
900
setup_instance(struct inf_hw *card)
905
snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
907
write_lock_irqsave(&card_lock, flags);
908
list_add_tail(&card->list, &Cards);
909
write_unlock_irqrestore(&card_lock, flags);
912
card->ipac.isac.name = card->name;
913
card->ipac.name = card->name;
914
card->ipac.owner = THIS_MODULE;
915
spin_lock_init(&card->lock);
916
card->ipac.isac.hwlock = &card->lock;
917
card->ipac.hwlock = &card->lock;
918
card->ipac.ctrl = (void *)&inf_ctrl;
920
err = setup_io(card);
924
card->ipac.isac.dch.dev.Bprotocols =
925
mISDNipac_init(&card->ipac, card);
927
if (card->ipac.isac.dch.dev.Bprotocols == 0)
930
err = mISDN_register_device(&card->ipac.isac.dch.dev,
931
&card->pdev->dev, card->name);
935
err = init_irq(card);
938
pr_notice("Infineon %d cards installed\n", inf_cnt);
941
mISDN_unregister_device(&card->ipac.isac.dch.dev);
943
card->ipac.release(&card->ipac);
946
write_lock_irqsave(&card_lock, flags);
947
list_del(&card->list);
948
write_unlock_irqrestore(&card_lock, flags);
952
static const struct inf_cinfo inf_card_info[] = {
957
AM_IND_IO, AM_NONE, 2, 0,
962
"Dialogic Diva 2.0U",
964
AM_IND_IO, AM_NONE, 2, 0,
969
"Dialogic Diva 2.01",
971
AM_MEMIO, AM_MEMIO, 0, 1,
976
"Dialogic Diva 2.02",
978
AM_MEMIO, AM_MEMIO, 0, 1,
983
"Sedlbauer SpeedWin PCI",
985
AM_IND_IO, AM_NONE, 0, 0,
992
AM_IND_IO, AM_NONE, 0, 0,
997
"Develo Microlink PCI",
999
AM_IO, AM_IND_IO, 1, 3,
1004
"Develo QuickStep 3000",
1006
AM_IO, AM_IND_IO, 1, 3,
1013
AM_IO, AM_IND_IO, 0, 1,
1020
AM_IO, AM_IND_IO, 1, 5,
1027
AM_NONE, AM_IND_IO, 0, 4,
1034
AM_NONE, AM_IND_IO, 0, 3,
1041
AM_NONE, AM_IND_IO, 0, 2,
1055
AM_IO, AM_IND_IO, 1, 2,
1063
static const struct inf_cinfo * __devinit
1064
get_card_info(enum inf_types typ)
1066
const struct inf_cinfo *ci = inf_card_info;
1068
while (ci->typ != INF_NONE) {
1076
static int __devinit
1077
inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1080
struct inf_hw *card;
1082
card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1084
pr_info("No memory for Infineon ISDN card\n");
1088
err = pci_enable_device(pdev);
1093
card->ci = get_card_info(ent->driver_data);
1095
pr_info("mISDN: do not have informations about adapter at %s\n",
1098
pci_disable_device(pdev);
1101
pr_notice("mISDN: found adapter %s at %s\n",
1102
card->ci->full, pci_name(pdev));
1104
card->irq = pdev->irq;
1105
pci_set_drvdata(pdev, card);
1106
err = setup_instance(card);
1108
pci_disable_device(pdev);
1110
pci_set_drvdata(pdev, NULL);
1111
} else if (ent->driver_data == INF_SCT_1) {
1115
for (i = 1; i < 4; i++) {
1116
sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1119
pci_disable_device(pdev);
1122
sc->irq = card->irq;
1123
sc->pdev = card->pdev;
1124
sc->ci = card->ci + i;
1125
err = setup_instance(sc);
1127
pci_disable_device(pdev);
1132
card->sc[i - 1] = sc;
1138
static void __devexit
1139
inf_remove(struct pci_dev *pdev)
1141
struct inf_hw *card = pci_get_drvdata(pdev);
1146
pr_debug("%s: drvdata already removed\n", __func__);
1149
static struct pci_driver infineon_driver = {
1150
.name = "ISDN Infineon pci",
1152
.remove = __devexit_p(inf_remove),
1153
.id_table = infineon_ids,
1161
pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
1162
err = pci_register_driver(&infineon_driver);
1167
infineon_cleanup(void)
1169
pci_unregister_driver(&infineon_driver);
1172
module_init(infineon_init);
1173
module_exit(infineon_cleanup);