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