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