[ARM] pxa: Gumstix Verdex PCMCIA support
[linux-2.6/verdex.git] / drivers / isdn / hardware / mISDN / mISDNinfineon.c
blob62441ba53b95c1b033a7744805c9d535eda722c1
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
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
22 * Author Karsten Keil <keil@isdn4linux.de>
24 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
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.
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.
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.
41 #include <linux/module.h>
42 #include <linux/pci.h>
43 #include <linux/delay.h>
44 #include <linux/mISDNhw.h>
45 #include "ipac.h"
47 #define INFINEON_REV "1.0"
49 static int inf_cnt;
50 static u32 debug;
51 static u32 irqloops = 4;
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
72 enum addr_mode {
73 AM_NONE = 0,
74 AM_IO,
75 AM_MEMIO,
76 AM_IND_IO,
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;
90 struct _ioaddr {
91 enum addr_mode mode;
92 union {
93 void __iomem *p;
94 struct _ioport io;
95 } a;
98 struct _iohandle {
99 enum addr_mode mode;
100 resource_size_t size;
101 resource_size_t start;
102 void __iomem *p;
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 */
122 #define PCI_SUBVENDOR_HST_SAPHIR3 0x52
123 #define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
124 #define PCI_SUB_ID_SEDLBAUER 0x01
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},
159 MODULE_DEVICE_TABLE(pci, infineon_ids);
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
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
177 /* Diva 2.01/2.02 */
178 /* Siemens PITA */
179 #define PITA_ICR_REG 0x00
180 #define PITA_INT0_STATUS 0x02
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
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
196 /* Tiger AUX BITs */
197 #define TIGER_IOMASK 0xdd /* 1 and 5 are inputs */
198 #define TIGER_IRQ_BIT 0x02
200 #define TIGER_IPAC_ALE 0xC0
201 #define TIGER_IPAC_PORT 0xC8
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
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
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
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
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
244 static LIST_HEAD(Cards);
245 static DEFINE_RWLOCK(card_lock); /* protect Cards */
247 static void
248 _set_debug(struct inf_hw *card)
250 card->ipac.isac.dch.debug = debug;
251 card->ipac.hscx[0].bch.debug = debug;
252 card->ipac.hscx[1].bch.debug = debug;
255 static int
256 set_debug(const char *val, struct kernel_param *kp)
258 int ret;
259 struct inf_hw *card;
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);
268 return ret;
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)");
279 /* Interface functions */
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)
288 static irqreturn_t
289 diva_irq(int intno, void *dev_id)
291 struct inf_hw *hw = dev_id;
292 u8 val;
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 */
300 hw->irqcnt++;
301 mISDNipac_irq(&hw->ipac, irqloops);
302 spin_unlock(&hw->lock);
303 return IRQ_HANDLED;
306 static irqreturn_t
307 diva20x_irq(int intno, void *dev_id)
309 struct inf_hw *hw = dev_id;
310 u8 val;
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 */
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;
325 static irqreturn_t
326 tiger_irq(int intno, void *dev_id)
328 struct inf_hw *hw = dev_id;
329 u8 val;
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 */
337 hw->irqcnt++;
338 mISDNipac_irq(&hw->ipac, irqloops);
339 spin_unlock(&hw->lock);
340 return IRQ_HANDLED;
343 static irqreturn_t
344 elsa_irq(int intno, void *dev_id)
346 struct inf_hw *hw = dev_id;
347 u8 val;
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 */
355 hw->irqcnt++;
356 mISDNipac_irq(&hw->ipac, irqloops);
357 spin_unlock(&hw->lock);
358 return IRQ_HANDLED;
361 static irqreturn_t
362 niccy_irq(int intno, void *dev_id)
364 struct inf_hw *hw = dev_id;
365 u32 val;
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 */
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;
380 static irqreturn_t
381 gazel_irq(int intno, void *dev_id)
383 struct inf_hw *hw = dev_id;
384 irqreturn_t ret;
386 spin_lock(&hw->lock);
387 ret = mISDNipac_irq(&hw->ipac, irqloops);
388 spin_unlock(&hw->lock);
389 return ret;
392 static irqreturn_t
393 ipac_irq(int intno, void *dev_id)
395 struct inf_hw *hw = dev_id;
396 u8 val;
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 */
404 hw->irqcnt++;
405 mISDNipac_irq(&hw->ipac, irqloops);
406 spin_unlock(&hw->lock);
407 return IRQ_HANDLED;
410 static void
411 enable_hwirq(struct inf_hw *hw)
413 u16 w;
414 u32 val;
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;
454 static void
455 disable_hwirq(struct inf_hw *hw)
457 u16 w;
458 u32 val;
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;
494 static void
495 ipac_chip_reset(struct inf_hw *hw)
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);
505 static void
506 reset_inf(struct inf_hw *hw)
508 u16 w;
509 u32 val;
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;
594 enable_hwirq(hw);
597 static int
598 inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
600 int ret = 0;
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;
612 return ret;
615 static int __devinit
616 init_irq(struct inf_hw *hw)
618 int ret, cnt = 3;
619 u_long flags;
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;
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;
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;
649 free_irq(hw->irq, hw);
650 return -EIO;
653 static void
654 release_io(struct inf_hw *hw)
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;
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;
674 static int __devinit
675 setup_io(struct inf_hw *hw)
677 int err = 0;
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;
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;
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);
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;
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;
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);
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;
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;
870 return 0;
873 static void
874 release_card(struct inf_hw *card) {
875 ulong flags;
876 int i;
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;
899 default:
900 pci_disable_device(card->pdev);
901 pci_set_drvdata(card->pdev, NULL);
902 break;
904 kfree(card);
905 inf_cnt--;
908 static int __devinit
909 setup_instance(struct inf_hw *card)
911 int err;
912 ulong flags;
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);
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;
929 err = setup_io(card);
930 if (err)
931 goto error_setup;
933 card->ipac.isac.dch.dev.Bprotocols =
934 mISDNipac_init(&card->ipac, card);
936 if (card->ipac.isac.dch.dev.Bprotocols == 0)
937 goto error_setup;;
939 err = mISDN_register_device(&card->ipac.isac.dch.dev,
940 &card->pdev->dev, card->name);
941 if (err)
942 goto error;
944 err = init_irq(card);
945 if (!err) {
946 inf_cnt++;
947 pr_notice("Infineon %d cards installed\n", inf_cnt);
948 return 0;
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;
961 static const struct inf_cinfo inf_card_info[] = {
963 INF_DIVA20,
964 "Dialogic Diva 2.0",
965 "diva20",
966 AM_IND_IO, AM_NONE, 2, 0,
967 &diva_irq
970 INF_DIVA20U,
971 "Dialogic Diva 2.0U",
972 "diva20U",
973 AM_IND_IO, AM_NONE, 2, 0,
974 &diva_irq
977 INF_DIVA201,
978 "Dialogic Diva 2.01",
979 "diva201",
980 AM_MEMIO, AM_MEMIO, 0, 1,
981 &diva20x_irq
984 INF_DIVA202,
985 "Dialogic Diva 2.02",
986 "diva202",
987 AM_MEMIO, AM_MEMIO, 0, 1,
988 &diva20x_irq
991 INF_SPEEDWIN,
992 "Sedlbauer SpeedWin PCI",
993 "speedwin",
994 AM_IND_IO, AM_NONE, 0, 0,
995 &tiger_irq
998 INF_SAPHIR3,
999 "HST Saphir 3",
1000 "saphir",
1001 AM_IND_IO, AM_NONE, 0, 0,
1002 &tiger_irq
1005 INF_QS1000,
1006 "Develo Microlink PCI",
1007 "qs1000",
1008 AM_IO, AM_IND_IO, 1, 3,
1009 &elsa_irq
1012 INF_QS3000,
1013 "Develo QuickStep 3000",
1014 "qs3000",
1015 AM_IO, AM_IND_IO, 1, 3,
1016 &elsa_irq
1019 INF_NICCY,
1020 "Sagem NICCY",
1021 "niccy",
1022 AM_IO, AM_IND_IO, 0, 1,
1023 &niccy_irq
1026 INF_SCT_1,
1027 "SciTel Quadro",
1028 "p1_scitel",
1029 AM_IO, AM_IND_IO, 1, 5,
1030 &ipac_irq
1033 INF_SCT_2,
1034 "SciTel Quadro",
1035 "p2_scitel",
1036 AM_NONE, AM_IND_IO, 0, 4,
1037 &ipac_irq
1040 INF_SCT_3,
1041 "SciTel Quadro",
1042 "p3_scitel",
1043 AM_NONE, AM_IND_IO, 0, 3,
1044 &ipac_irq
1047 INF_SCT_4,
1048 "SciTel Quadro",
1049 "p4_scitel",
1050 AM_NONE, AM_IND_IO, 0, 2,
1051 &ipac_irq
1054 INF_GAZEL_R685,
1055 "Gazel R685",
1056 "gazel685",
1057 AM_IO, AM_IO, 1, 2,
1058 &gazel_irq
1061 INF_GAZEL_R753,
1062 "Gazel R753",
1063 "gazel753",
1064 AM_IO, AM_IND_IO, 1, 2,
1065 &ipac_irq
1068 INF_NONE,
1072 static const struct inf_cinfo * __devinit
1073 get_card_info(enum inf_types typ)
1075 const struct inf_cinfo *ci = inf_card_info;
1077 while (ci->typ != INF_NONE) {
1078 if (ci->typ == typ)
1079 return ci;
1080 ci++;
1082 return NULL;
1085 static int __devinit
1086 inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1088 int err = -ENOMEM;
1089 struct inf_hw *card;
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;
1096 card->pdev = pdev;
1097 err = pci_enable_device(pdev);
1098 if (err) {
1099 kfree(card);
1100 return err;
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));
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;
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;
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;
1140 return err;
1143 static void __devexit
1144 inf_remove(struct pci_dev *pdev)
1146 struct inf_hw *card = pci_get_drvdata(pdev);
1148 if (card)
1149 release_card(card);
1150 else
1151 pr_debug("%s: drvdata allready removed\n", __func__);
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,
1161 static int __init
1162 infineon_init(void)
1164 int err;
1166 pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
1167 err = pci_register_driver(&infineon_driver);
1168 return err;
1171 static void __exit
1172 infineon_cleanup(void)
1174 pci_unregister_driver(&infineon_driver);
1177 module_init(infineon_init);
1178 module_exit(infineon_cleanup);