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