Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us