1/* $Id: diva.c,v 1.33.2.6 2004/02/11 13:21:33 keil Exp $ 2 * 3 * low level stuff for Eicon.Diehl Diva Family ISDN cards 4 * 5 * Author Karsten Keil 6 * Copyright by Karsten Keil <keil@isdn4linux.de> 7 * 8 * This software may be used and distributed according to the terms 9 * of the GNU General Public License, incorporated herein by reference. 10 * 11 * For changes and modifications please read 12 * Documentation/isdn/HiSax.cert 13 * 14 * Thanks to Eicon Technology for documents and information 15 * 16 */ 17 18#include <linux/init.h> 19#include "hisax.h" 20#include "isac.h" 21#include "hscx.h" 22#include "ipac.h" 23#include "ipacx.h" 24#include "isdnl1.h" 25#include <linux/pci.h> 26#include <linux/isapnp.h> 27 28static const char *Diva_revision = "$Revision: 1.33.2.6 $"; 29 30#define byteout(addr, val) outb(val, addr) 31#define bytein(addr) inb(addr) 32 33#define DIVA_HSCX_DATA 0 34#define DIVA_HSCX_ADR 4 35#define DIVA_ISA_ISAC_DATA 2 36#define DIVA_ISA_ISAC_ADR 6 37#define DIVA_ISA_CTRL 7 38#define DIVA_IPAC_ADR 0 39#define DIVA_IPAC_DATA 1 40 41#define DIVA_PCI_ISAC_DATA 8 42#define DIVA_PCI_ISAC_ADR 0xc 43#define DIVA_PCI_CTRL 0x10 44 45/* SUB Types */ 46#define DIVA_ISA 1 47#define DIVA_PCI 2 48#define DIVA_IPAC_ISA 3 49#define DIVA_IPAC_PCI 4 50#define DIVA_IPACX_PCI 5 51 52/* CTRL (Read) */ 53#define DIVA_IRQ_STAT 0x01 54#define DIVA_EEPROM_SDA 0x02 55 56/* CTRL (Write) */ 57#define DIVA_IRQ_REQ 0x01 58#define DIVA_RESET 0x08 59#define DIVA_EEPROM_CLK 0x40 60#define DIVA_PCI_LED_A 0x10 61#define DIVA_PCI_LED_B 0x20 62#define DIVA_ISA_LED_A 0x20 63#define DIVA_ISA_LED_B 0x40 64#define DIVA_IRQ_CLR 0x80 65 66/* Siemens PITA */ 67#define PITA_MISC_REG 0x1c 68#ifdef __BIG_ENDIAN 69#define PITA_PARA_SOFTRESET 0x00000001 70#define PITA_SER_SOFTRESET 0x00000002 71#define PITA_PARA_MPX_MODE 0x00000004 72#define PITA_INT0_ENABLE 0x00000200 73#else 74#define PITA_PARA_SOFTRESET 0x01000000 75#define PITA_SER_SOFTRESET 0x02000000 76#define PITA_PARA_MPX_MODE 0x04000000 77#define PITA_INT0_ENABLE 0x00020000 78#endif 79#define PITA_INT0_STATUS 0x02 80 81static inline u_char 82readreg(unsigned int ale, unsigned int adr, u_char off) 83{ 84 register u_char ret; 85 86 byteout(ale, off); 87 ret = bytein(adr); 88 return (ret); 89} 90 91static inline void 92readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) 93{ 94 byteout(ale, off); 95 insb(adr, data, size); 96} 97 98 99static inline void 100writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) 101{ 102 byteout(ale, off); 103 byteout(adr, data); 104} 105 106static inline void 107writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) 108{ 109 byteout(ale, off); 110 outsb(adr, data, size); 111} 112 113static inline u_char 114memreadreg(unsigned long adr, u_char off) 115{ 116 return (*((unsigned char *) 117 (((unsigned int *)adr) + off))); 118} 119 120static inline void 121memwritereg(unsigned long adr, u_char off, u_char data) 122{ 123 register u_char *p; 124 125 p = (unsigned char *)(((unsigned int *)adr) + off); 126 *p = data; 127} 128 129/* Interface functions */ 130 131static u_char 132ReadISAC(struct IsdnCardState *cs, u_char offset) 133{ 134 return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset)); 135} 136 137static void 138WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) 139{ 140 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, value); 141} 142 143static void 144ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) 145{ 146 readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size); 147} 148 149static void 150WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) 151{ 152 writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size); 153} 154 155static u_char 156ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) 157{ 158 return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset + 0x80)); 159} 160 161static void 162WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) 163{ 164 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset | 0x80, value); 165} 166 167static void 168ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) 169{ 170 readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size); 171} 172 173static void 174WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) 175{ 176 writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size); 177} 178 179static u_char 180ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) 181{ 182 return (readreg(cs->hw.diva.hscx_adr, 183 cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0))); 184} 185 186static void 187WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) 188{ 189 writereg(cs->hw.diva.hscx_adr, 190 cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0), value); 191} 192 193static u_char 194MemReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) 195{ 196 return (memreadreg(cs->hw.diva.cfg_reg, offset + 0x80)); 197} 198 199static void 200MemWriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) 201{ 202 memwritereg(cs->hw.diva.cfg_reg, offset | 0x80, value); 203} 204 205static void 206MemReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) 207{ 208 while (size--) 209 *data++ = memreadreg(cs->hw.diva.cfg_reg, 0x80); 210} 211 212static void 213MemWriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) 214{ 215 while (size--) 216 memwritereg(cs->hw.diva.cfg_reg, 0x80, *data++); 217} 218 219static u_char 220MemReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) 221{ 222 return (memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0))); 223} 224 225static void 226MemWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) 227{ 228 memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value); 229} 230 231/* IO-Functions for IPACX type cards */ 232static u_char 233MemReadISAC_IPACX(struct IsdnCardState *cs, u_char offset) 234{ 235 return (memreadreg(cs->hw.diva.cfg_reg, offset)); 236} 237 238static void 239MemWriteISAC_IPACX(struct IsdnCardState *cs, u_char offset, u_char value) 240{ 241 memwritereg(cs->hw.diva.cfg_reg, offset, value); 242} 243 244static void 245MemReadISACfifo_IPACX(struct IsdnCardState *cs, u_char *data, int size) 246{ 247 while (size--) 248 *data++ = memreadreg(cs->hw.diva.cfg_reg, 0); 249} 250 251static void 252MemWriteISACfifo_IPACX(struct IsdnCardState *cs, u_char *data, int size) 253{ 254 while (size--) 255 memwritereg(cs->hw.diva.cfg_reg, 0, *data++); 256} 257 258static u_char 259MemReadHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset) 260{ 261 return (memreadreg(cs->hw.diva.cfg_reg, offset + 262 (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1))); 263} 264 265static void 266MemWriteHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) 267{ 268 memwritereg(cs->hw.diva.cfg_reg, offset + 269 (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value); 270} 271 272/* 273 * fast interrupt HSCX stuff goes here 274 */ 275 276#define READHSCX(cs, nr, reg) readreg(cs->hw.diva.hscx_adr, \ 277 cs->hw.diva.hscx, reg + (nr ? 0x40 : 0)) 278#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.diva.hscx_adr, \ 279 cs->hw.diva.hscx, reg + (nr ? 0x40 : 0), data) 280 281#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.diva.hscx_adr, \ 282 cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt) 283 284#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.diva.hscx_adr, \ 285 cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt) 286 287#include "hscx_irq.c" 288 289static irqreturn_t 290diva_interrupt(int intno, void *dev_id) 291{ 292 struct IsdnCardState *cs = dev_id; 293 u_char val, sval; 294 u_long flags; 295 int cnt = 5; 296 297 spin_lock_irqsave(&cs->lock, flags); 298 while (((sval = bytein(cs->hw.diva.ctrl)) & DIVA_IRQ_REQ) && cnt) { 299 val = readreg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_ISTA + 0x40); 300 if (val) 301 hscx_int_main(cs, val); 302 val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA); 303 if (val) 304 isac_interrupt(cs, val); 305 cnt--; 306 } 307 if (!cnt) 308 printk(KERN_WARNING "Diva: IRQ LOOP\n"); 309 writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0xFF); 310 writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0xFF); 311 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0xFF); 312 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0x0); 313 writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0x0); 314 writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0x0); 315 spin_unlock_irqrestore(&cs->lock, flags); 316 return IRQ_HANDLED; 317} 318 319static irqreturn_t 320diva_irq_ipac_isa(int intno, void *dev_id) 321{ 322 struct IsdnCardState *cs = dev_id; 323 u_char ista, val; 324 u_long flags; 325 int icnt = 5; 326 327 spin_lock_irqsave(&cs->lock, flags); 328 ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA); 329Start_IPACISA: 330 if (cs->debug & L1_DEB_IPAC) 331 debugl1(cs, "IPAC ISTA %02X", ista); 332 if (ista & 0x0f) { 333 val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, HSCX_ISTA + 0x40); 334 if (ista & 0x01) 335 val |= 0x01; 336 if (ista & 0x04) 337 val |= 0x02; 338 if (ista & 0x08) 339 val |= 0x04; 340 if (val) 341 hscx_int_main(cs, val); 342 } 343 if (ista & 0x20) { 344 val = 0xfe & readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA + 0x80); 345 if (val) { 346 isac_interrupt(cs, val); 347 } 348 } 349 if (ista & 0x10) { 350 val = 0x01; 351 isac_interrupt(cs, val); 352 } 353 ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA); 354 if ((ista & 0x3f) && icnt) { 355 icnt--; 356 goto Start_IPACISA; 357 } 358 if (!icnt) 359 printk(KERN_WARNING "DIVA IPAC IRQ LOOP\n"); 360 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xFF); 361 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xC0); 362 spin_unlock_irqrestore(&cs->lock, flags); 363 return IRQ_HANDLED; 364} 365 366static inline void 367MemwaitforCEC(struct IsdnCardState *cs, int hscx) 368{ 369 int to = 50; 370 371 while ((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x04) && to) { 372 udelay(1); 373 to--; 374 } 375 if (!to) 376 printk(KERN_WARNING "HiSax: waitforCEC timeout\n"); 377} 378 379 380static inline void 381MemwaitforXFW(struct IsdnCardState *cs, int hscx) 382{ 383 int to = 50; 384 385 while (((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) { 386 udelay(1); 387 to--; 388 } 389 if (!to) 390 printk(KERN_WARNING "HiSax: waitforXFW timeout\n"); 391} 392 393static inline void 394MemWriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u_char data) 395{ 396 MemwaitforCEC(cs, hscx); 397 MemWriteHSCX(cs, hscx, HSCX_CMDR, data); 398} 399 400static void 401Memhscx_empty_fifo(struct BCState *bcs, int count) 402{ 403 u_char *ptr; 404 struct IsdnCardState *cs = bcs->cs; 405 int cnt; 406 407 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 408 debugl1(cs, "hscx_empty_fifo"); 409 410 if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) { 411 if (cs->debug & L1_DEB_WARN) 412 debugl1(cs, "hscx_empty_fifo: incoming packet too large"); 413 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); 414 bcs->hw.hscx.rcvidx = 0; 415 return; 416 } 417 ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; 418 cnt = count; 419 while (cnt--) 420 *ptr++ = memreadreg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0); 421 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); 422 ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; 423 bcs->hw.hscx.rcvidx += count; 424 if (cs->debug & L1_DEB_HSCX_FIFO) { 425 char *t = bcs->blog; 426 427 t += sprintf(t, "hscx_empty_fifo %c cnt %d", 428 bcs->hw.hscx.hscx ? 'B' : 'A', count); 429 QuickHex(t, ptr, count); 430 debugl1(cs, "%s", bcs->blog); 431 } 432} 433 434static void 435Memhscx_fill_fifo(struct BCState *bcs) 436{ 437 struct IsdnCardState *cs = bcs->cs; 438 int more, count, cnt; 439 int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32; 440 u_char *ptr, *p; 441 442 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 443 debugl1(cs, "hscx_fill_fifo"); 444 445 if (!bcs->tx_skb) 446 return; 447 if (bcs->tx_skb->len <= 0) 448 return; 449 450 more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; 451 if (bcs->tx_skb->len > fifo_size) { 452 more = !0; 453 count = fifo_size; 454 } else 455 count = bcs->tx_skb->len; 456 cnt = count; 457 MemwaitforXFW(cs, bcs->hw.hscx.hscx); 458 p = ptr = bcs->tx_skb->data; 459 skb_pull(bcs->tx_skb, count); 460 bcs->tx_cnt -= count; 461 bcs->hw.hscx.count += count; 462 while (cnt--) 463 memwritereg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0, 464 *p++); 465 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa); 466 if (cs->debug & L1_DEB_HSCX_FIFO) { 467 char *t = bcs->blog; 468 469 t += sprintf(t, "hscx_fill_fifo %c cnt %d", 470 bcs->hw.hscx.hscx ? 'B' : 'A', count); 471 QuickHex(t, ptr, count); 472 debugl1(cs, "%s", bcs->blog); 473 } 474} 475 476static void 477Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx) 478{ 479 u_char r; 480 struct BCState *bcs = cs->bcs + hscx; 481 struct sk_buff *skb; 482 int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32; 483 int count; 484 485 if (!test_bit(BC_FLG_INIT, &bcs->Flag)) 486 return; 487 488 if (val & 0x80) { /* RME */ 489 r = MemReadHSCX(cs, hscx, HSCX_RSTA); 490 if ((r & 0xf0) != 0xa0) { 491 if (!(r & 0x80)) 492 if (cs->debug & L1_DEB_WARN) 493 debugl1(cs, "HSCX invalid frame"); 494 if ((r & 0x40) && bcs->mode) 495 if (cs->debug & L1_DEB_WARN) 496 debugl1(cs, "HSCX RDO mode=%d", 497 bcs->mode); 498 if (!(r & 0x20)) 499 if (cs->debug & L1_DEB_WARN) 500 debugl1(cs, "HSCX CRC error"); 501 MemWriteHSCXCMDR(cs, hscx, 0x80); 502 } else { 503 count = MemReadHSCX(cs, hscx, HSCX_RBCL) & ( 504 test_bit(HW_IPAC, &cs->HW_Flags) ? 0x3f : 0x1f); 505 if (count == 0) 506 count = fifo_size; 507 Memhscx_empty_fifo(bcs, count); 508 if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { 509 if (cs->debug & L1_DEB_HSCX_FIFO) 510 debugl1(cs, "HX Frame %d", count); 511 if (!(skb = dev_alloc_skb(count))) 512 printk(KERN_WARNING "HSCX: receive out of memory\n"); 513 else { 514 memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); 515 skb_queue_tail(&bcs->rqueue, skb); 516 } 517 } 518 } 519 bcs->hw.hscx.rcvidx = 0; 520 schedule_event(bcs, B_RCVBUFREADY); 521 } 522 if (val & 0x40) { /* RPF */ 523 Memhscx_empty_fifo(bcs, fifo_size); 524 if (bcs->mode == L1_MODE_TRANS) { 525 /* receive audio data */ 526 if (!(skb = dev_alloc_skb(fifo_size))) 527 printk(KERN_WARNING "HiSax: receive out of memory\n"); 528 else { 529 memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size); 530 skb_queue_tail(&bcs->rqueue, skb); 531 } 532 bcs->hw.hscx.rcvidx = 0; 533 schedule_event(bcs, B_RCVBUFREADY); 534 } 535 } 536 if (val & 0x10) { /* XPR */ 537 if (bcs->tx_skb) { 538 if (bcs->tx_skb->len) { 539 Memhscx_fill_fifo(bcs); 540 return; 541 } else { 542 if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && 543 (PACKET_NOACK != bcs->tx_skb->pkt_type)) { 544 u_long flags; 545 spin_lock_irqsave(&bcs->aclock, flags); 546 bcs->ackcnt += bcs->hw.hscx.count; 547 spin_unlock_irqrestore(&bcs->aclock, flags); 548 schedule_event(bcs, B_ACKPENDING); 549 } 550 dev_kfree_skb_irq(bcs->tx_skb); 551 bcs->hw.hscx.count = 0; 552 bcs->tx_skb = NULL; 553 } 554 } 555 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { 556 bcs->hw.hscx.count = 0; 557 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 558 Memhscx_fill_fifo(bcs); 559 } else { 560 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 561 schedule_event(bcs, B_XMTBUFREADY); 562 } 563 } 564} 565 566static inline void 567Memhscx_int_main(struct IsdnCardState *cs, u_char val) 568{ 569 570 u_char exval; 571 struct BCState *bcs; 572 573 if (val & 0x01) { // EXB 574 bcs = cs->bcs + 1; 575 exval = MemReadHSCX(cs, 1, HSCX_EXIR); 576 if (exval & 0x40) { 577 if (bcs->mode == 1) 578 Memhscx_fill_fifo(bcs); 579 else { 580 /* Here we lost an TX interrupt, so 581 * restart transmitting the whole frame. 582 */ 583 if (bcs->tx_skb) { 584 skb_push(bcs->tx_skb, bcs->hw.hscx.count); 585 bcs->tx_cnt += bcs->hw.hscx.count; 586 bcs->hw.hscx.count = 0; 587 } 588 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); 589 if (cs->debug & L1_DEB_WARN) 590 debugl1(cs, "HSCX B EXIR %x Lost TX", exval); 591 } 592 } else if (cs->debug & L1_DEB_HSCX) 593 debugl1(cs, "HSCX B EXIR %x", exval); 594 } 595 if (val & 0xf8) { 596 if (cs->debug & L1_DEB_HSCX) 597 debugl1(cs, "HSCX B interrupt %x", val); 598 Memhscx_interrupt(cs, val, 1); 599 } 600 if (val & 0x02) { // EXA 601 bcs = cs->bcs; 602 exval = MemReadHSCX(cs, 0, HSCX_EXIR); 603 if (exval & 0x40) { 604 if (bcs->mode == L1_MODE_TRANS) 605 Memhscx_fill_fifo(bcs); 606 else { 607 /* Here we lost an TX interrupt, so 608 * restart transmitting the whole frame. 609 */ 610 if (bcs->tx_skb) { 611 skb_push(bcs->tx_skb, bcs->hw.hscx.count); 612 bcs->tx_cnt += bcs->hw.hscx.count; 613 bcs->hw.hscx.count = 0; 614 } 615 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); 616 if (cs->debug & L1_DEB_WARN) 617 debugl1(cs, "HSCX A EXIR %x Lost TX", exval); 618 } 619 } else if (cs->debug & L1_DEB_HSCX) 620 debugl1(cs, "HSCX A EXIR %x", exval); 621 } 622 if (val & 0x04) { // ICA 623 exval = MemReadHSCX(cs, 0, HSCX_ISTA); 624 if (cs->debug & L1_DEB_HSCX) 625 debugl1(cs, "HSCX A interrupt %x", exval); 626 Memhscx_interrupt(cs, exval, 0); 627 } 628} 629 630static irqreturn_t 631diva_irq_ipac_pci(int intno, void *dev_id) 632{ 633 struct IsdnCardState *cs = dev_id; 634 u_char ista, val; 635 int icnt = 5; 636 u_char *cfg; 637 u_long flags; 638 639 spin_lock_irqsave(&cs->lock, flags); 640 cfg = (u_char *) cs->hw.diva.pci_cfg; 641 val = *cfg; 642 if (!(val & PITA_INT0_STATUS)) { 643 spin_unlock_irqrestore(&cs->lock, flags); 644 return IRQ_NONE; /* other shared IRQ */ 645 } 646 *cfg = PITA_INT0_STATUS; /* Reset pending INT0 */ 647 ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA); 648Start_IPACPCI: 649 if (cs->debug & L1_DEB_IPAC) 650 debugl1(cs, "IPAC ISTA %02X", ista); 651 if (ista & 0x0f) { 652 val = memreadreg(cs->hw.diva.cfg_reg, HSCX_ISTA + 0x40); 653 if (ista & 0x01) 654 val |= 0x01; 655 if (ista & 0x04) 656 val |= 0x02; 657 if (ista & 0x08) 658 val |= 0x04; 659 if (val) 660 Memhscx_int_main(cs, val); 661 } 662 if (ista & 0x20) { 663 val = 0xfe & memreadreg(cs->hw.diva.cfg_reg, ISAC_ISTA + 0x80); 664 if (val) { 665 isac_interrupt(cs, val); 666 } 667 } 668 if (ista & 0x10) { 669 val = 0x01; 670 isac_interrupt(cs, val); 671 } 672 ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA); 673 if ((ista & 0x3f) && icnt) { 674 icnt--; 675 goto Start_IPACPCI; 676 } 677 if (!icnt) 678 printk(KERN_WARNING "DIVA IPAC PCI IRQ LOOP\n"); 679 memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xFF); 680 memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xC0); 681 spin_unlock_irqrestore(&cs->lock, flags); 682 return IRQ_HANDLED; 683} 684 685static irqreturn_t 686diva_irq_ipacx_pci(int intno, void *dev_id) 687{ 688 struct IsdnCardState *cs = dev_id; 689 u_char val; 690 u_char *cfg; 691 u_long flags; 692 693 spin_lock_irqsave(&cs->lock, flags); 694 cfg = (u_char *) cs->hw.diva.pci_cfg; 695 val = *cfg; 696 if (!(val & PITA_INT0_STATUS)) { 697 spin_unlock_irqrestore(&cs->lock, flags); 698 return IRQ_NONE; // other shared IRQ 699 } 700 interrupt_ipacx(cs); // handler for chip 701 *cfg = PITA_INT0_STATUS; // Reset PLX interrupt 702 spin_unlock_irqrestore(&cs->lock, flags); 703 return IRQ_HANDLED; 704} 705 706static void 707release_io_diva(struct IsdnCardState *cs) 708{ 709 int bytecnt; 710 711 if ((cs->subtyp == DIVA_IPAC_PCI) || 712 (cs->subtyp == DIVA_IPACX_PCI)) { 713 u_int *cfg = (unsigned int *)cs->hw.diva.pci_cfg; 714 715 *cfg = 0; /* disable INT0/1 */ 716 *cfg = 2; /* reset pending INT0 */ 717 if (cs->hw.diva.cfg_reg) 718 iounmap((void *)cs->hw.diva.cfg_reg); 719 if (cs->hw.diva.pci_cfg) 720 iounmap((void *)cs->hw.diva.pci_cfg); 721 return; 722 } else if (cs->subtyp != DIVA_IPAC_ISA) { 723 del_timer(&cs->hw.diva.tl); 724 if (cs->hw.diva.cfg_reg) 725 byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */ 726 } 727 if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) 728 bytecnt = 8; 729 else 730 bytecnt = 32; 731 if (cs->hw.diva.cfg_reg) { 732 release_region(cs->hw.diva.cfg_reg, bytecnt); 733 } 734} 735 736static void 737iounmap_diva(struct IsdnCardState *cs) 738{ 739 if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) { 740 if (cs->hw.diva.cfg_reg) { 741 iounmap((void *)cs->hw.diva.cfg_reg); 742 cs->hw.diva.cfg_reg = 0; 743 } 744 if (cs->hw.diva.pci_cfg) { 745 iounmap((void *)cs->hw.diva.pci_cfg); 746 cs->hw.diva.pci_cfg = 0; 747 } 748 } 749 750 return; 751} 752 753static void 754reset_diva(struct IsdnCardState *cs) 755{ 756 if (cs->subtyp == DIVA_IPAC_ISA) { 757 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x20); 758 mdelay(10); 759 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x00); 760 mdelay(10); 761 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xc0); 762 } else if (cs->subtyp == DIVA_IPAC_PCI) { 763 unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg + 764 PITA_MISC_REG); 765 *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE; 766 mdelay(10); 767 *ireg = PITA_PARA_MPX_MODE; 768 mdelay(10); 769 memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xc0); 770 } else if (cs->subtyp == DIVA_IPACX_PCI) { 771 unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg + 772 PITA_MISC_REG); 773 *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE; 774 mdelay(10); 775 *ireg = PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET; 776 mdelay(10); 777 MemWriteISAC_IPACX(cs, IPACX_MASK, 0xff); // Interrupts off 778 } else { /* DIVA 2.0 */ 779 cs->hw.diva.ctrl_reg = 0; /* Reset On */ 780 byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); 781 mdelay(10); 782 cs->hw.diva.ctrl_reg |= DIVA_RESET; /* Reset Off */ 783 byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); 784 mdelay(10); 785 if (cs->subtyp == DIVA_ISA) 786 cs->hw.diva.ctrl_reg |= DIVA_ISA_LED_A; 787 else { 788 /* Workaround PCI9060 */ 789 byteout(cs->hw.diva.pci_cfg + 0x69, 9); 790 cs->hw.diva.ctrl_reg |= DIVA_PCI_LED_A; 791 } 792 byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); 793 } 794} 795 796#define DIVA_ASSIGN 1 797 798static void 799diva_led_handler(struct IsdnCardState *cs) 800{ 801 int blink = 0; 802 803 if ((cs->subtyp == DIVA_IPAC_ISA) || 804 (cs->subtyp == DIVA_IPAC_PCI) || 805 (cs->subtyp == DIVA_IPACX_PCI)) 806 return; 807 del_timer(&cs->hw.diva.tl); 808 if (cs->hw.diva.status & DIVA_ASSIGN) 809 cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ? 810 DIVA_ISA_LED_A : DIVA_PCI_LED_A; 811 else { 812 cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ? 813 DIVA_ISA_LED_A : DIVA_PCI_LED_A; 814 blink = 250; 815 } 816 if (cs->hw.diva.status & 0xf000) 817 cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ? 818 DIVA_ISA_LED_B : DIVA_PCI_LED_B; 819 else if (cs->hw.diva.status & 0x0f00) { 820 cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ? 821 DIVA_ISA_LED_B : DIVA_PCI_LED_B; 822 blink = 500; 823 } else 824 cs->hw.diva.ctrl_reg &= ~((DIVA_ISA == cs->subtyp) ? 825 DIVA_ISA_LED_B : DIVA_PCI_LED_B); 826 827 byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); 828 if (blink) { 829 init_timer(&cs->hw.diva.tl); 830 cs->hw.diva.tl.expires = jiffies + ((blink * HZ) / 1000); 831 add_timer(&cs->hw.diva.tl); 832 } 833} 834 835static int 836Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg) 837{ 838 u_int *ireg; 839 u_long flags; 840 841 switch (mt) { 842 case CARD_RESET: 843 spin_lock_irqsave(&cs->lock, flags); 844 reset_diva(cs); 845 spin_unlock_irqrestore(&cs->lock, flags); 846 return (0); 847 case CARD_RELEASE: 848 release_io_diva(cs); 849 return (0); 850 case CARD_INIT: 851 spin_lock_irqsave(&cs->lock, flags); 852 reset_diva(cs); 853 if (cs->subtyp == DIVA_IPACX_PCI) { 854 ireg = (unsigned int *)cs->hw.diva.pci_cfg; 855 *ireg = PITA_INT0_ENABLE; 856 init_ipacx(cs, 3); // init chip and enable interrupts 857 spin_unlock_irqrestore(&cs->lock, flags); 858 return (0); 859 } 860 if (cs->subtyp == DIVA_IPAC_PCI) { 861 ireg = (unsigned int *)cs->hw.diva.pci_cfg; 862 *ireg = PITA_INT0_ENABLE; 863 } 864 inithscxisac(cs, 3); 865 spin_unlock_irqrestore(&cs->lock, flags); 866 return (0); 867 case CARD_TEST: 868 return (0); 869 case (MDL_REMOVE | REQUEST): 870 cs->hw.diva.status = 0; 871 break; 872 case (MDL_ASSIGN | REQUEST): 873 cs->hw.diva.status |= DIVA_ASSIGN; 874 break; 875 case MDL_INFO_SETUP: 876 if ((long)arg) 877 cs->hw.diva.status |= 0x0200; 878 else 879 cs->hw.diva.status |= 0x0100; 880 break; 881 case MDL_INFO_CONN: 882 if ((long)arg) 883 cs->hw.diva.status |= 0x2000; 884 else 885 cs->hw.diva.status |= 0x1000; 886 break; 887 case MDL_INFO_REL: 888 if ((long)arg) { 889 cs->hw.diva.status &= ~0x2000; 890 cs->hw.diva.status &= ~0x0200; 891 } else { 892 cs->hw.diva.status &= ~0x1000; 893 cs->hw.diva.status &= ~0x0100; 894 } 895 break; 896 } 897 if ((cs->subtyp != DIVA_IPAC_ISA) && 898 (cs->subtyp != DIVA_IPAC_PCI) && 899 (cs->subtyp != DIVA_IPACX_PCI)) { 900 spin_lock_irqsave(&cs->lock, flags); 901 diva_led_handler(cs); 902 spin_unlock_irqrestore(&cs->lock, flags); 903 } 904 return (0); 905} 906 907static int setup_diva_common(struct IsdnCardState *cs) 908{ 909 int bytecnt; 910 u_char val; 911 912 if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) 913 bytecnt = 8; 914 else 915 bytecnt = 32; 916 917 printk(KERN_INFO 918 "Diva: %s card configured at %#lx IRQ %d\n", 919 (cs->subtyp == DIVA_PCI) ? "PCI" : 920 (cs->subtyp == DIVA_ISA) ? "ISA" : 921 (cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" : 922 (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", 923 cs->hw.diva.cfg_reg, cs->irq); 924 if ((cs->subtyp == DIVA_IPAC_PCI) || 925 (cs->subtyp == DIVA_IPACX_PCI) || 926 (cs->subtyp == DIVA_PCI)) 927 printk(KERN_INFO "Diva: %s space at %#lx\n", 928 (cs->subtyp == DIVA_PCI) ? "PCI" : 929 (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", 930 cs->hw.diva.pci_cfg); 931 if ((cs->subtyp != DIVA_IPAC_PCI) && 932 (cs->subtyp != DIVA_IPACX_PCI)) { 933 if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) { 934 printk(KERN_WARNING 935 "HiSax: %s config port %lx-%lx already in use\n", 936 "diva", 937 cs->hw.diva.cfg_reg, 938 cs->hw.diva.cfg_reg + bytecnt); 939 iounmap_diva(cs); 940 return (0); 941 } 942 } 943 cs->BC_Read_Reg = &ReadHSCX; 944 cs->BC_Write_Reg = &WriteHSCX; 945 cs->BC_Send_Data = &hscx_fill_fifo; 946 cs->cardmsg = &Diva_card_msg; 947 setup_isac(cs); 948 if (cs->subtyp == DIVA_IPAC_ISA) { 949 cs->readisac = &ReadISAC_IPAC; 950 cs->writeisac = &WriteISAC_IPAC; 951 cs->readisacfifo = &ReadISACfifo_IPAC; 952 cs->writeisacfifo = &WriteISACfifo_IPAC; 953 cs->irq_func = &diva_irq_ipac_isa; 954 val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID); 955 printk(KERN_INFO "Diva: IPAC version %x\n", val); 956 } else if (cs->subtyp == DIVA_IPAC_PCI) { 957 cs->readisac = &MemReadISAC_IPAC; 958 cs->writeisac = &MemWriteISAC_IPAC; 959 cs->readisacfifo = &MemReadISACfifo_IPAC; 960 cs->writeisacfifo = &MemWriteISACfifo_IPAC; 961 cs->BC_Read_Reg = &MemReadHSCX; 962 cs->BC_Write_Reg = &MemWriteHSCX; 963 cs->BC_Send_Data = &Memhscx_fill_fifo; 964 cs->irq_func = &diva_irq_ipac_pci; 965 val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID); 966 printk(KERN_INFO "Diva: IPAC version %x\n", val); 967 } else if (cs->subtyp == DIVA_IPACX_PCI) { 968 cs->readisac = &MemReadISAC_IPACX; 969 cs->writeisac = &MemWriteISAC_IPACX; 970 cs->readisacfifo = &MemReadISACfifo_IPACX; 971 cs->writeisacfifo = &MemWriteISACfifo_IPACX; 972 cs->BC_Read_Reg = &MemReadHSCX_IPACX; 973 cs->BC_Write_Reg = &MemWriteHSCX_IPACX; 974 cs->BC_Send_Data = NULL; // function located in ipacx module 975 cs->irq_func = &diva_irq_ipacx_pci; 976 printk(KERN_INFO "Diva: IPACX Design Id: %x\n", 977 MemReadISAC_IPACX(cs, IPACX_ID) & 0x3F); 978 } else { /* DIVA 2.0 */ 979 cs->hw.diva.tl.function = (void *) diva_led_handler; 980 cs->hw.diva.tl.data = (long) cs; 981 init_timer(&cs->hw.diva.tl); 982 cs->readisac = &ReadISAC; 983 cs->writeisac = &WriteISAC; 984 cs->readisacfifo = &ReadISACfifo; 985 cs->writeisacfifo = &WriteISACfifo; 986 cs->irq_func = &diva_interrupt; 987 ISACVersion(cs, "Diva:"); 988 if (HscxVersion(cs, "Diva:")) { 989 printk(KERN_WARNING 990 "Diva: wrong HSCX versions check IO address\n"); 991 release_io_diva(cs); 992 return (0); 993 } 994 } 995 return (1); 996} 997 998#ifdef CONFIG_ISA 999 1000static int setup_diva_isa(struct IsdnCard *card) 1001{ 1002 struct IsdnCardState *cs = card->cs; 1003 u_char val; 1004 1005 if (!card->para[1]) 1006 return (-1); /* card not found; continue search */ 1007 1008 cs->hw.diva.ctrl_reg = 0; 1009 cs->hw.diva.cfg_reg = card->para[1]; 1010 val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, 1011 cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); 1012 printk(KERN_INFO "Diva: IPAC version %x\n", val); 1013 if ((val == 1) || (val == 2)) { 1014 cs->subtyp = DIVA_IPAC_ISA; 1015 cs->hw.diva.ctrl = 0; 1016 cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; 1017 cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA; 1018 cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; 1019 cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR; 1020 test_and_set_bit(HW_IPAC, &cs->HW_Flags); 1021 } else { 1022 cs->subtyp = DIVA_ISA; 1023 cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; 1024 cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; 1025 cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; 1026 cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; 1027 cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; 1028 } 1029 cs->irq = card->para[0]; 1030 1031 return (1); /* card found */ 1032} 1033 1034#else /* if !CONFIG_ISA */ 1035 1036static int setup_diva_isa(struct IsdnCard *card) 1037{ 1038 return (-1); /* card not found; continue search */ 1039} 1040 1041#endif /* CONFIG_ISA */ 1042 1043#ifdef __ISAPNP__ 1044static struct isapnp_device_id diva_ids[] = { 1045 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), 1046 ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), 1047 (unsigned long) "Diva picola" }, 1048 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), 1049 ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), 1050 (unsigned long) "Diva picola" }, 1051 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), 1052 ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), 1053 (unsigned long) "Diva 2.0" }, 1054 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), 1055 ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), 1056 (unsigned long) "Diva 2.0" }, 1057 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), 1058 ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), 1059 (unsigned long) "Diva 2.01" }, 1060 { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), 1061 ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), 1062 (unsigned long) "Diva 2.01" }, 1063 { 0, } 1064}; 1065 1066static struct isapnp_device_id *ipid = &diva_ids[0]; 1067static struct pnp_card *pnp_c = NULL; 1068 1069static int setup_diva_isapnp(struct IsdnCard *card) 1070{ 1071 struct IsdnCardState *cs = card->cs; 1072 struct pnp_dev *pnp_d; 1073 1074 if (!isapnp_present()) 1075 return (-1); /* card not found; continue search */ 1076 1077 while (ipid->card_vendor) { 1078 if ((pnp_c = pnp_find_card(ipid->card_vendor, 1079 ipid->card_device, pnp_c))) { 1080 pnp_d = NULL; 1081 if ((pnp_d = pnp_find_dev(pnp_c, 1082 ipid->vendor, ipid->function, pnp_d))) { 1083 int err; 1084 1085 printk(KERN_INFO "HiSax: %s detected\n", 1086 (char *)ipid->driver_data); 1087 pnp_disable_dev(pnp_d); 1088 err = pnp_activate_dev(pnp_d); 1089 if (err < 0) { 1090 printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", 1091 __func__, err); 1092 return (0); 1093 } 1094 card->para[1] = pnp_port_start(pnp_d, 0); 1095 card->para[0] = pnp_irq(pnp_d, 0); 1096 if (!card->para[0] || !card->para[1]) { 1097 printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", 1098 card->para[0], card->para[1]); 1099 pnp_disable_dev(pnp_d); 1100 return (0); 1101 } 1102 cs->hw.diva.cfg_reg = card->para[1]; 1103 cs->irq = card->para[0]; 1104 if (ipid->function == ISAPNP_FUNCTION(0xA1)) { 1105 cs->subtyp = DIVA_IPAC_ISA; 1106 cs->hw.diva.ctrl = 0; 1107 cs->hw.diva.isac = 1108 card->para[1] + DIVA_IPAC_DATA; 1109 cs->hw.diva.hscx = 1110 card->para[1] + DIVA_IPAC_DATA; 1111 cs->hw.diva.isac_adr = 1112 card->para[1] + DIVA_IPAC_ADR; 1113 cs->hw.diva.hscx_adr = 1114 card->para[1] + DIVA_IPAC_ADR; 1115 test_and_set_bit(HW_IPAC, &cs->HW_Flags); 1116 } else { 1117 cs->subtyp = DIVA_ISA; 1118 cs->hw.diva.ctrl = 1119 card->para[1] + DIVA_ISA_CTRL; 1120 cs->hw.diva.isac = 1121 card->para[1] + DIVA_ISA_ISAC_DATA; 1122 cs->hw.diva.hscx = 1123 card->para[1] + DIVA_HSCX_DATA; 1124 cs->hw.diva.isac_adr = 1125 card->para[1] + DIVA_ISA_ISAC_ADR; 1126 cs->hw.diva.hscx_adr = 1127 card->para[1] + DIVA_HSCX_ADR; 1128 } 1129 return (1); /* card found */ 1130 } else { 1131 printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); 1132 return (0); 1133 } 1134 } 1135 ipid++; 1136 pnp_c = NULL; 1137 } 1138 1139 return (-1); /* card not found; continue search */ 1140} 1141 1142#else /* if !ISAPNP */ 1143 1144static int setup_diva_isapnp(struct IsdnCard *card) 1145{ 1146 return (-1); /* card not found; continue search */ 1147} 1148 1149#endif /* ISAPNP */ 1150 1151#ifdef CONFIG_PCI 1152static struct pci_dev *dev_diva = NULL; 1153static struct pci_dev *dev_diva_u = NULL; 1154static struct pci_dev *dev_diva201 = NULL; 1155static struct pci_dev *dev_diva202 = NULL; 1156 1157static int setup_diva_pci(struct IsdnCard *card) 1158{ 1159 struct IsdnCardState *cs = card->cs; 1160 1161 cs->subtyp = 0; 1162 if ((dev_diva = hisax_find_pci_device(PCI_VENDOR_ID_EICON, 1163 PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { 1164 if (pci_enable_device(dev_diva)) 1165 return (0); 1166 cs->subtyp = DIVA_PCI; 1167 cs->irq = dev_diva->irq; 1168 cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); 1169 } else if ((dev_diva_u = hisax_find_pci_device(PCI_VENDOR_ID_EICON, 1170 PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { 1171 if (pci_enable_device(dev_diva_u)) 1172 return (0); 1173 cs->subtyp = DIVA_PCI; 1174 cs->irq = dev_diva_u->irq; 1175 cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); 1176 } else if ((dev_diva201 = hisax_find_pci_device(PCI_VENDOR_ID_EICON, 1177 PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { 1178 if (pci_enable_device(dev_diva201)) 1179 return (0); 1180 cs->subtyp = DIVA_IPAC_PCI; 1181 cs->irq = dev_diva201->irq; 1182 cs->hw.diva.pci_cfg = 1183 (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); 1184 cs->hw.diva.cfg_reg = 1185 (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); 1186 } else if ((dev_diva202 = hisax_find_pci_device(PCI_VENDOR_ID_EICON, 1187 PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { 1188 if (pci_enable_device(dev_diva202)) 1189 return (0); 1190 cs->subtyp = DIVA_IPACX_PCI; 1191 cs->irq = dev_diva202->irq; 1192 cs->hw.diva.pci_cfg = 1193 (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096); 1194 cs->hw.diva.cfg_reg = 1195 (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096); 1196 } else { 1197 return (-1); /* card not found; continue search */ 1198 } 1199 1200 if (!cs->irq) { 1201 printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); 1202 iounmap_diva(cs); 1203 return (0); 1204 } 1205 1206 if (!cs->hw.diva.cfg_reg) { 1207 printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); 1208 iounmap_diva(cs); 1209 return (0); 1210 } 1211 cs->irq_flags |= IRQF_SHARED; 1212 1213 if ((cs->subtyp == DIVA_IPAC_PCI) || 1214 (cs->subtyp == DIVA_IPACX_PCI)) { 1215 cs->hw.diva.ctrl = 0; 1216 cs->hw.diva.isac = 0; 1217 cs->hw.diva.hscx = 0; 1218 cs->hw.diva.isac_adr = 0; 1219 cs->hw.diva.hscx_adr = 0; 1220 test_and_set_bit(HW_IPAC, &cs->HW_Flags); 1221 } else { 1222 cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; 1223 cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; 1224 cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; 1225 cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; 1226 cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; 1227 } 1228 1229 return (1); /* card found */ 1230} 1231 1232#else /* if !CONFIG_PCI */ 1233 1234static int setup_diva_pci(struct IsdnCard *card) 1235{ 1236 return (-1); /* card not found; continue search */ 1237} 1238 1239#endif /* CONFIG_PCI */ 1240 1241int setup_diva(struct IsdnCard *card) 1242{ 1243 int rc, have_card = 0; 1244 struct IsdnCardState *cs = card->cs; 1245 char tmp[64]; 1246 1247 strcpy(tmp, Diva_revision); 1248 printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); 1249 if (cs->typ != ISDN_CTYPE_DIEHLDIVA) 1250 return (0); 1251 cs->hw.diva.status = 0; 1252 1253 rc = setup_diva_isa(card); 1254 if (!rc) 1255 return rc; 1256 if (rc > 0) { 1257 have_card = 1; 1258 goto ready; 1259 } 1260 1261 rc = setup_diva_isapnp(card); 1262 if (!rc) 1263 return rc; 1264 if (rc > 0) { 1265 have_card = 1; 1266 goto ready; 1267 } 1268 1269 rc = setup_diva_pci(card); 1270 if (!rc) 1271 return rc; 1272 if (rc > 0) 1273 have_card = 1; 1274 1275ready: 1276 if (!have_card) { 1277 printk(KERN_WARNING "Diva: No ISA, ISAPNP or PCI card found\n"); 1278 return (0); 1279 } 1280 1281 return setup_diva_common(card->cs); 1282} 1283