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