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.mode == AM_MEMIO) {
634 			release_mem_region(hw->cfg.start, hw->cfg.size);
635 			if (hw->cfg.p)
636 				iounmap(hw->cfg.p);
637 		} else
638 			release_region(hw->cfg.start, hw->cfg.size);
639 		hw->cfg.mode = AM_NONE;
640 	}
641 	if (hw->addr.mode) {
642 		if (hw->addr.mode == AM_MEMIO) {
643 			release_mem_region(hw->addr.start, hw->addr.size);
644 			if (hw->addr.p)
645 				iounmap(hw->addr.p);
646 		} else
647 			release_region(hw->addr.start, hw->addr.size);
648 		hw->addr.mode = AM_NONE;
649 	}
650 }
651 
652 static int
653 setup_io(struct inf_hw *hw)
654 {
655 	int err = 0;
656 
657 	if (hw->ci->cfg_mode) {
658 		hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
659 		hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
660 		if (hw->ci->cfg_mode == AM_MEMIO) {
661 			if (!request_mem_region(hw->cfg.start, hw->cfg.size,
662 						hw->name))
663 				err = -EBUSY;
664 		} else {
665 			if (!request_region(hw->cfg.start, hw->cfg.size,
666 					    hw->name))
667 				err = -EBUSY;
668 		}
669 		if (err) {
670 			pr_info("mISDN: %s config port %lx (%lu bytes)"
671 				"already in use\n", hw->name,
672 				(ulong)hw->cfg.start, (ulong)hw->cfg.size);
673 			return err;
674 		}
675 		hw->cfg.mode = hw->ci->cfg_mode;
676 		if (hw->ci->cfg_mode == AM_MEMIO) {
677 			hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
678 			if (!hw->cfg.p)
679 				return -ENOMEM;
680 		}
681 		if (debug & DEBUG_HW)
682 			pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
683 				  hw->name, (ulong)hw->cfg.start,
684 				  (ulong)hw->cfg.size, hw->ci->cfg_mode);
685 
686 	}
687 	if (hw->ci->addr_mode) {
688 		hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
689 		hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
690 		if (hw->ci->addr_mode == AM_MEMIO) {
691 			if (!request_mem_region(hw->addr.start, hw->addr.size,
692 						hw->name))
693 				err = -EBUSY;
694 		} else {
695 			if (!request_region(hw->addr.start, hw->addr.size,
696 					    hw->name))
697 				err = -EBUSY;
698 		}
699 		if (err) {
700 			pr_info("mISDN: %s address port %lx (%lu bytes)"
701 				"already in use\n", hw->name,
702 				(ulong)hw->addr.start, (ulong)hw->addr.size);
703 			return err;
704 		}
705 		hw->addr.mode = hw->ci->addr_mode;
706 		if (hw->ci->addr_mode == AM_MEMIO) {
707 			hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
708 			if (!hw->addr.p)
709 				return -ENOMEM;
710 		}
711 		if (debug & DEBUG_HW)
712 			pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
713 				  hw->name, (ulong)hw->addr.start,
714 				  (ulong)hw->addr.size, hw->ci->addr_mode);
715 
716 	}
717 
718 	switch (hw->ci->typ) {
719 	case INF_DIVA20:
720 	case INF_DIVA20U:
721 		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
722 		hw->isac.mode = hw->cfg.mode;
723 		hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
724 		hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
725 		hw->hscx.mode = hw->cfg.mode;
726 		hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
727 		hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
728 		break;
729 	case INF_DIVA201:
730 		hw->ipac.type = IPAC_TYPE_IPAC;
731 		hw->ipac.isac.off = 0x80;
732 		hw->isac.mode = hw->addr.mode;
733 		hw->isac.a.p = hw->addr.p;
734 		hw->hscx.mode = hw->addr.mode;
735 		hw->hscx.a.p = hw->addr.p;
736 		break;
737 	case INF_DIVA202:
738 		hw->ipac.type = IPAC_TYPE_IPACX;
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;
743 		break;
744 	case INF_SPEEDWIN:
745 	case INF_SAPHIR3:
746 		hw->ipac.type = IPAC_TYPE_IPAC;
747 		hw->ipac.isac.off = 0x80;
748 		hw->isac.mode = hw->cfg.mode;
749 		hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
750 		hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
751 		hw->hscx.mode = hw->cfg.mode;
752 		hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
753 		hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
754 		outb(0xff, (ulong)hw->cfg.start);
755 		mdelay(1);
756 		outb(0x00, (ulong)hw->cfg.start);
757 		mdelay(1);
758 		outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
759 		break;
760 	case INF_QS1000:
761 	case INF_QS3000:
762 		hw->ipac.type = IPAC_TYPE_IPAC;
763 		hw->ipac.isac.off = 0x80;
764 		hw->isac.a.io.ale = (u32)hw->addr.start;
765 		hw->isac.a.io.port = (u32)hw->addr.start + 1;
766 		hw->isac.mode = hw->addr.mode;
767 		hw->hscx.a.io.ale = (u32)hw->addr.start;
768 		hw->hscx.a.io.port = (u32)hw->addr.start + 1;
769 		hw->hscx.mode = hw->addr.mode;
770 		break;
771 	case INF_NICCY:
772 		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
773 		hw->isac.mode = hw->addr.mode;
774 		hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
775 		hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
776 		hw->hscx.mode = hw->addr.mode;
777 		hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
778 		hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
779 		break;
780 	case INF_SCT_1:
781 		hw->ipac.type = IPAC_TYPE_IPAC;
782 		hw->ipac.isac.off = 0x80;
783 		hw->isac.a.io.ale = (u32)hw->addr.start;
784 		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
785 		hw->isac.mode = hw->addr.mode;
786 		hw->hscx.a.io.ale = hw->isac.a.io.ale;
787 		hw->hscx.a.io.port = hw->isac.a.io.port;
788 		hw->hscx.mode = hw->addr.mode;
789 		break;
790 	case INF_SCT_2:
791 		hw->ipac.type = IPAC_TYPE_IPAC;
792 		hw->ipac.isac.off = 0x80;
793 		hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
794 		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
795 		hw->isac.mode = hw->addr.mode;
796 		hw->hscx.a.io.ale = hw->isac.a.io.ale;
797 		hw->hscx.a.io.port = hw->isac.a.io.port;
798 		hw->hscx.mode = hw->addr.mode;
799 		break;
800 	case INF_SCT_3:
801 		hw->ipac.type = IPAC_TYPE_IPAC;
802 		hw->ipac.isac.off = 0x80;
803 		hw->isac.a.io.ale = (u32)hw->addr.start + 0x10;
804 		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
805 		hw->isac.mode = hw->addr.mode;
806 		hw->hscx.a.io.ale = hw->isac.a.io.ale;
807 		hw->hscx.a.io.port = hw->isac.a.io.port;
808 		hw->hscx.mode = hw->addr.mode;
809 		break;
810 	case INF_SCT_4:
811 		hw->ipac.type = IPAC_TYPE_IPAC;
812 		hw->ipac.isac.off = 0x80;
813 		hw->isac.a.io.ale = (u32)hw->addr.start + 0x20;
814 		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
815 		hw->isac.mode = hw->addr.mode;
816 		hw->hscx.a.io.ale = hw->isac.a.io.ale;
817 		hw->hscx.a.io.port = hw->isac.a.io.port;
818 		hw->hscx.mode = hw->addr.mode;
819 		break;
820 	case INF_GAZEL_R685:
821 		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
822 		hw->ipac.isac.off = 0x80;
823 		hw->isac.mode = hw->addr.mode;
824 		hw->isac.a.io.port = (u32)hw->addr.start;
825 		hw->hscx.mode = hw->addr.mode;
826 		hw->hscx.a.io.port = hw->isac.a.io.port;
827 		break;
828 	case INF_GAZEL_R753:
829 		hw->ipac.type = IPAC_TYPE_IPAC;
830 		hw->ipac.isac.off = 0x80;
831 		hw->isac.mode = hw->addr.mode;
832 		hw->isac.a.io.ale = (u32)hw->addr.start;
833 		hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
834 		hw->hscx.mode = hw->addr.mode;
835 		hw->hscx.a.io.ale = hw->isac.a.io.ale;
836 		hw->hscx.a.io.port = hw->isac.a.io.port;
837 		break;
838 	default:
839 		return -EINVAL;
840 	}
841 	switch (hw->isac.mode) {
842 	case AM_MEMIO:
843 		ASSIGN_FUNC_IPAC(MIO, hw->ipac);
844 		break;
845 	case AM_IND_IO:
846 		ASSIGN_FUNC_IPAC(IND, hw->ipac);
847 		break;
848 	case AM_IO:
849 		ASSIGN_FUNC_IPAC(IO, hw->ipac);
850 		break;
851 	default:
852 		return -EINVAL;
853 	}
854 	return 0;
855 }
856 
857 static void
858 release_card(struct inf_hw *card) {
859 	ulong	flags;
860 	int	i;
861 
862 	spin_lock_irqsave(&card->lock, flags);
863 	disable_hwirq(card);
864 	spin_unlock_irqrestore(&card->lock, flags);
865 	card->ipac.isac.release(&card->ipac.isac);
866 	free_irq(card->irq, card);
867 	mISDN_unregister_device(&card->ipac.isac.dch.dev);
868 	release_io(card);
869 	write_lock_irqsave(&card_lock, flags);
870 	list_del(&card->list);
871 	write_unlock_irqrestore(&card_lock, flags);
872 	switch (card->ci->typ) {
873 	case INF_SCT_2:
874 	case INF_SCT_3:
875 	case INF_SCT_4:
876 		break;
877 	case INF_SCT_1:
878 		for (i = 0; i < 3; i++) {
879 			if (card->sc[i])
880 				release_card(card->sc[i]);
881 			card->sc[i] = NULL;
882 		}
883 		fallthrough;
884 	default:
885 		pci_disable_device(card->pdev);
886 		pci_set_drvdata(card->pdev, NULL);
887 		break;
888 	}
889 	kfree(card);
890 	inf_cnt--;
891 }
892 
893 static int
894 setup_instance(struct inf_hw *card)
895 {
896 	int err;
897 	ulong flags;
898 
899 	snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
900 		 inf_cnt + 1);
901 	write_lock_irqsave(&card_lock, flags);
902 	list_add_tail(&card->list, &Cards);
903 	write_unlock_irqrestore(&card_lock, flags);
904 
905 	_set_debug(card);
906 	card->ipac.isac.name = card->name;
907 	card->ipac.name = card->name;
908 	card->ipac.owner = THIS_MODULE;
909 	spin_lock_init(&card->lock);
910 	card->ipac.isac.hwlock = &card->lock;
911 	card->ipac.hwlock = &card->lock;
912 	card->ipac.ctrl = (void *)&inf_ctrl;
913 
914 	err = setup_io(card);
915 	if (err)
916 		goto error_setup;
917 
918 	card->ipac.isac.dch.dev.Bprotocols =
919 		mISDNipac_init(&card->ipac, card);
920 
921 	if (card->ipac.isac.dch.dev.Bprotocols == 0)
922 		goto error_setup;
923 
924 	err = mISDN_register_device(&card->ipac.isac.dch.dev,
925 				    &card->pdev->dev, card->name);
926 	if (err)
927 		goto error;
928 
929 	err = init_irq(card);
930 	if (!err)  {
931 		inf_cnt++;
932 		pr_notice("Infineon %d cards installed\n", inf_cnt);
933 		return 0;
934 	}
935 	mISDN_unregister_device(&card->ipac.isac.dch.dev);
936 error:
937 	card->ipac.release(&card->ipac);
938 error_setup:
939 	release_io(card);
940 	write_lock_irqsave(&card_lock, flags);
941 	list_del(&card->list);
942 	write_unlock_irqrestore(&card_lock, flags);
943 	return err;
944 }
945 
946 static const struct inf_cinfo inf_card_info[] = {
947 	{
948 		INF_DIVA20,
949 		"Dialogic Diva 2.0",
950 		"diva20",
951 		AM_IND_IO, AM_NONE, 2, 0,
952 		&diva_irq
953 	},
954 	{
955 		INF_DIVA20U,
956 		"Dialogic Diva 2.0U",
957 		"diva20U",
958 		AM_IND_IO, AM_NONE, 2, 0,
959 		&diva_irq
960 	},
961 	{
962 		INF_DIVA201,
963 		"Dialogic Diva 2.01",
964 		"diva201",
965 		AM_MEMIO, AM_MEMIO, 0, 1,
966 		&diva20x_irq
967 	},
968 	{
969 		INF_DIVA202,
970 		"Dialogic Diva 2.02",
971 		"diva202",
972 		AM_MEMIO, AM_MEMIO, 0, 1,
973 		&diva20x_irq
974 	},
975 	{
976 		INF_SPEEDWIN,
977 		"Sedlbauer SpeedWin PCI",
978 		"speedwin",
979 		AM_IND_IO, AM_NONE, 0, 0,
980 		&tiger_irq
981 	},
982 	{
983 		INF_SAPHIR3,
984 		"HST Saphir 3",
985 		"saphir",
986 		AM_IND_IO, AM_NONE, 0, 0,
987 		&tiger_irq
988 	},
989 	{
990 		INF_QS1000,
991 		"Develo Microlink PCI",
992 		"qs1000",
993 		AM_IO, AM_IND_IO, 1, 3,
994 		&elsa_irq
995 	},
996 	{
997 		INF_QS3000,
998 		"Develo QuickStep 3000",
999 		"qs3000",
1000 		AM_IO, AM_IND_IO, 1, 3,
1001 		&elsa_irq
1002 	},
1003 	{
1004 		INF_NICCY,
1005 		"Sagem NICCY",
1006 		"niccy",
1007 		AM_IO, AM_IND_IO, 0, 1,
1008 		&niccy_irq
1009 	},
1010 	{
1011 		INF_SCT_1,
1012 		"SciTel Quadro",
1013 		"p1_scitel",
1014 		AM_IO, AM_IND_IO, 1, 5,
1015 		&ipac_irq
1016 	},
1017 	{
1018 		INF_SCT_2,
1019 		"SciTel Quadro",
1020 		"p2_scitel",
1021 		AM_NONE, AM_IND_IO, 0, 4,
1022 		&ipac_irq
1023 	},
1024 	{
1025 		INF_SCT_3,
1026 		"SciTel Quadro",
1027 		"p3_scitel",
1028 		AM_NONE, AM_IND_IO, 0, 3,
1029 		&ipac_irq
1030 	},
1031 	{
1032 		INF_SCT_4,
1033 		"SciTel Quadro",
1034 		"p4_scitel",
1035 		AM_NONE, AM_IND_IO, 0, 2,
1036 		&ipac_irq
1037 	},
1038 	{
1039 		INF_GAZEL_R685,
1040 		"Gazel R685",
1041 		"gazel685",
1042 		AM_IO, AM_IO, 1, 2,
1043 		&gazel_irq
1044 	},
1045 	{
1046 		INF_GAZEL_R753,
1047 		"Gazel R753",
1048 		"gazel753",
1049 		AM_IO, AM_IND_IO, 1, 2,
1050 		&ipac_irq
1051 	},
1052 	{
1053 		INF_NONE,
1054 	}
1055 };
1056 
1057 static const struct inf_cinfo *
1058 get_card_info(enum inf_types typ)
1059 {
1060 	const struct inf_cinfo *ci = inf_card_info;
1061 
1062 	while (ci->typ != INF_NONE) {
1063 		if (ci->typ == typ)
1064 			return ci;
1065 		ci++;
1066 	}
1067 	return NULL;
1068 }
1069 
1070 static int
1071 inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1072 {
1073 	int err = -ENOMEM;
1074 	struct inf_hw *card;
1075 
1076 	card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1077 	if (!card) {
1078 		pr_info("No memory for Infineon ISDN card\n");
1079 		return err;
1080 	}
1081 	card->pdev = pdev;
1082 	err = pci_enable_device(pdev);
1083 	if (err) {
1084 		kfree(card);
1085 		return err;
1086 	}
1087 	card->ci = get_card_info(ent->driver_data);
1088 	if (!card->ci) {
1089 		pr_info("mISDN: do not have information about adapter at %s\n",
1090 			pci_name(pdev));
1091 		kfree(card);
1092 		pci_disable_device(pdev);
1093 		return -EINVAL;
1094 	} else
1095 		pr_notice("mISDN: found adapter %s at %s\n",
1096 			  card->ci->full, pci_name(pdev));
1097 
1098 	card->irq = pdev->irq;
1099 	pci_set_drvdata(pdev, card);
1100 	err = setup_instance(card);
1101 	if (err) {
1102 		pci_disable_device(pdev);
1103 		kfree(card);
1104 		pci_set_drvdata(pdev, NULL);
1105 	} else if (ent->driver_data == INF_SCT_1) {
1106 		int i;
1107 		struct inf_hw *sc;
1108 
1109 		for (i = 1; i < 4; i++) {
1110 			sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1111 			if (!sc) {
1112 				release_card(card);
1113 				pci_disable_device(pdev);
1114 				return -ENOMEM;
1115 			}
1116 			sc->irq = card->irq;
1117 			sc->pdev = card->pdev;
1118 			sc->ci = card->ci + i;
1119 			err = setup_instance(sc);
1120 			if (err) {
1121 				pci_disable_device(pdev);
1122 				kfree(sc);
1123 				release_card(card);
1124 				break;
1125 			} else
1126 				card->sc[i - 1] = sc;
1127 		}
1128 	}
1129 	return err;
1130 }
1131 
1132 static void
1133 inf_remove(struct pci_dev *pdev)
1134 {
1135 	struct inf_hw	*card = pci_get_drvdata(pdev);
1136 
1137 	if (card)
1138 		release_card(card);
1139 	else
1140 		pr_debug("%s: drvdata already removed\n", __func__);
1141 }
1142 
1143 static struct pci_driver infineon_driver = {
1144 	.name = "ISDN Infineon pci",
1145 	.probe = inf_probe,
1146 	.remove = inf_remove,
1147 	.id_table = infineon_ids,
1148 };
1149 
1150 static int __init
1151 infineon_init(void)
1152 {
1153 	int err;
1154 
1155 	pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
1156 	err = pci_register_driver(&infineon_driver);
1157 	return err;
1158 }
1159 
1160 static void __exit
1161 infineon_cleanup(void)
1162 {
1163 	pci_unregister_driver(&infineon_driver);
1164 }
1165 
1166 module_init(infineon_init);
1167 module_exit(infineon_cleanup);
1168