Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mISDNinfineon.c
Go to the documentation of this file.
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 <[email protected]>
23  *
24  * Copyright 2009 by Karsten Keil <[email protected]>
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 {
72 };
73 
74 enum addr_mode {
75  AM_NONE = 0,
79 };
80 
81 struct inf_cinfo {
82  enum inf_types typ;
83  const char *full;
84  const char *name;
89  void *irqfunc;
90 };
91 
92 struct _ioaddr {
94  union {
95  void __iomem *p;
96  struct _ioport io;
97  } a;
98 };
99 
100 struct _iohandle {
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;
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[] __devinitdata = {
135  INF_SPEEDWIN },
143  INF_SCT_1 },
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");
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;
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:
434  (u32)hw->cfg.start + GAZEL_INCSR);
435  break;
436  case INF_GAZEL_R753:
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);
514  (u32)hw->cfg.start + DIVA_PCI_CTRL);
515  break;
516  case INF_DIVA201:
518  hw->cfg.p + PITA_MISC_REG);
519  mdelay(1);
521  mdelay(10);
522  break;
523  case INF_DIVA202:
525  hw->cfg.p + PITA_MISC_REG);
526  mdelay(1);
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 __devinit
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);
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 __devinit
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 __devinit
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  {
1046  "Gazel R685",
1047  "gazel685",
1048  AM_IO, AM_IO, 1, 2,
1049  &gazel_irq
1050  },
1051  {
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 * __devinit
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 __devinit
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 __devexit
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 = __devexit_p(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);