xref: /linux/drivers/isdn/hardware/mISDN/mISDNinfineon.c (revision 2ade0c1d9d93b7642212657ef76f4a1e30233711)
1 /*
2  * mISDNinfineon.c
3  *		Support for cards based on following Infineon ISDN chipsets
4  *		- ISAC + HSCX
5  *		- IPAC and IPAC-X
6  *		- ISAC-SX + HSCX
7  *
8  * Supported cards:
9  *		- Dialogic Diva 2.0
10  *		- Dialogic Diva 2.0U
11  *		- Dialogic Diva 2.01
12  *		- Dialogic Diva 2.02
13  *		- Sedlbauer Speedwin
14  *		- HST Saphir3
15  *		- Develo (former ELSA) Microlink PCI (Quickstep 1000)
16  *		- Develo (former ELSA) Quickstep 3000
17  *		- Berkom Scitel BRIX Quadro
18  *		- Dr.Neuhaus (Sagem) Niccy
19  *
20  *
21  *
22  * Author       Karsten Keil <keil@isdn4linux.de>
23  *
24  * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
25  *
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.
29  *
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.
34  *
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.
38  *
39  */
40 
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>
46 #include "ipac.h"
47 
48 #define INFINEON_REV	"1.0"
49 
50 static int inf_cnt;
51 static u32 debug;
52 static u32 irqloops = 4;
53 
54 enum inf_types {
55 	INF_NONE,
56 	INF_DIVA20,
57 	INF_DIVA20U,
58 	INF_DIVA201,
59 	INF_DIVA202,
60 	INF_SPEEDWIN,
61 	INF_SAPHIR3,
62 	INF_QS1000,
63 	INF_QS3000,
64 	INF_NICCY,
65 	INF_SCT_1,
66 	INF_SCT_2,
67 	INF_SCT_3,
68 	INF_SCT_4,
69 	INF_GAZEL_R685,
70 	INF_GAZEL_R753
71 };
72 
73 enum addr_mode {
74 	AM_NONE = 0,
75 	AM_IO,
76 	AM_MEMIO,
77 	AM_IND_IO,
78 };
79 
80 struct inf_cinfo {
81 	enum inf_types	typ;
82 	const char	*full;
83 	const char	*name;
84 	enum addr_mode	cfg_mode;
85 	enum addr_mode	addr_mode;
86 	u8		cfg_bar;
87 	u8		addr_bar;
88 	void		*irqfunc;
89 };
90 
91 struct _ioaddr {
92 	enum addr_mode	mode;
93 	union {
94 		void __iomem	*p;
95 		struct _ioport	io;
96 	} a;
97 };
98 
99 struct _iohandle {
100 	enum addr_mode	mode;
101 	resource_size_t	size;
102 	resource_size_t	start;
103 	void __iomem	*p;
104 };
105 
106 struct inf_hw {
107 	struct list_head	list;
108 	struct pci_dev		*pdev;
109 	const struct inf_cinfo	*ci;
110 	char			name[MISDN_MAX_IDLEN];
111 	u32			irq;
112 	u32			irqcnt;
113 	struct _iohandle	cfg;
114 	struct _iohandle	addr;
115 	struct _ioaddr		isac;
116 	struct _ioaddr		hscx;
117 	spinlock_t		lock;	/* HW access lock */
118 	struct ipac_hw		ipac;
119 	struct inf_hw		*sc[3];	/* slave cards */
120 };
121 
122 
123 #define PCI_SUBVENDOR_HST_SAPHIR3       0x52
124 #define PCI_SUBVENDOR_SEDLBAUER_PCI     0x53
125 #define PCI_SUB_ID_SEDLBAUER            0x01
126 
127 static struct pci_device_id infineon_ids[] __devinitdata = {
128 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), INF_DIVA20 },
129 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), INF_DIVA20U },
130 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), INF_DIVA201 },
131 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), INF_DIVA202 },
132 	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
133 	  PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
134 	  INF_SPEEDWIN },
135 	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
136 	  PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3 },
137 	{ PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK), INF_QS1000 },
138 	{ PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000), INF_QS3000 },
139 	{ PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY), INF_NICCY },
140 	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
141 	  PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
142 	  INF_SCT_1 },
143 	{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685), INF_GAZEL_R685 },
144 	{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753), INF_GAZEL_R753 },
145 	{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO), INF_GAZEL_R753 },
146 	{ PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC), INF_GAZEL_R753 },
147 	{ }
148 };
149 MODULE_DEVICE_TABLE(pci, infineon_ids);
150 
151 /* PCI interface specific defines */
152 /* Diva 2.0/2.0U */
153 #define DIVA_HSCX_PORT		0x00
154 #define DIVA_HSCX_ALE		0x04
155 #define DIVA_ISAC_PORT		0x08
156 #define DIVA_ISAC_ALE		0x0C
157 #define DIVA_PCI_CTRL           0x10
158 
159 /* DIVA_PCI_CTRL bits */
160 #define DIVA_IRQ_BIT		0x01
161 #define DIVA_RESET_BIT		0x08
162 #define DIVA_EEPROM_CLK		0x40
163 #define DIVA_LED_A		0x10
164 #define DIVA_LED_B		0x20
165 #define DIVA_IRQ_CLR		0x80
166 
167 /* Diva 2.01/2.02 */
168 /* Siemens PITA */
169 #define PITA_ICR_REG		0x00
170 #define PITA_INT0_STATUS	0x02
171 
172 #define PITA_MISC_REG		0x1c
173 #define PITA_PARA_SOFTRESET	0x01000000
174 #define PITA_SER_SOFTRESET	0x02000000
175 #define PITA_PARA_MPX_MODE	0x04000000
176 #define PITA_INT0_ENABLE	0x00020000
177 
178 /* TIGER 100 Registers */
179 #define TIGER_RESET_ADDR	0x00
180 #define TIGER_EXTERN_RESET	0x01
181 #define TIGER_AUX_CTRL		0x02
182 #define TIGER_AUX_DATA		0x03
183 #define TIGER_AUX_IRQMASK	0x05
184 #define TIGER_AUX_STATUS	0x07
185 
186 /* Tiger AUX BITs */
187 #define TIGER_IOMASK		0xdd	/* 1 and 5 are inputs */
188 #define TIGER_IRQ_BIT		0x02
189 
190 #define TIGER_IPAC_ALE		0xC0
191 #define TIGER_IPAC_PORT		0xC8
192 
193 /* ELSA (now Develo) PCI cards */
194 #define ELSA_IRQ_ADDR		0x4c
195 #define ELSA_IRQ_MASK		0x04
196 #define QS1000_IRQ_OFF		0x01
197 #define QS3000_IRQ_OFF		0x03
198 #define QS1000_IRQ_ON		0x41
199 #define QS3000_IRQ_ON		0x43
200 
201 /* Dr Neuhaus/Sagem Niccy */
202 #define NICCY_ISAC_PORT		0x00
203 #define NICCY_HSCX_PORT		0x01
204 #define NICCY_ISAC_ALE		0x02
205 #define NICCY_HSCX_ALE		0x03
206 
207 #define NICCY_IRQ_CTRL_REG	0x38
208 #define NICCY_IRQ_ENABLE	0x001f00
209 #define NICCY_IRQ_DISABLE	0xff0000
210 #define NICCY_IRQ_BIT		0x800000
211 
212 
213 /* Scitel PLX */
214 #define SCT_PLX_IRQ_ADDR	0x4c
215 #define SCT_PLX_RESET_ADDR	0x50
216 #define SCT_PLX_IRQ_ENABLE	0x41
217 #define SCT_PLX_RESET_BIT	0x04
218 
219 /* Gazel */
220 #define	GAZEL_IPAC_DATA_PORT	0x04
221 /* Gazel PLX */
222 #define GAZEL_CNTRL		0x50
223 #define GAZEL_RESET		0x04
224 #define GAZEL_RESET_9050	0x40000000
225 #define GAZEL_INCSR		0x4C
226 #define GAZEL_ISAC_EN		0x08
227 #define GAZEL_INT_ISAC		0x20
228 #define GAZEL_HSCX_EN		0x01
229 #define GAZEL_INT_HSCX		0x04
230 #define GAZEL_PCI_EN		0x40
231 #define GAZEL_IPAC_EN		0x03
232 
233 
234 static LIST_HEAD(Cards);
235 static DEFINE_RWLOCK(card_lock); /* protect Cards */
236 
237 static void
238 _set_debug(struct inf_hw *card)
239 {
240 	card->ipac.isac.dch.debug = debug;
241 	card->ipac.hscx[0].bch.debug = debug;
242 	card->ipac.hscx[1].bch.debug = debug;
243 }
244 
245 static int
246 set_debug(const char *val, struct kernel_param *kp)
247 {
248 	int ret;
249 	struct inf_hw *card;
250 
251 	ret = param_set_uint(val, kp);
252 	if (!ret) {
253 		read_lock(&card_lock);
254 		list_for_each_entry(card, &Cards, list)
255 			_set_debug(card);
256 		read_unlock(&card_lock);
257 	}
258 	return ret;
259 }
260 
261 MODULE_AUTHOR("Karsten Keil");
262 MODULE_LICENSE("GPL v2");
263 MODULE_VERSION(INFINEON_REV);
264 module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
265 MODULE_PARM_DESC(debug, "infineon debug mask");
266 module_param(irqloops, uint, S_IRUGO | S_IWUSR);
267 MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)");
268 
269 /* Interface functions */
270 
271 IOFUNC_IO(ISAC, inf_hw, isac.a.io)
272 IOFUNC_IO(IPAC, inf_hw, hscx.a.io)
273 IOFUNC_IND(ISAC, inf_hw, isac.a.io)
274 IOFUNC_IND(IPAC, inf_hw, hscx.a.io)
275 IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p)
276 IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p)
277 
278 static irqreturn_t
279 diva_irq(int intno, void *dev_id)
280 {
281 	struct inf_hw *hw = dev_id;
282 	u8 val;
283 
284 	spin_lock(&hw->lock);
285 	val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL);
286 	if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */
287 		spin_unlock(&hw->lock);
288 		return IRQ_NONE; /* shared */
289 	}
290 	hw->irqcnt++;
291 	mISDNipac_irq(&hw->ipac, irqloops);
292 	spin_unlock(&hw->lock);
293 	return IRQ_HANDLED;
294 }
295 
296 static irqreturn_t
297 diva20x_irq(int intno, void *dev_id)
298 {
299 	struct inf_hw *hw = dev_id;
300 	u8 val;
301 
302 	spin_lock(&hw->lock);
303 	val = readb(hw->cfg.p);
304 	if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */
305 		spin_unlock(&hw->lock);
306 		return IRQ_NONE; /* shared */
307 	}
308 	hw->irqcnt++;
309 	mISDNipac_irq(&hw->ipac, irqloops);
310 	writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */
311 	spin_unlock(&hw->lock);
312 	return IRQ_HANDLED;
313 }
314 
315 static irqreturn_t
316 tiger_irq(int intno, void *dev_id)
317 {
318 	struct inf_hw *hw = dev_id;
319 	u8 val;
320 
321 	spin_lock(&hw->lock);
322 	val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS);
323 	if (val & TIGER_IRQ_BIT) { /* for us or shared ? */
324 		spin_unlock(&hw->lock);
325 		return IRQ_NONE; /* shared */
326 	}
327 	hw->irqcnt++;
328 	mISDNipac_irq(&hw->ipac, irqloops);
329 	spin_unlock(&hw->lock);
330 	return IRQ_HANDLED;
331 }
332 
333 static irqreturn_t
334 elsa_irq(int intno, void *dev_id)
335 {
336 	struct inf_hw *hw = dev_id;
337 	u8 val;
338 
339 	spin_lock(&hw->lock);
340 	val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR);
341 	if (!(val & ELSA_IRQ_MASK)) {
342 		spin_unlock(&hw->lock);
343 		return IRQ_NONE; /* shared */
344 	}
345 	hw->irqcnt++;
346 	mISDNipac_irq(&hw->ipac, irqloops);
347 	spin_unlock(&hw->lock);
348 	return IRQ_HANDLED;
349 }
350 
351 static irqreturn_t
352 niccy_irq(int intno, void *dev_id)
353 {
354 	struct inf_hw *hw = dev_id;
355 	u32 val;
356 
357 	spin_lock(&hw->lock);
358 	val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
359 	if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */
360 		spin_unlock(&hw->lock);
361 		return IRQ_NONE; /* shared */
362 	}
363 	outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
364 	hw->irqcnt++;
365 	mISDNipac_irq(&hw->ipac, irqloops);
366 	spin_unlock(&hw->lock);
367 	return IRQ_HANDLED;
368 }
369 
370 static irqreturn_t
371 gazel_irq(int intno, void *dev_id)
372 {
373 	struct inf_hw *hw = dev_id;
374 	irqreturn_t ret;
375 
376 	spin_lock(&hw->lock);
377 	ret = mISDNipac_irq(&hw->ipac, irqloops);
378 	spin_unlock(&hw->lock);
379 	return ret;
380 }
381 
382 static irqreturn_t
383 ipac_irq(int intno, void *dev_id)
384 {
385 	struct inf_hw *hw = dev_id;
386 	u8 val;
387 
388 	spin_lock(&hw->lock);
389 	val = hw->ipac.read_reg(hw, IPAC_ISTA);
390 	if (!(val & 0x3f)) {
391 		spin_unlock(&hw->lock);
392 		return IRQ_NONE; /* shared */
393 	}
394 	hw->irqcnt++;
395 	mISDNipac_irq(&hw->ipac, irqloops);
396 	spin_unlock(&hw->lock);
397 	return IRQ_HANDLED;
398 }
399 
400 static void
401 enable_hwirq(struct inf_hw *hw)
402 {
403 	u16 w;
404 	u32 val;
405 
406 	switch (hw->ci->typ) {
407 	case INF_DIVA201:
408 	case INF_DIVA202:
409 		writel(PITA_INT0_ENABLE, hw->cfg.p);
410 		break;
411 	case INF_SPEEDWIN:
412 	case INF_SAPHIR3:
413 		outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
414 		break;
415 	case INF_QS1000:
416 		outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
417 		break;
418 	case INF_QS3000:
419 		outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
420 		break;
421 	case INF_NICCY:
422 		val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
423 		val |= NICCY_IRQ_ENABLE;;
424 		outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
425 		break;
426 	case INF_SCT_1:
427 		w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
428 		w |= SCT_PLX_IRQ_ENABLE;
429 		outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
430 		break;
431 	case INF_GAZEL_R685:
432 		outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
433 			(u32)hw->cfg.start + GAZEL_INCSR);
434 		break;
435 	case INF_GAZEL_R753:
436 		outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
437 			(u32)hw->cfg.start + GAZEL_INCSR);
438 		break;
439 	default:
440 		break;
441 	}
442 }
443 
444 static void
445 disable_hwirq(struct inf_hw *hw)
446 {
447 	u16 w;
448 	u32 val;
449 
450 	switch (hw->ci->typ) {
451 	case INF_DIVA201:
452 	case INF_DIVA202:
453 		writel(0, hw->cfg.p);
454 		break;
455 	case INF_SPEEDWIN:
456 	case INF_SAPHIR3:
457 		outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
458 		break;
459 	case INF_QS1000:
460 		outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
461 		break;
462 	case INF_QS3000:
463 		outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
464 		break;
465 	case INF_NICCY:
466 		val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
467 		val &= NICCY_IRQ_DISABLE;
468 		outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
469 		break;
470 	case INF_SCT_1:
471 		w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
472 		w &= (~SCT_PLX_IRQ_ENABLE);
473 		outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
474 		break;
475 	case INF_GAZEL_R685:
476 	case INF_GAZEL_R753:
477 		outb(0, (u32)hw->cfg.start + GAZEL_INCSR);
478 		break;
479 	default:
480 		break;
481 	}
482 }
483 
484 static void
485 ipac_chip_reset(struct inf_hw *hw)
486 {
487 	hw->ipac.write_reg(hw, IPAC_POTA2, 0x20);
488 	mdelay(5);
489 	hw->ipac.write_reg(hw, IPAC_POTA2, 0x00);
490 	mdelay(5);
491 	hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf);
492 	hw->ipac.write_reg(hw, IPAC_MASK, 0xc0);
493 }
494 
495 static void
496 reset_inf(struct inf_hw *hw)
497 {
498 	u16 w;
499 	u32 val;
500 
501 	if (debug & DEBUG_HW)
502 		pr_notice("%s: resetting card\n", hw->name);
503 	switch (hw->ci->typ) {
504 	case INF_DIVA20:
505 	case INF_DIVA20U:
506 		outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL);
507 		mdelay(10);
508 		outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL);
509 		mdelay(10);
510 		/* Workaround PCI9060 */
511 		outb(9, (u32)hw->cfg.start + 0x69);
512 		outb(DIVA_RESET_BIT | DIVA_LED_A,
513 			(u32)hw->cfg.start + DIVA_PCI_CTRL);
514 		break;
515 	case INF_DIVA201:
516 		writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
517 			hw->cfg.p + PITA_MISC_REG);
518 		mdelay(1);
519 		writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
520 		mdelay(10);
521 		break;
522 	case INF_DIVA202:
523 		writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
524 			hw->cfg.p + PITA_MISC_REG);
525 		mdelay(1);
526 		writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
527 			hw->cfg.p + PITA_MISC_REG);
528 		mdelay(10);
529 		break;
530 	case INF_SPEEDWIN:
531 	case INF_SAPHIR3:
532 		ipac_chip_reset(hw);
533 		hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
534 		hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
535 		hw->ipac.write_reg(hw, IPAC_PCFG, 0x12);
536 		break;
537 	case INF_QS1000:
538 	case INF_QS3000:
539 		ipac_chip_reset(hw);
540 		hw->ipac.write_reg(hw, IPAC_ACFG, 0x00);
541 		hw->ipac.write_reg(hw, IPAC_AOE, 0x3c);
542 		hw->ipac.write_reg(hw, IPAC_ATX, 0xff);
543 		break;
544 	case INF_NICCY:
545 		break;
546 	case INF_SCT_1:
547 		w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
548 		w &= (~SCT_PLX_RESET_BIT);
549 		outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
550 		mdelay(10);
551 		w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
552 		w |= SCT_PLX_RESET_BIT;
553 		outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
554 		mdelay(10);
555 		break;
556 	case INF_GAZEL_R685:
557 		val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
558 		val |= (GAZEL_RESET_9050 + GAZEL_RESET);
559 		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
560 		val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
561 		mdelay(4);
562 		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
563 		mdelay(10);
564 		hw->ipac.isac.adf2 = 0x87;
565 		hw->ipac.hscx[0].slot = 0x1f;
566 		hw->ipac.hscx[1].slot = 0x23;
567 		break;
568 	case INF_GAZEL_R753:
569 		val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
570 		val |= (GAZEL_RESET_9050 + GAZEL_RESET);
571 		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
572 		val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
573 		mdelay(4);
574 		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
575 		mdelay(10);
576 		ipac_chip_reset(hw);
577 		hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
578 		hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
579 		hw->ipac.conf = 0x01; /* IOM off */
580 		break;
581 	default:
582 		return;
583 	}
584 	enable_hwirq(hw);
585 }
586 
587 static int
588 inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
589 {
590 	int ret = 0;
591 
592 	switch (cmd) {
593 	case HW_RESET_REQ:
594 		reset_inf(hw);
595 		break;
596 	default:
597 		pr_info("%s: %s unknown command %x %lx\n",
598 			hw->name, __func__, cmd, arg);
599 		ret = -EINVAL;
600 		break;
601 	}
602 	return ret;
603 }
604 
605 static int __devinit
606 init_irq(struct inf_hw *hw)
607 {
608 	int	ret, cnt = 3;
609 	u_long	flags;
610 
611 	if (!hw->ci->irqfunc)
612 		return -EINVAL;
613 	ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw);
614 	if (ret) {
615 		pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq);
616 		return ret;
617 	}
618 	while (cnt--) {
619 		spin_lock_irqsave(&hw->lock, flags);
620 		reset_inf(hw);
621 		ret = hw->ipac.init(&hw->ipac);
622 		if (ret) {
623 			spin_unlock_irqrestore(&hw->lock, flags);
624 			pr_info("%s: ISAC init failed with %d\n",
625 				hw->name, ret);
626 			break;
627 		}
628 		spin_unlock_irqrestore(&hw->lock, flags);
629 		msleep_interruptible(10);
630 		if (debug & DEBUG_HW)
631 			pr_notice("%s: IRQ %d count %d\n", hw->name,
632 				hw->irq, hw->irqcnt);
633 		if (!hw->irqcnt) {
634 			pr_info("%s: IRQ(%d) got no requests during init %d\n",
635 				hw->name, hw->irq, 3 - cnt);
636 		} else
637 			return 0;
638 	}
639 	free_irq(hw->irq, hw);
640 	return -EIO;
641 }
642 
643 static void
644 release_io(struct inf_hw *hw)
645 {
646 	if (hw->cfg.mode) {
647 		if (hw->cfg.p) {
648 			release_mem_region(hw->cfg.start, hw->cfg.size);
649 			iounmap(hw->cfg.p);
650 		} else
651 			release_region(hw->cfg.start, hw->cfg.size);
652 		hw->cfg.mode = AM_NONE;
653 	}
654 	if (hw->addr.mode) {
655 		if (hw->addr.p) {
656 			release_mem_region(hw->addr.start, hw->addr.size);
657 			iounmap(hw->addr.p);
658 		} else
659 			release_region(hw->addr.start, hw->addr.size);
660 		hw->addr.mode = AM_NONE;
661 	}
662 }
663 
664 static int __devinit
665 setup_io(struct inf_hw *hw)
666 {
667 	int err = 0;
668 
669 	if (hw->ci->cfg_mode) {
670 		hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
671 		hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
672 		if (hw->ci->cfg_mode == AM_MEMIO) {
673 			if (!request_mem_region(hw->cfg.start, hw->cfg.size,
674 			    hw->name))
675 				err = -EBUSY;
676 		} else {
677 			if (!request_region(hw->cfg.start, hw->cfg.size,
678 			    hw->name))
679 				err = -EBUSY;
680 		}
681 		if (err) {
682 			pr_info("mISDN: %s config port %lx (%lu bytes)"
683 				"already in use\n", hw->name,
684 				(ulong)hw->cfg.start, (ulong)hw->cfg.size);
685 			return err;
686 		}
687 		if (hw->ci->cfg_mode == AM_MEMIO)
688 			hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
689 		hw->cfg.mode = hw->ci->cfg_mode;
690 		if (debug & DEBUG_HW)
691 			pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
692 				hw->name, (ulong)hw->cfg.start,
693 				(ulong)hw->cfg.size, hw->ci->cfg_mode);
694 
695 	}
696 	if (hw->ci->addr_mode) {
697 		hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
698 		hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
699 		if (hw->ci->addr_mode == AM_MEMIO) {
700 			if (!request_mem_region(hw->addr.start, hw->addr.size,
701 			    hw->name))
702 				err = -EBUSY;
703 		} else {
704 			if (!request_region(hw->addr.start, hw->addr.size,
705 			    hw->name))
706 				err = -EBUSY;
707 		}
708 		if (err) {
709 			pr_info("mISDN: %s address port %lx (%lu bytes)"
710 				"already in use\n", hw->name,
711 				(ulong)hw->addr.start, (ulong)hw->addr.size);
712 			return err;
713 		}
714 		if (hw->ci->addr_mode == AM_MEMIO)
715 			hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
716 		hw->addr.mode = hw->ci->addr_mode;
717 		if (debug & DEBUG_HW)
718 			pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
719 				hw->name, (ulong)hw->addr.start,
720 				(ulong)hw->addr.size, hw->ci->addr_mode);
721 
722 	}
723 
724 	switch (hw->ci->typ) {
725 	case INF_DIVA20:
726 	case INF_DIVA20U:
727 		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
728 		hw->isac.mode = hw->cfg.mode;
729 		hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
730 		hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
731 		hw->hscx.mode = hw->cfg.mode;
732 		hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
733 		hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
734 		break;
735 	case INF_DIVA201:
736 		hw->ipac.type = IPAC_TYPE_IPAC;
737 		hw->ipac.isac.off = 0x80;
738 		hw->isac.mode = hw->addr.mode;
739 		hw->isac.a.p = hw->addr.p;
740 		hw->hscx.mode = hw->addr.mode;
741 		hw->hscx.a.p = hw->addr.p;
742 		break;
743 	case INF_DIVA202:
744 		hw->ipac.type = IPAC_TYPE_IPACX;
745 		hw->isac.mode = hw->addr.mode;
746 		hw->isac.a.p = hw->addr.p;
747 		hw->hscx.mode = hw->addr.mode;
748 		hw->hscx.a.p = hw->addr.p;
749 		break;
750 	case INF_SPEEDWIN:
751 	case INF_SAPHIR3:
752 		hw->ipac.type = IPAC_TYPE_IPAC;
753 		hw->ipac.isac.off = 0x80;
754 		hw->isac.mode = hw->cfg.mode;
755 		hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
756 		hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
757 		hw->hscx.mode = hw->cfg.mode;
758 		hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
759 		hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
760 		outb(0xff, (ulong)hw->cfg.start);
761 		mdelay(1);
762 		outb(0x00, (ulong)hw->cfg.start);
763 		mdelay(1);
764 		outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
765 		break;
766 	case INF_QS1000:
767 	case INF_QS3000:
768 		hw->ipac.type = IPAC_TYPE_IPAC;
769 		hw->ipac.isac.off = 0x80;
770 		hw->isac.a.io.ale = (u32)hw->addr.start;
771 		hw->isac.a.io.port = (u32)hw->addr.start + 1;
772 		hw->isac.mode = hw->addr.mode;
773 		hw->hscx.a.io.ale = (u32)hw->addr.start;
774 		hw->hscx.a.io.port = (u32)hw->addr.start + 1;
775 		hw->hscx.mode = hw->addr.mode;
776 		break;
777 	case INF_NICCY:
778 		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
779 		hw->isac.mode = hw->addr.mode;
780 		hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
781 		hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
782 		hw->hscx.mode = hw->addr.mode;
783 		hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
784 		hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
785 		break;
786 	case INF_SCT_1:
787 		hw->ipac.type = IPAC_TYPE_IPAC;
788 		hw->ipac.isac.off = 0x80;
789 		hw->isac.a.io.ale = (u32)hw->addr.start;
790 		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
791 		hw->isac.mode = hw->addr.mode;
792 		hw->hscx.a.io.ale = hw->isac.a.io.ale;
793 		hw->hscx.a.io.port = hw->isac.a.io.port;
794 		hw->hscx.mode = hw->addr.mode;
795 		break;
796 	case INF_SCT_2:
797 		hw->ipac.type = IPAC_TYPE_IPAC;
798 		hw->ipac.isac.off = 0x80;
799 		hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
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;
805 		break;
806 	case INF_SCT_3:
807 		hw->ipac.type = IPAC_TYPE_IPAC;
808 		hw->ipac.isac.off = 0x80;
809 		hw->isac.a.io.ale = (u32)hw->addr.start + 0x10;
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;
815 		break;
816 	case INF_SCT_4:
817 		hw->ipac.type = IPAC_TYPE_IPAC;
818 		hw->ipac.isac.off = 0x80;
819 		hw->isac.a.io.ale = (u32)hw->addr.start + 0x20;
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;
825 		break;
826 	case INF_GAZEL_R685:
827 		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
828 		hw->ipac.isac.off = 0x80;
829 		hw->isac.mode = hw->addr.mode;
830 		hw->isac.a.io.port = (u32)hw->addr.start;
831 		hw->hscx.mode = hw->addr.mode;
832 		hw->hscx.a.io.port = hw->isac.a.io.port;
833 		break;
834 	case INF_GAZEL_R753:
835 		hw->ipac.type = IPAC_TYPE_IPAC;
836 		hw->ipac.isac.off = 0x80;
837 		hw->isac.mode = hw->addr.mode;
838 		hw->isac.a.io.ale = (u32)hw->addr.start;
839 		hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
840 		hw->hscx.mode = hw->addr.mode;
841 		hw->hscx.a.io.ale = hw->isac.a.io.ale;
842 		hw->hscx.a.io.port = hw->isac.a.io.port;
843 		break;
844 	default:
845 		return -EINVAL;
846 	}
847 	switch (hw->isac.mode) {
848 	case AM_MEMIO:
849 		ASSIGN_FUNC_IPAC(MIO, hw->ipac);
850 		break;
851 	case AM_IND_IO:
852 		ASSIGN_FUNC_IPAC(IND, hw->ipac);
853 		break;
854 	case AM_IO:
855 		ASSIGN_FUNC_IPAC(IO, hw->ipac);
856 		break;
857 	default:
858 		return -EINVAL;
859 	}
860 	return 0;
861 }
862 
863 static void
864 release_card(struct inf_hw *card) {
865 	ulong	flags;
866 	int	i;
867 
868 	spin_lock_irqsave(&card->lock, flags);
869 	disable_hwirq(card);
870 	spin_unlock_irqrestore(&card->lock, flags);
871 	card->ipac.isac.release(&card->ipac.isac);
872 	free_irq(card->irq, card);
873 	mISDN_unregister_device(&card->ipac.isac.dch.dev);
874 	release_io(card);
875 	write_lock_irqsave(&card_lock, flags);
876 	list_del(&card->list);
877 	write_unlock_irqrestore(&card_lock, flags);
878 	switch (card->ci->typ) {
879 	case INF_SCT_2:
880 	case INF_SCT_3:
881 	case INF_SCT_4:
882 		break;
883 	case INF_SCT_1:
884 		for (i = 0; i < 3; i++) {
885 			if (card->sc[i])
886 				release_card(card->sc[i]);
887 			card->sc[i] = NULL;
888 		}
889 	default:
890 		pci_disable_device(card->pdev);
891 		pci_set_drvdata(card->pdev, NULL);
892 		break;
893 	}
894 	kfree(card);
895 	inf_cnt--;
896 }
897 
898 static int __devinit
899 setup_instance(struct inf_hw *card)
900 {
901 	int err;
902 	ulong flags;
903 
904 	snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
905 		inf_cnt + 1);
906 	write_lock_irqsave(&card_lock, flags);
907 	list_add_tail(&card->list, &Cards);
908 	write_unlock_irqrestore(&card_lock, flags);
909 
910 	_set_debug(card);
911 	card->ipac.isac.name = card->name;
912 	card->ipac.name = card->name;
913 	card->ipac.owner = THIS_MODULE;
914 	spin_lock_init(&card->lock);
915 	card->ipac.isac.hwlock = &card->lock;
916 	card->ipac.hwlock = &card->lock;
917 	card->ipac.ctrl = (void *)&inf_ctrl;
918 
919 	err = setup_io(card);
920 	if (err)
921 		goto error_setup;
922 
923 	card->ipac.isac.dch.dev.Bprotocols =
924 		mISDNipac_init(&card->ipac, card);
925 
926 	if (card->ipac.isac.dch.dev.Bprotocols == 0)
927 		goto error_setup;;
928 
929 	err = mISDN_register_device(&card->ipac.isac.dch.dev,
930 		&card->pdev->dev, card->name);
931 	if (err)
932 		goto error;
933 
934 	err = init_irq(card);
935 	if (!err)  {
936 		inf_cnt++;
937 		pr_notice("Infineon %d cards installed\n", inf_cnt);
938 		return 0;
939 	}
940 	mISDN_unregister_device(&card->ipac.isac.dch.dev);
941 error:
942 	card->ipac.release(&card->ipac);
943 error_setup:
944 	release_io(card);
945 	write_lock_irqsave(&card_lock, flags);
946 	list_del(&card->list);
947 	write_unlock_irqrestore(&card_lock, flags);
948 	return err;
949 }
950 
951 static const struct inf_cinfo inf_card_info[] = {
952 	{
953 		INF_DIVA20,
954 		"Dialogic Diva 2.0",
955 		"diva20",
956 		AM_IND_IO, AM_NONE, 2, 0,
957 		&diva_irq
958 	},
959 	{
960 		INF_DIVA20U,
961 		"Dialogic Diva 2.0U",
962 		"diva20U",
963 		AM_IND_IO, AM_NONE, 2, 0,
964 		&diva_irq
965 	},
966 	{
967 		INF_DIVA201,
968 		"Dialogic Diva 2.01",
969 		"diva201",
970 		AM_MEMIO, AM_MEMIO, 0, 1,
971 		&diva20x_irq
972 	},
973 	{
974 		INF_DIVA202,
975 		"Dialogic Diva 2.02",
976 		"diva202",
977 		AM_MEMIO, AM_MEMIO, 0, 1,
978 		&diva20x_irq
979 	},
980 	{
981 		INF_SPEEDWIN,
982 		"Sedlbauer SpeedWin PCI",
983 		"speedwin",
984 		AM_IND_IO, AM_NONE, 0, 0,
985 		&tiger_irq
986 	},
987 	{
988 		INF_SAPHIR3,
989 		"HST Saphir 3",
990 		"saphir",
991 		AM_IND_IO, AM_NONE, 0, 0,
992 		&tiger_irq
993 	},
994 	{
995 		INF_QS1000,
996 		"Develo Microlink PCI",
997 		"qs1000",
998 		AM_IO, AM_IND_IO, 1, 3,
999 		&elsa_irq
1000 	},
1001 	{
1002 		INF_QS3000,
1003 		"Develo QuickStep 3000",
1004 		"qs3000",
1005 		AM_IO, AM_IND_IO, 1, 3,
1006 		&elsa_irq
1007 	},
1008 	{
1009 		INF_NICCY,
1010 		"Sagem NICCY",
1011 		"niccy",
1012 		AM_IO, AM_IND_IO, 0, 1,
1013 		&niccy_irq
1014 	},
1015 	{
1016 		INF_SCT_1,
1017 		"SciTel Quadro",
1018 		"p1_scitel",
1019 		AM_IO, AM_IND_IO, 1, 5,
1020 		&ipac_irq
1021 	},
1022 	{
1023 		INF_SCT_2,
1024 		"SciTel Quadro",
1025 		"p2_scitel",
1026 		AM_NONE, AM_IND_IO, 0, 4,
1027 		&ipac_irq
1028 	},
1029 	{
1030 		INF_SCT_3,
1031 		"SciTel Quadro",
1032 		"p3_scitel",
1033 		AM_NONE, AM_IND_IO, 0, 3,
1034 		&ipac_irq
1035 	},
1036 	{
1037 		INF_SCT_4,
1038 		"SciTel Quadro",
1039 		"p4_scitel",
1040 		AM_NONE, AM_IND_IO, 0, 2,
1041 		&ipac_irq
1042 	},
1043 	{
1044 		INF_GAZEL_R685,
1045 		"Gazel R685",
1046 		"gazel685",
1047 		AM_IO, AM_IO, 1, 2,
1048 		&gazel_irq
1049 	},
1050 	{
1051 		INF_GAZEL_R753,
1052 		"Gazel R753",
1053 		"gazel753",
1054 		AM_IO, AM_IND_IO, 1, 2,
1055 		&ipac_irq
1056 	},
1057 	{
1058 		INF_NONE,
1059 	}
1060 };
1061 
1062 static const struct inf_cinfo * __devinit
1063 get_card_info(enum inf_types typ)
1064 {
1065 	const struct inf_cinfo *ci = inf_card_info;
1066 
1067 	while (ci->typ != INF_NONE) {
1068 		if (ci->typ == typ)
1069 			return ci;
1070 		ci++;
1071 	}
1072 	return NULL;
1073 }
1074 
1075 static int __devinit
1076 inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1077 {
1078 	int err = -ENOMEM;
1079 	struct inf_hw *card;
1080 
1081 	card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1082 	if (!card) {
1083 		pr_info("No memory for Infineon ISDN card\n");
1084 		return err;
1085 	}
1086 	card->pdev = pdev;
1087 	err = pci_enable_device(pdev);
1088 	if (err) {
1089 		kfree(card);
1090 		return err;
1091 	}
1092 	card->ci = get_card_info(ent->driver_data);
1093 	if (!card->ci) {
1094 		pr_info("mISDN: do not have informations about adapter at %s\n",
1095 			pci_name(pdev));
1096 		kfree(card);
1097 		pci_disable_device(pdev);
1098 		return -EINVAL;
1099 	} else
1100 		pr_notice("mISDN: found adapter %s at %s\n",
1101 			card->ci->full, pci_name(pdev));
1102 
1103 	card->irq = pdev->irq;
1104 	pci_set_drvdata(pdev, card);
1105 	err = setup_instance(card);
1106 	if (err) {
1107 		pci_disable_device(pdev);
1108 		kfree(card);
1109 		pci_set_drvdata(pdev, NULL);
1110 	} else if (ent->driver_data == INF_SCT_1) {
1111 		int i;
1112 		struct inf_hw *sc;
1113 
1114 		for (i = 1; i < 4; i++) {
1115 			sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1116 			if (!sc) {
1117 				release_card(card);
1118 				pci_disable_device(pdev);
1119 				return -ENOMEM;
1120 			}
1121 			sc->irq = card->irq;
1122 			sc->pdev = card->pdev;
1123 			sc->ci = card->ci + i;
1124 			err = setup_instance(sc);
1125 			if (err) {
1126 				pci_disable_device(pdev);
1127 				kfree(sc);
1128 				release_card(card);
1129 				break;
1130 			} else
1131 				card->sc[i - 1] = sc;
1132 		}
1133 	}
1134 	return err;
1135 }
1136 
1137 static void __devexit
1138 inf_remove(struct pci_dev *pdev)
1139 {
1140 	struct inf_hw	*card = pci_get_drvdata(pdev);
1141 
1142 	if (card)
1143 		release_card(card);
1144 	else
1145 		pr_debug("%s: drvdata already removed\n", __func__);
1146 }
1147 
1148 static struct pci_driver infineon_driver = {
1149 	.name = "ISDN Infineon pci",
1150 	.probe = inf_probe,
1151 	.remove = __devexit_p(inf_remove),
1152 	.id_table = infineon_ids,
1153 };
1154 
1155 static int __init
1156 infineon_init(void)
1157 {
1158 	int err;
1159 
1160 	pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
1161 	err = pci_register_driver(&infineon_driver);
1162 	return err;
1163 }
1164 
1165 static void __exit
1166 infineon_cleanup(void)
1167 {
1168 	pci_unregister_driver(&infineon_driver);
1169 }
1170 
1171 module_init(infineon_init);
1172 module_exit(infineon_cleanup);
1173