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/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 { 56 INF_NONE, 57 INF_DIVA20, 58 INF_DIVA20U, 59 INF_DIVA201, 60 INF_DIVA202, 61 INF_SPEEDWIN, 62 INF_SAPHIR3, 63 INF_QS1000, 64 INF_QS3000, 65 INF_NICCY, 66 INF_SCT_1, 67 INF_SCT_2, 68 INF_SCT_3, 69 INF_SCT_4, 70 INF_GAZEL_R685, 71 INF_GAZEL_R753 72 }; 73 74 enum addr_mode { 75 AM_NONE = 0, 76 AM_IO, 77 AM_MEMIO, 78 AM_IND_IO, 79 }; 80 81 struct inf_cinfo { 82 enum inf_types typ; 83 const char *full; 84 const char *name; 85 enum addr_mode cfg_mode; 86 enum addr_mode addr_mode; 87 u8 cfg_bar; 88 u8 addr_bar; 89 void *irqfunc; 90 }; 91 92 struct _ioaddr { 93 enum addr_mode mode; 94 union { 95 void __iomem *p; 96 struct _ioport io; 97 } a; 98 }; 99 100 struct _iohandle { 101 enum addr_mode mode; 102 resource_size_t size; 103 resource_size_t start; 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; 111 char name[MISDN_MAX_IDLEN]; 112 u32 irq; 113 u32 irqcnt; 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[] = { 129 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), INF_DIVA20 }, 130 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), INF_DIVA20U }, 131 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), INF_DIVA201 }, 132 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), INF_DIVA202 }, 133 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, 134 PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0, 135 INF_SPEEDWIN }, 136 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, 137 PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3 }, 138 { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK), INF_QS1000 }, 139 { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000), INF_QS3000 }, 140 { PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY), INF_NICCY }, 141 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, 142 PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0, 143 INF_SCT_1 }, 144 { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685), INF_GAZEL_R685 }, 145 { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753), INF_GAZEL_R753 }, 146 { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO), INF_GAZEL_R753 }, 147 { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC), INF_GAZEL_R753 }, 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, const 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"); 264 MODULE_VERSION(INFINEON_REV); 265 module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR); 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; 375 irqreturn_t ret; 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: 433 outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN, 434 (u32)hw->cfg.start + GAZEL_INCSR); 435 break; 436 case INF_GAZEL_R753: 437 outb(GAZEL_IPAC_EN + GAZEL_PCI_EN, 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); 513 outb(DIVA_RESET_BIT | DIVA_LED_A, 514 (u32)hw->cfg.start + DIVA_PCI_CTRL); 515 break; 516 case INF_DIVA201: 517 writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE, 518 hw->cfg.p + PITA_MISC_REG); 519 mdelay(1); 520 writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG); 521 mdelay(10); 522 break; 523 case INF_DIVA202: 524 writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE, 525 hw->cfg.p + PITA_MISC_REG); 526 mdelay(1); 527 writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET, 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 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); 630 msleep_interruptible(10); 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 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 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 { 1045 INF_GAZEL_R685, 1046 "Gazel R685", 1047 "gazel685", 1048 AM_IO, AM_IO, 1, 2, 1049 &gazel_irq 1050 }, 1051 { 1052 INF_GAZEL_R753, 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 * 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 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 information 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 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 = 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); 1174