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