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