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