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 if (unlikely(!hw->addr.p)) 718 return -ENOMEM; 719 } 720 hw->addr.mode = hw->ci->addr_mode; 721 if (debug & DEBUG_HW) 722 pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n", 723 hw->name, (ulong)hw->addr.start, 724 (ulong)hw->addr.size, hw->ci->addr_mode); 725 726 } 727 728 switch (hw->ci->typ) { 729 case INF_DIVA20: 730 case INF_DIVA20U: 731 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX; 732 hw->isac.mode = hw->cfg.mode; 733 hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE; 734 hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT; 735 hw->hscx.mode = hw->cfg.mode; 736 hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE; 737 hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT; 738 break; 739 case INF_DIVA201: 740 hw->ipac.type = IPAC_TYPE_IPAC; 741 hw->ipac.isac.off = 0x80; 742 hw->isac.mode = hw->addr.mode; 743 hw->isac.a.p = hw->addr.p; 744 hw->hscx.mode = hw->addr.mode; 745 hw->hscx.a.p = hw->addr.p; 746 break; 747 case INF_DIVA202: 748 hw->ipac.type = IPAC_TYPE_IPACX; 749 hw->isac.mode = hw->addr.mode; 750 hw->isac.a.p = hw->addr.p; 751 hw->hscx.mode = hw->addr.mode; 752 hw->hscx.a.p = hw->addr.p; 753 break; 754 case INF_SPEEDWIN: 755 case INF_SAPHIR3: 756 hw->ipac.type = IPAC_TYPE_IPAC; 757 hw->ipac.isac.off = 0x80; 758 hw->isac.mode = hw->cfg.mode; 759 hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE; 760 hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT; 761 hw->hscx.mode = hw->cfg.mode; 762 hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE; 763 hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT; 764 outb(0xff, (ulong)hw->cfg.start); 765 mdelay(1); 766 outb(0x00, (ulong)hw->cfg.start); 767 mdelay(1); 768 outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL); 769 break; 770 case INF_QS1000: 771 case INF_QS3000: 772 hw->ipac.type = IPAC_TYPE_IPAC; 773 hw->ipac.isac.off = 0x80; 774 hw->isac.a.io.ale = (u32)hw->addr.start; 775 hw->isac.a.io.port = (u32)hw->addr.start + 1; 776 hw->isac.mode = hw->addr.mode; 777 hw->hscx.a.io.ale = (u32)hw->addr.start; 778 hw->hscx.a.io.port = (u32)hw->addr.start + 1; 779 hw->hscx.mode = hw->addr.mode; 780 break; 781 case INF_NICCY: 782 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX; 783 hw->isac.mode = hw->addr.mode; 784 hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE; 785 hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT; 786 hw->hscx.mode = hw->addr.mode; 787 hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE; 788 hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT; 789 break; 790 case INF_SCT_1: 791 hw->ipac.type = IPAC_TYPE_IPAC; 792 hw->ipac.isac.off = 0x80; 793 hw->isac.a.io.ale = (u32)hw->addr.start; 794 hw->isac.a.io.port = hw->isac.a.io.ale + 4; 795 hw->isac.mode = hw->addr.mode; 796 hw->hscx.a.io.ale = hw->isac.a.io.ale; 797 hw->hscx.a.io.port = hw->isac.a.io.port; 798 hw->hscx.mode = hw->addr.mode; 799 break; 800 case INF_SCT_2: 801 hw->ipac.type = IPAC_TYPE_IPAC; 802 hw->ipac.isac.off = 0x80; 803 hw->isac.a.io.ale = (u32)hw->addr.start + 0x08; 804 hw->isac.a.io.port = hw->isac.a.io.ale + 4; 805 hw->isac.mode = hw->addr.mode; 806 hw->hscx.a.io.ale = hw->isac.a.io.ale; 807 hw->hscx.a.io.port = hw->isac.a.io.port; 808 hw->hscx.mode = hw->addr.mode; 809 break; 810 case INF_SCT_3: 811 hw->ipac.type = IPAC_TYPE_IPAC; 812 hw->ipac.isac.off = 0x80; 813 hw->isac.a.io.ale = (u32)hw->addr.start + 0x10; 814 hw->isac.a.io.port = hw->isac.a.io.ale + 4; 815 hw->isac.mode = hw->addr.mode; 816 hw->hscx.a.io.ale = hw->isac.a.io.ale; 817 hw->hscx.a.io.port = hw->isac.a.io.port; 818 hw->hscx.mode = hw->addr.mode; 819 break; 820 case INF_SCT_4: 821 hw->ipac.type = IPAC_TYPE_IPAC; 822 hw->ipac.isac.off = 0x80; 823 hw->isac.a.io.ale = (u32)hw->addr.start + 0x20; 824 hw->isac.a.io.port = hw->isac.a.io.ale + 4; 825 hw->isac.mode = hw->addr.mode; 826 hw->hscx.a.io.ale = hw->isac.a.io.ale; 827 hw->hscx.a.io.port = hw->isac.a.io.port; 828 hw->hscx.mode = hw->addr.mode; 829 break; 830 case INF_GAZEL_R685: 831 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX; 832 hw->ipac.isac.off = 0x80; 833 hw->isac.mode = hw->addr.mode; 834 hw->isac.a.io.port = (u32)hw->addr.start; 835 hw->hscx.mode = hw->addr.mode; 836 hw->hscx.a.io.port = hw->isac.a.io.port; 837 break; 838 case INF_GAZEL_R753: 839 hw->ipac.type = IPAC_TYPE_IPAC; 840 hw->ipac.isac.off = 0x80; 841 hw->isac.mode = hw->addr.mode; 842 hw->isac.a.io.ale = (u32)hw->addr.start; 843 hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT; 844 hw->hscx.mode = hw->addr.mode; 845 hw->hscx.a.io.ale = hw->isac.a.io.ale; 846 hw->hscx.a.io.port = hw->isac.a.io.port; 847 break; 848 default: 849 return -EINVAL; 850 } 851 switch (hw->isac.mode) { 852 case AM_MEMIO: 853 ASSIGN_FUNC_IPAC(MIO, hw->ipac); 854 break; 855 case AM_IND_IO: 856 ASSIGN_FUNC_IPAC(IND, hw->ipac); 857 break; 858 case AM_IO: 859 ASSIGN_FUNC_IPAC(IO, hw->ipac); 860 break; 861 default: 862 return -EINVAL; 863 } 864 return 0; 865 } 866 867 static void 868 release_card(struct inf_hw *card) { 869 ulong flags; 870 int i; 871 872 spin_lock_irqsave(&card->lock, flags); 873 disable_hwirq(card); 874 spin_unlock_irqrestore(&card->lock, flags); 875 card->ipac.isac.release(&card->ipac.isac); 876 free_irq(card->irq, card); 877 mISDN_unregister_device(&card->ipac.isac.dch.dev); 878 release_io(card); 879 write_lock_irqsave(&card_lock, flags); 880 list_del(&card->list); 881 write_unlock_irqrestore(&card_lock, flags); 882 switch (card->ci->typ) { 883 case INF_SCT_2: 884 case INF_SCT_3: 885 case INF_SCT_4: 886 break; 887 case INF_SCT_1: 888 for (i = 0; i < 3; i++) { 889 if (card->sc[i]) 890 release_card(card->sc[i]); 891 card->sc[i] = NULL; 892 } 893 /* fall through */ 894 default: 895 pci_disable_device(card->pdev); 896 pci_set_drvdata(card->pdev, NULL); 897 break; 898 } 899 kfree(card); 900 inf_cnt--; 901 } 902 903 static int 904 setup_instance(struct inf_hw *card) 905 { 906 int err; 907 ulong flags; 908 909 snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name, 910 inf_cnt + 1); 911 write_lock_irqsave(&card_lock, flags); 912 list_add_tail(&card->list, &Cards); 913 write_unlock_irqrestore(&card_lock, flags); 914 915 _set_debug(card); 916 card->ipac.isac.name = card->name; 917 card->ipac.name = card->name; 918 card->ipac.owner = THIS_MODULE; 919 spin_lock_init(&card->lock); 920 card->ipac.isac.hwlock = &card->lock; 921 card->ipac.hwlock = &card->lock; 922 card->ipac.ctrl = (void *)&inf_ctrl; 923 924 err = setup_io(card); 925 if (err) 926 goto error_setup; 927 928 card->ipac.isac.dch.dev.Bprotocols = 929 mISDNipac_init(&card->ipac, card); 930 931 if (card->ipac.isac.dch.dev.Bprotocols == 0) 932 goto error_setup; 933 934 err = mISDN_register_device(&card->ipac.isac.dch.dev, 935 &card->pdev->dev, card->name); 936 if (err) 937 goto error; 938 939 err = init_irq(card); 940 if (!err) { 941 inf_cnt++; 942 pr_notice("Infineon %d cards installed\n", inf_cnt); 943 return 0; 944 } 945 mISDN_unregister_device(&card->ipac.isac.dch.dev); 946 error: 947 card->ipac.release(&card->ipac); 948 error_setup: 949 release_io(card); 950 write_lock_irqsave(&card_lock, flags); 951 list_del(&card->list); 952 write_unlock_irqrestore(&card_lock, flags); 953 return err; 954 } 955 956 static const struct inf_cinfo inf_card_info[] = { 957 { 958 INF_DIVA20, 959 "Dialogic Diva 2.0", 960 "diva20", 961 AM_IND_IO, AM_NONE, 2, 0, 962 &diva_irq 963 }, 964 { 965 INF_DIVA20U, 966 "Dialogic Diva 2.0U", 967 "diva20U", 968 AM_IND_IO, AM_NONE, 2, 0, 969 &diva_irq 970 }, 971 { 972 INF_DIVA201, 973 "Dialogic Diva 2.01", 974 "diva201", 975 AM_MEMIO, AM_MEMIO, 0, 1, 976 &diva20x_irq 977 }, 978 { 979 INF_DIVA202, 980 "Dialogic Diva 2.02", 981 "diva202", 982 AM_MEMIO, AM_MEMIO, 0, 1, 983 &diva20x_irq 984 }, 985 { 986 INF_SPEEDWIN, 987 "Sedlbauer SpeedWin PCI", 988 "speedwin", 989 AM_IND_IO, AM_NONE, 0, 0, 990 &tiger_irq 991 }, 992 { 993 INF_SAPHIR3, 994 "HST Saphir 3", 995 "saphir", 996 AM_IND_IO, AM_NONE, 0, 0, 997 &tiger_irq 998 }, 999 { 1000 INF_QS1000, 1001 "Develo Microlink PCI", 1002 "qs1000", 1003 AM_IO, AM_IND_IO, 1, 3, 1004 &elsa_irq 1005 }, 1006 { 1007 INF_QS3000, 1008 "Develo QuickStep 3000", 1009 "qs3000", 1010 AM_IO, AM_IND_IO, 1, 3, 1011 &elsa_irq 1012 }, 1013 { 1014 INF_NICCY, 1015 "Sagem NICCY", 1016 "niccy", 1017 AM_IO, AM_IND_IO, 0, 1, 1018 &niccy_irq 1019 }, 1020 { 1021 INF_SCT_1, 1022 "SciTel Quadro", 1023 "p1_scitel", 1024 AM_IO, AM_IND_IO, 1, 5, 1025 &ipac_irq 1026 }, 1027 { 1028 INF_SCT_2, 1029 "SciTel Quadro", 1030 "p2_scitel", 1031 AM_NONE, AM_IND_IO, 0, 4, 1032 &ipac_irq 1033 }, 1034 { 1035 INF_SCT_3, 1036 "SciTel Quadro", 1037 "p3_scitel", 1038 AM_NONE, AM_IND_IO, 0, 3, 1039 &ipac_irq 1040 }, 1041 { 1042 INF_SCT_4, 1043 "SciTel Quadro", 1044 "p4_scitel", 1045 AM_NONE, AM_IND_IO, 0, 2, 1046 &ipac_irq 1047 }, 1048 { 1049 INF_GAZEL_R685, 1050 "Gazel R685", 1051 "gazel685", 1052 AM_IO, AM_IO, 1, 2, 1053 &gazel_irq 1054 }, 1055 { 1056 INF_GAZEL_R753, 1057 "Gazel R753", 1058 "gazel753", 1059 AM_IO, AM_IND_IO, 1, 2, 1060 &ipac_irq 1061 }, 1062 { 1063 INF_NONE, 1064 } 1065 }; 1066 1067 static const struct inf_cinfo * 1068 get_card_info(enum inf_types typ) 1069 { 1070 const struct inf_cinfo *ci = inf_card_info; 1071 1072 while (ci->typ != INF_NONE) { 1073 if (ci->typ == typ) 1074 return ci; 1075 ci++; 1076 } 1077 return NULL; 1078 } 1079 1080 static int 1081 inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 1082 { 1083 int err = -ENOMEM; 1084 struct inf_hw *card; 1085 1086 card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL); 1087 if (!card) { 1088 pr_info("No memory for Infineon ISDN card\n"); 1089 return err; 1090 } 1091 card->pdev = pdev; 1092 err = pci_enable_device(pdev); 1093 if (err) { 1094 kfree(card); 1095 return err; 1096 } 1097 card->ci = get_card_info(ent->driver_data); 1098 if (!card->ci) { 1099 pr_info("mISDN: do not have information about adapter at %s\n", 1100 pci_name(pdev)); 1101 kfree(card); 1102 pci_disable_device(pdev); 1103 return -EINVAL; 1104 } else 1105 pr_notice("mISDN: found adapter %s at %s\n", 1106 card->ci->full, pci_name(pdev)); 1107 1108 card->irq = pdev->irq; 1109 pci_set_drvdata(pdev, card); 1110 err = setup_instance(card); 1111 if (err) { 1112 pci_disable_device(pdev); 1113 kfree(card); 1114 pci_set_drvdata(pdev, NULL); 1115 } else if (ent->driver_data == INF_SCT_1) { 1116 int i; 1117 struct inf_hw *sc; 1118 1119 for (i = 1; i < 4; i++) { 1120 sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL); 1121 if (!sc) { 1122 release_card(card); 1123 pci_disable_device(pdev); 1124 return -ENOMEM; 1125 } 1126 sc->irq = card->irq; 1127 sc->pdev = card->pdev; 1128 sc->ci = card->ci + i; 1129 err = setup_instance(sc); 1130 if (err) { 1131 pci_disable_device(pdev); 1132 kfree(sc); 1133 release_card(card); 1134 break; 1135 } else 1136 card->sc[i - 1] = sc; 1137 } 1138 } 1139 return err; 1140 } 1141 1142 static void 1143 inf_remove(struct pci_dev *pdev) 1144 { 1145 struct inf_hw *card = pci_get_drvdata(pdev); 1146 1147 if (card) 1148 release_card(card); 1149 else 1150 pr_debug("%s: drvdata already removed\n", __func__); 1151 } 1152 1153 static struct pci_driver infineon_driver = { 1154 .name = "ISDN Infineon pci", 1155 .probe = inf_probe, 1156 .remove = inf_remove, 1157 .id_table = infineon_ids, 1158 }; 1159 1160 static int __init 1161 infineon_init(void) 1162 { 1163 int err; 1164 1165 pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV); 1166 err = pci_register_driver(&infineon_driver); 1167 return err; 1168 } 1169 1170 static void __exit 1171 infineon_cleanup(void) 1172 { 1173 pci_unregister_driver(&infineon_driver); 1174 } 1175 1176 module_init(infineon_init); 1177 module_exit(infineon_cleanup); 1178