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