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 50 static int inf_cnt; 51 static u32 debug; 52 static u32 irqloops = 4; 53 54 enum 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 73 enum addr_mode { 74 AM_NONE = 0, 75 AM_IO, 76 AM_MEMIO, 77 AM_IND_IO, 78 }; 79 80 struct 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 91 struct _ioaddr { 92 enum addr_mode mode; 93 union { 94 void __iomem *p; 95 struct _ioport io; 96 } a; 97 }; 98 99 struct _iohandle { 100 enum addr_mode mode; 101 resource_size_t size; 102 resource_size_t start; 103 void __iomem *p; 104 }; 105 106 struct 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 127 static 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 }; 149 MODULE_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 234 static LIST_HEAD(Cards); 235 static DEFINE_RWLOCK(card_lock); /* protect Cards */ 236 237 static 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 245 static int 246 set_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 261 MODULE_AUTHOR("Karsten Keil"); 262 MODULE_LICENSE("GPL v2"); 263 MODULE_VERSION(INFINEON_REV); 264 module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR); 265 MODULE_PARM_DESC(debug, "infineon debug mask"); 266 module_param(irqloops, uint, S_IRUGO | S_IWUSR); 267 MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)"); 268 269 /* Interface functions */ 270 271 IOFUNC_IO(ISAC, inf_hw, isac.a.io) 272 IOFUNC_IO(IPAC, inf_hw, hscx.a.io) 273 IOFUNC_IND(ISAC, inf_hw, isac.a.io) 274 IOFUNC_IND(IPAC, inf_hw, hscx.a.io) 275 IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p) 276 IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p) 277 278 static irqreturn_t 279 diva_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 296 static irqreturn_t 297 diva20x_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 315 static irqreturn_t 316 tiger_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 333 static irqreturn_t 334 elsa_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 351 static irqreturn_t 352 niccy_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 370 static irqreturn_t 371 gazel_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 382 static irqreturn_t 383 ipac_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 400 static void 401 enable_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 444 static void 445 disable_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 484 static void 485 ipac_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 495 static void 496 reset_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 /* Workaround PCI9060 */ 511 outb(9, (u32)hw->cfg.start + 0x69); 512 outb(DIVA_RESET_BIT | DIVA_LED_A, 513 (u32)hw->cfg.start + DIVA_PCI_CTRL); 514 break; 515 case INF_DIVA201: 516 writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE, 517 hw->cfg.p + PITA_MISC_REG); 518 mdelay(1); 519 writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG); 520 mdelay(10); 521 break; 522 case INF_DIVA202: 523 writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE, 524 hw->cfg.p + PITA_MISC_REG); 525 mdelay(1); 526 writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET, 527 hw->cfg.p + PITA_MISC_REG); 528 mdelay(10); 529 break; 530 case INF_SPEEDWIN: 531 case INF_SAPHIR3: 532 ipac_chip_reset(hw); 533 hw->ipac.write_reg(hw, IPAC_ACFG, 0xff); 534 hw->ipac.write_reg(hw, IPAC_AOE, 0x00); 535 hw->ipac.write_reg(hw, IPAC_PCFG, 0x12); 536 break; 537 case INF_QS1000: 538 case INF_QS3000: 539 ipac_chip_reset(hw); 540 hw->ipac.write_reg(hw, IPAC_ACFG, 0x00); 541 hw->ipac.write_reg(hw, IPAC_AOE, 0x3c); 542 hw->ipac.write_reg(hw, IPAC_ATX, 0xff); 543 break; 544 case INF_NICCY: 545 break; 546 case INF_SCT_1: 547 w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR); 548 w &= (~SCT_PLX_RESET_BIT); 549 outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR); 550 mdelay(10); 551 w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR); 552 w |= SCT_PLX_RESET_BIT; 553 outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR); 554 mdelay(10); 555 break; 556 case INF_GAZEL_R685: 557 val = inl((u32)hw->cfg.start + GAZEL_CNTRL); 558 val |= (GAZEL_RESET_9050 + GAZEL_RESET); 559 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL); 560 val &= ~(GAZEL_RESET_9050 + GAZEL_RESET); 561 mdelay(4); 562 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL); 563 mdelay(10); 564 hw->ipac.isac.adf2 = 0x87; 565 hw->ipac.hscx[0].slot = 0x1f; 566 hw->ipac.hscx[1].slot = 0x23; 567 break; 568 case INF_GAZEL_R753: 569 val = inl((u32)hw->cfg.start + GAZEL_CNTRL); 570 val |= (GAZEL_RESET_9050 + GAZEL_RESET); 571 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL); 572 val &= ~(GAZEL_RESET_9050 + GAZEL_RESET); 573 mdelay(4); 574 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL); 575 mdelay(10); 576 ipac_chip_reset(hw); 577 hw->ipac.write_reg(hw, IPAC_ACFG, 0xff); 578 hw->ipac.write_reg(hw, IPAC_AOE, 0x00); 579 hw->ipac.conf = 0x01; /* IOM off */ 580 break; 581 default: 582 return; 583 } 584 enable_hwirq(hw); 585 } 586 587 static int 588 inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg) 589 { 590 int ret = 0; 591 592 switch (cmd) { 593 case HW_RESET_REQ: 594 reset_inf(hw); 595 break; 596 default: 597 pr_info("%s: %s unknown command %x %lx\n", 598 hw->name, __func__, cmd, arg); 599 ret = -EINVAL; 600 break; 601 } 602 return ret; 603 } 604 605 static int __devinit 606 init_irq(struct inf_hw *hw) 607 { 608 int ret, cnt = 3; 609 u_long flags; 610 611 if (!hw->ci->irqfunc) 612 return -EINVAL; 613 ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw); 614 if (ret) { 615 pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq); 616 return ret; 617 } 618 while (cnt--) { 619 spin_lock_irqsave(&hw->lock, flags); 620 reset_inf(hw); 621 ret = hw->ipac.init(&hw->ipac); 622 if (ret) { 623 spin_unlock_irqrestore(&hw->lock, flags); 624 pr_info("%s: ISAC init failed with %d\n", 625 hw->name, ret); 626 break; 627 } 628 spin_unlock_irqrestore(&hw->lock, flags); 629 msleep_interruptible(10); 630 if (debug & DEBUG_HW) 631 pr_notice("%s: IRQ %d count %d\n", hw->name, 632 hw->irq, hw->irqcnt); 633 if (!hw->irqcnt) { 634 pr_info("%s: IRQ(%d) got no requests during init %d\n", 635 hw->name, hw->irq, 3 - cnt); 636 } else 637 return 0; 638 } 639 free_irq(hw->irq, hw); 640 return -EIO; 641 } 642 643 static void 644 release_io(struct inf_hw *hw) 645 { 646 if (hw->cfg.mode) { 647 if (hw->cfg.p) { 648 release_mem_region(hw->cfg.start, hw->cfg.size); 649 iounmap(hw->cfg.p); 650 } else 651 release_region(hw->cfg.start, hw->cfg.size); 652 hw->cfg.mode = AM_NONE; 653 } 654 if (hw->addr.mode) { 655 if (hw->addr.p) { 656 release_mem_region(hw->addr.start, hw->addr.size); 657 iounmap(hw->addr.p); 658 } else 659 release_region(hw->addr.start, hw->addr.size); 660 hw->addr.mode = AM_NONE; 661 } 662 } 663 664 static int __devinit 665 setup_io(struct inf_hw *hw) 666 { 667 int err = 0; 668 669 if (hw->ci->cfg_mode) { 670 hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar); 671 hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar); 672 if (hw->ci->cfg_mode == AM_MEMIO) { 673 if (!request_mem_region(hw->cfg.start, hw->cfg.size, 674 hw->name)) 675 err = -EBUSY; 676 } else { 677 if (!request_region(hw->cfg.start, hw->cfg.size, 678 hw->name)) 679 err = -EBUSY; 680 } 681 if (err) { 682 pr_info("mISDN: %s config port %lx (%lu bytes)" 683 "already in use\n", hw->name, 684 (ulong)hw->cfg.start, (ulong)hw->cfg.size); 685 return err; 686 } 687 if (hw->ci->cfg_mode == AM_MEMIO) 688 hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size); 689 hw->cfg.mode = hw->ci->cfg_mode; 690 if (debug & DEBUG_HW) 691 pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n", 692 hw->name, (ulong)hw->cfg.start, 693 (ulong)hw->cfg.size, hw->ci->cfg_mode); 694 695 } 696 if (hw->ci->addr_mode) { 697 hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar); 698 hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar); 699 if (hw->ci->addr_mode == AM_MEMIO) { 700 if (!request_mem_region(hw->addr.start, hw->addr.size, 701 hw->name)) 702 err = -EBUSY; 703 } else { 704 if (!request_region(hw->addr.start, hw->addr.size, 705 hw->name)) 706 err = -EBUSY; 707 } 708 if (err) { 709 pr_info("mISDN: %s address port %lx (%lu bytes)" 710 "already in use\n", hw->name, 711 (ulong)hw->addr.start, (ulong)hw->addr.size); 712 return err; 713 } 714 if (hw->ci->addr_mode == AM_MEMIO) 715 hw->addr.p = ioremap(hw->addr.start, hw->addr.size); 716 hw->addr.mode = hw->ci->addr_mode; 717 if (debug & DEBUG_HW) 718 pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n", 719 hw->name, (ulong)hw->addr.start, 720 (ulong)hw->addr.size, hw->ci->addr_mode); 721 722 } 723 724 switch (hw->ci->typ) { 725 case INF_DIVA20: 726 case INF_DIVA20U: 727 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX; 728 hw->isac.mode = hw->cfg.mode; 729 hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE; 730 hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT; 731 hw->hscx.mode = hw->cfg.mode; 732 hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE; 733 hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT; 734 break; 735 case INF_DIVA201: 736 hw->ipac.type = IPAC_TYPE_IPAC; 737 hw->ipac.isac.off = 0x80; 738 hw->isac.mode = hw->addr.mode; 739 hw->isac.a.p = hw->addr.p; 740 hw->hscx.mode = hw->addr.mode; 741 hw->hscx.a.p = hw->addr.p; 742 break; 743 case INF_DIVA202: 744 hw->ipac.type = IPAC_TYPE_IPACX; 745 hw->isac.mode = hw->addr.mode; 746 hw->isac.a.p = hw->addr.p; 747 hw->hscx.mode = hw->addr.mode; 748 hw->hscx.a.p = hw->addr.p; 749 break; 750 case INF_SPEEDWIN: 751 case INF_SAPHIR3: 752 hw->ipac.type = IPAC_TYPE_IPAC; 753 hw->ipac.isac.off = 0x80; 754 hw->isac.mode = hw->cfg.mode; 755 hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE; 756 hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT; 757 hw->hscx.mode = hw->cfg.mode; 758 hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE; 759 hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT; 760 outb(0xff, (ulong)hw->cfg.start); 761 mdelay(1); 762 outb(0x00, (ulong)hw->cfg.start); 763 mdelay(1); 764 outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL); 765 break; 766 case INF_QS1000: 767 case INF_QS3000: 768 hw->ipac.type = IPAC_TYPE_IPAC; 769 hw->ipac.isac.off = 0x80; 770 hw->isac.a.io.ale = (u32)hw->addr.start; 771 hw->isac.a.io.port = (u32)hw->addr.start + 1; 772 hw->isac.mode = hw->addr.mode; 773 hw->hscx.a.io.ale = (u32)hw->addr.start; 774 hw->hscx.a.io.port = (u32)hw->addr.start + 1; 775 hw->hscx.mode = hw->addr.mode; 776 break; 777 case INF_NICCY: 778 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX; 779 hw->isac.mode = hw->addr.mode; 780 hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE; 781 hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT; 782 hw->hscx.mode = hw->addr.mode; 783 hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE; 784 hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT; 785 break; 786 case INF_SCT_1: 787 hw->ipac.type = IPAC_TYPE_IPAC; 788 hw->ipac.isac.off = 0x80; 789 hw->isac.a.io.ale = (u32)hw->addr.start; 790 hw->isac.a.io.port = hw->isac.a.io.ale + 4; 791 hw->isac.mode = hw->addr.mode; 792 hw->hscx.a.io.ale = hw->isac.a.io.ale; 793 hw->hscx.a.io.port = hw->isac.a.io.port; 794 hw->hscx.mode = hw->addr.mode; 795 break; 796 case INF_SCT_2: 797 hw->ipac.type = IPAC_TYPE_IPAC; 798 hw->ipac.isac.off = 0x80; 799 hw->isac.a.io.ale = (u32)hw->addr.start + 0x08; 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_3: 807 hw->ipac.type = IPAC_TYPE_IPAC; 808 hw->ipac.isac.off = 0x80; 809 hw->isac.a.io.ale = (u32)hw->addr.start + 0x10; 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_4: 817 hw->ipac.type = IPAC_TYPE_IPAC; 818 hw->ipac.isac.off = 0x80; 819 hw->isac.a.io.ale = (u32)hw->addr.start + 0x20; 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_GAZEL_R685: 827 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX; 828 hw->ipac.isac.off = 0x80; 829 hw->isac.mode = hw->addr.mode; 830 hw->isac.a.io.port = (u32)hw->addr.start; 831 hw->hscx.mode = hw->addr.mode; 832 hw->hscx.a.io.port = hw->isac.a.io.port; 833 break; 834 case INF_GAZEL_R753: 835 hw->ipac.type = IPAC_TYPE_IPAC; 836 hw->ipac.isac.off = 0x80; 837 hw->isac.mode = hw->addr.mode; 838 hw->isac.a.io.ale = (u32)hw->addr.start; 839 hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT; 840 hw->hscx.mode = hw->addr.mode; 841 hw->hscx.a.io.ale = hw->isac.a.io.ale; 842 hw->hscx.a.io.port = hw->isac.a.io.port; 843 break; 844 default: 845 return -EINVAL; 846 } 847 switch (hw->isac.mode) { 848 case AM_MEMIO: 849 ASSIGN_FUNC_IPAC(MIO, hw->ipac); 850 break; 851 case AM_IND_IO: 852 ASSIGN_FUNC_IPAC(IND, hw->ipac); 853 break; 854 case AM_IO: 855 ASSIGN_FUNC_IPAC(IO, hw->ipac); 856 break; 857 default: 858 return -EINVAL; 859 } 860 return 0; 861 } 862 863 static void 864 release_card(struct inf_hw *card) { 865 ulong flags; 866 int i; 867 868 spin_lock_irqsave(&card->lock, flags); 869 disable_hwirq(card); 870 spin_unlock_irqrestore(&card->lock, flags); 871 card->ipac.isac.release(&card->ipac.isac); 872 free_irq(card->irq, card); 873 mISDN_unregister_device(&card->ipac.isac.dch.dev); 874 release_io(card); 875 write_lock_irqsave(&card_lock, flags); 876 list_del(&card->list); 877 write_unlock_irqrestore(&card_lock, flags); 878 switch (card->ci->typ) { 879 case INF_SCT_2: 880 case INF_SCT_3: 881 case INF_SCT_4: 882 break; 883 case INF_SCT_1: 884 for (i = 0; i < 3; i++) { 885 if (card->sc[i]) 886 release_card(card->sc[i]); 887 card->sc[i] = NULL; 888 } 889 default: 890 pci_disable_device(card->pdev); 891 pci_set_drvdata(card->pdev, NULL); 892 break; 893 } 894 kfree(card); 895 inf_cnt--; 896 } 897 898 static int __devinit 899 setup_instance(struct inf_hw *card) 900 { 901 int err; 902 ulong flags; 903 904 snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name, 905 inf_cnt + 1); 906 write_lock_irqsave(&card_lock, flags); 907 list_add_tail(&card->list, &Cards); 908 write_unlock_irqrestore(&card_lock, flags); 909 910 _set_debug(card); 911 card->ipac.isac.name = card->name; 912 card->ipac.name = card->name; 913 card->ipac.owner = THIS_MODULE; 914 spin_lock_init(&card->lock); 915 card->ipac.isac.hwlock = &card->lock; 916 card->ipac.hwlock = &card->lock; 917 card->ipac.ctrl = (void *)&inf_ctrl; 918 919 err = setup_io(card); 920 if (err) 921 goto error_setup; 922 923 card->ipac.isac.dch.dev.Bprotocols = 924 mISDNipac_init(&card->ipac, card); 925 926 if (card->ipac.isac.dch.dev.Bprotocols == 0) 927 goto error_setup;; 928 929 err = mISDN_register_device(&card->ipac.isac.dch.dev, 930 &card->pdev->dev, card->name); 931 if (err) 932 goto error; 933 934 err = init_irq(card); 935 if (!err) { 936 inf_cnt++; 937 pr_notice("Infineon %d cards installed\n", inf_cnt); 938 return 0; 939 } 940 mISDN_unregister_device(&card->ipac.isac.dch.dev); 941 error: 942 card->ipac.release(&card->ipac); 943 error_setup: 944 release_io(card); 945 write_lock_irqsave(&card_lock, flags); 946 list_del(&card->list); 947 write_unlock_irqrestore(&card_lock, flags); 948 return err; 949 } 950 951 static const struct inf_cinfo inf_card_info[] = { 952 { 953 INF_DIVA20, 954 "Dialogic Diva 2.0", 955 "diva20", 956 AM_IND_IO, AM_NONE, 2, 0, 957 &diva_irq 958 }, 959 { 960 INF_DIVA20U, 961 "Dialogic Diva 2.0U", 962 "diva20U", 963 AM_IND_IO, AM_NONE, 2, 0, 964 &diva_irq 965 }, 966 { 967 INF_DIVA201, 968 "Dialogic Diva 2.01", 969 "diva201", 970 AM_MEMIO, AM_MEMIO, 0, 1, 971 &diva20x_irq 972 }, 973 { 974 INF_DIVA202, 975 "Dialogic Diva 2.02", 976 "diva202", 977 AM_MEMIO, AM_MEMIO, 0, 1, 978 &diva20x_irq 979 }, 980 { 981 INF_SPEEDWIN, 982 "Sedlbauer SpeedWin PCI", 983 "speedwin", 984 AM_IND_IO, AM_NONE, 0, 0, 985 &tiger_irq 986 }, 987 { 988 INF_SAPHIR3, 989 "HST Saphir 3", 990 "saphir", 991 AM_IND_IO, AM_NONE, 0, 0, 992 &tiger_irq 993 }, 994 { 995 INF_QS1000, 996 "Develo Microlink PCI", 997 "qs1000", 998 AM_IO, AM_IND_IO, 1, 3, 999 &elsa_irq 1000 }, 1001 { 1002 INF_QS3000, 1003 "Develo QuickStep 3000", 1004 "qs3000", 1005 AM_IO, AM_IND_IO, 1, 3, 1006 &elsa_irq 1007 }, 1008 { 1009 INF_NICCY, 1010 "Sagem NICCY", 1011 "niccy", 1012 AM_IO, AM_IND_IO, 0, 1, 1013 &niccy_irq 1014 }, 1015 { 1016 INF_SCT_1, 1017 "SciTel Quadro", 1018 "p1_scitel", 1019 AM_IO, AM_IND_IO, 1, 5, 1020 &ipac_irq 1021 }, 1022 { 1023 INF_SCT_2, 1024 "SciTel Quadro", 1025 "p2_scitel", 1026 AM_NONE, AM_IND_IO, 0, 4, 1027 &ipac_irq 1028 }, 1029 { 1030 INF_SCT_3, 1031 "SciTel Quadro", 1032 "p3_scitel", 1033 AM_NONE, AM_IND_IO, 0, 3, 1034 &ipac_irq 1035 }, 1036 { 1037 INF_SCT_4, 1038 "SciTel Quadro", 1039 "p4_scitel", 1040 AM_NONE, AM_IND_IO, 0, 2, 1041 &ipac_irq 1042 }, 1043 { 1044 INF_GAZEL_R685, 1045 "Gazel R685", 1046 "gazel685", 1047 AM_IO, AM_IO, 1, 2, 1048 &gazel_irq 1049 }, 1050 { 1051 INF_GAZEL_R753, 1052 "Gazel R753", 1053 "gazel753", 1054 AM_IO, AM_IND_IO, 1, 2, 1055 &ipac_irq 1056 }, 1057 { 1058 INF_NONE, 1059 } 1060 }; 1061 1062 static const struct inf_cinfo * __devinit 1063 get_card_info(enum inf_types typ) 1064 { 1065 const struct inf_cinfo *ci = inf_card_info; 1066 1067 while (ci->typ != INF_NONE) { 1068 if (ci->typ == typ) 1069 return ci; 1070 ci++; 1071 } 1072 return NULL; 1073 } 1074 1075 static int __devinit 1076 inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 1077 { 1078 int err = -ENOMEM; 1079 struct inf_hw *card; 1080 1081 card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL); 1082 if (!card) { 1083 pr_info("No memory for Infineon ISDN card\n"); 1084 return err; 1085 } 1086 card->pdev = pdev; 1087 err = pci_enable_device(pdev); 1088 if (err) { 1089 kfree(card); 1090 return err; 1091 } 1092 card->ci = get_card_info(ent->driver_data); 1093 if (!card->ci) { 1094 pr_info("mISDN: do not have informations about adapter at %s\n", 1095 pci_name(pdev)); 1096 kfree(card); 1097 pci_disable_device(pdev); 1098 return -EINVAL; 1099 } else 1100 pr_notice("mISDN: found adapter %s at %s\n", 1101 card->ci->full, pci_name(pdev)); 1102 1103 card->irq = pdev->irq; 1104 pci_set_drvdata(pdev, card); 1105 err = setup_instance(card); 1106 if (err) { 1107 pci_disable_device(pdev); 1108 kfree(card); 1109 pci_set_drvdata(pdev, NULL); 1110 } else if (ent->driver_data == INF_SCT_1) { 1111 int i; 1112 struct inf_hw *sc; 1113 1114 for (i = 1; i < 4; i++) { 1115 sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL); 1116 if (!sc) { 1117 release_card(card); 1118 pci_disable_device(pdev); 1119 return -ENOMEM; 1120 } 1121 sc->irq = card->irq; 1122 sc->pdev = card->pdev; 1123 sc->ci = card->ci + i; 1124 err = setup_instance(sc); 1125 if (err) { 1126 pci_disable_device(pdev); 1127 kfree(sc); 1128 release_card(card); 1129 break; 1130 } else 1131 card->sc[i - 1] = sc; 1132 } 1133 } 1134 return err; 1135 } 1136 1137 static void __devexit 1138 inf_remove(struct pci_dev *pdev) 1139 { 1140 struct inf_hw *card = pci_get_drvdata(pdev); 1141 1142 if (card) 1143 release_card(card); 1144 else 1145 pr_debug("%s: drvdata already removed\n", __func__); 1146 } 1147 1148 static struct pci_driver infineon_driver = { 1149 .name = "ISDN Infineon pci", 1150 .probe = inf_probe, 1151 .remove = __devexit_p(inf_remove), 1152 .id_table = infineon_ids, 1153 }; 1154 1155 static int __init 1156 infineon_init(void) 1157 { 1158 int err; 1159 1160 pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV); 1161 err = pci_register_driver(&infineon_driver); 1162 return err; 1163 } 1164 1165 static void __exit 1166 infineon_cleanup(void) 1167 { 1168 pci_unregister_driver(&infineon_driver); 1169 } 1170 1171 module_init(infineon_init); 1172 module_exit(infineon_cleanup); 1173