Linux 6.9-rc6
[sfrench/cifs-2.6.git] / drivers / isdn / hardware / mISDN / mISDNinfineon.c
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);