20 #include <linux/pci.h>
22 static const char *gazel_revision =
"$Revision: 2.19.2.4 $";
29 #define PLX_CNTRL 0x50
30 #define RESET_GAZEL 0x4
31 #define RESET_9050 0x40000000
32 #define PLX_INCSR 0x4C
33 #define INT_ISAC_EN 0x8
35 #define INT_HSCX_EN 0x1
37 #define INT_PCI_EN 0x40
38 #define INT_IPAC_EN 0x3
41 #define byteout(addr, val) outb(val, addr)
42 #define bytein(addr) inb(addr)
60 insb(adr, data, size);
66 outsb(adr, data, size);
70 readreg_ipac(
unsigned int adr,
u_short off)
91 insb(adr + 4, data, size);
98 outsb(adr + 4, data, size);
108 switch (cs->subtyp) {
110 off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
112 return (
readreg(cs->hw.gazel.isac, off2));
115 return (readreg_ipac(cs->hw.gazel.ipac, 0x80 + off2));
125 switch (cs->subtyp) {
127 off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
129 writereg(cs->hw.gazel.isac, off2, value);
133 writereg_ipac(cs->hw.gazel.ipac, 0x80 + off2, value);
141 switch (cs->subtyp) {
144 read_fifo(cs->hw.gazel.isacfifo, data, size);
148 read_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size);
154 WriteISACfifo(
struct IsdnCardState *cs,
u_char *data,
int size)
156 switch (cs->subtyp) {
159 write_fifo(cs->hw.gazel.isacfifo, data, size);
163 write_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size);
169 ReadHSCXfifo(
struct IsdnCardState *cs,
int hscx,
u_char *data,
int size)
171 switch (cs->subtyp) {
174 read_fifo(cs->hw.gazel.hscxfifo[hscx], data, size);
178 read_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size);
184 WriteHSCXfifo(
struct IsdnCardState *cs,
int hscx,
u_char *data,
int size)
186 switch (cs->subtyp) {
189 write_fifo(cs->hw.gazel.hscxfifo[hscx], data, size);
193 write_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size);
203 switch (cs->subtyp) {
205 off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
207 return (
readreg(cs->hw.gazel.hscx[hscx], off2));
210 return (readreg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2));
220 switch (cs->subtyp) {
222 off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
224 writereg(cs->hw.gazel.hscx[hscx], off2, value);
228 writereg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2, value);
237 #define READHSCX(cs, nr, reg) ReadHSCX(cs, nr, reg)
238 #define WRITEHSCX(cs, nr, reg, data) WriteHSCX(cs, nr, reg, data)
239 #define READHSCXFIFO(cs, nr, ptr, cnt) ReadHSCXfifo(cs, nr, ptr, cnt)
240 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) WriteHSCXfifo(cs, nr, ptr, cnt)
245 gazel_interrupt(
int intno,
void *
dev_id)
248 struct IsdnCardState *cs =
dev_id;
257 hscx_int_main(cs, valhscx);
262 }
while ((valhscx || valisac) && (count <
MAXCOUNT));
270 spin_unlock_irqrestore(&cs->lock, flags);
276 gazel_interrupt_ipac(
int intno,
void *
dev_id)
278 struct IsdnCardState *cs =
dev_id;
295 hscx_int_main(cs, val);
311 while ((ista & 0x3f) && (count < MAXCOUNT));
315 spin_unlock_irqrestore(&cs->lock, flags);
320 release_io_gazel(
struct IsdnCardState *cs)
324 switch (cs->subtyp) {
326 for (i = 0x0000; i < 0xC000; i += 0x1000)
348 reset_gazel(
struct IsdnCardState *cs)
350 unsigned long plxcntrl,
addr = cs->hw.gazel.cfg_reg;
352 switch (cs->subtyp) {
401 Gazel_card_msg(
struct IsdnCardState *cs,
int mt,
void *
arg)
409 spin_unlock_irqrestore(&cs->lock, flags);
412 release_io_gazel(cs);
417 if ((cs->subtyp ==
R647) || (cs->subtyp ==
R685)) {
420 cs->bcs[
i].hw.hscx.tsaxr0 = 0x1f;
421 cs->bcs[
i].hw.hscx.tsaxr1 = 0x23;
424 spin_unlock_irqrestore(&cs->lock, flags);
433 reserve_regions(
struct IsdnCard *
card,
struct IsdnCardState *cs)
435 unsigned int i,
j,
base = 0, adr = 0,
len = 0;
437 switch (cs->subtyp) {
439 base = cs->hw.gazel.hscx[0];
442 for (i = 0x0000; i < 0xC000; i += 0x1000) {
447 for (j = 0; j <
i; j += 0x1000)
455 if (!
request_region(adr = cs->hw.gazel.hscx[0], len = 0x100,
"gazel"))
457 if (!
request_region(adr = cs->hw.gazel.cfg_reg, len = 0x80,
"gazel")) {
466 if (!
request_region(adr = cs->hw.gazel.cfg_reg, len = 0x80,
"gazel")) {
487 setup_gazelisa(
struct IsdnCard *card,
struct IsdnCardState *cs)
500 cs->hw.gazel.cfg_reg = card->
para[1] + 0xC000;
501 cs->hw.gazel.ipac = card->
para[1];
502 cs->hw.gazel.isac = card->
para[1] + 0x8000;
503 cs->hw.gazel.hscx[0] = card->
para[1];
504 cs->hw.gazel.hscx[1] = card->
para[1] + 0x4000;
505 cs->irq = card->
para[0];
506 cs->hw.gazel.isacfifo = cs->hw.gazel.isac;
507 cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0];
508 cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1];
510 switch (cs->subtyp) {
513 cs->dc.isac.adf2 = 0x87;
515 "Gazel: config irq:%d isac:0x%X cfg:0x%X\n",
516 cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
518 "Gazel: hscx A:0x%X hscx B:0x%X\n",
519 cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
526 "Gazel: config irq:%d ipac:0x%X\n",
527 cs->irq, cs->hw.gazel.ipac);
538 setup_gazelpci(
struct IsdnCardState *cs)
540 u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0;
541 u_char pci_irq = 0, found;
542 u_int nbseek, seekcard;
548 for (nbseek = 0; nbseek < 4; nbseek++) {
550 seekcard, dev_tel))) {
553 pci_irq = dev_tel->irq;
582 cs->hw.gazel.pciaddr[0] = pci_ioaddr0;
583 cs->hw.gazel.pciaddr[1] = pci_ioaddr1;
585 pci_ioaddr1 &= 0xfffe;
586 cs->hw.gazel.cfg_reg = pci_ioaddr0 & 0xfffe;
587 cs->hw.gazel.ipac = pci_ioaddr1;
588 cs->hw.gazel.isac = pci_ioaddr1 + 0x80;
589 cs->hw.gazel.hscx[0] = pci_ioaddr1;
590 cs->hw.gazel.hscx[1] = pci_ioaddr1 + 0x40;
591 cs->hw.gazel.isacfifo = cs->hw.gazel.isac;
592 cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0];
593 cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1];
601 cs->dc.isac.adf2 = 0x87;
603 "Gazel: config irq:%d isac:0x%X cfg:0x%X\n",
604 cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
606 "Gazel: hscx A:0x%X hscx B:0x%X\n",
607 cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
616 "Gazel: config irq:%d ipac:0x%X cfg:0x%X\n",
617 cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg);
628 struct IsdnCardState *cs = card->
cs;
632 strcpy(tmp, gazel_revision);
639 if (setup_gazelisa(card, cs))
644 if (setup_gazelpci(cs))
652 if (reserve_regions(card, cs)) {
655 if (reset_gazel(cs)) {
657 release_io_gazel(cs);
662 cs->readisacfifo = &ReadISACfifo;
663 cs->writeisacfifo = &WriteISACfifo;
666 cs->BC_Send_Data = &hscx_fill_fifo;
667 cs->cardmsg = &Gazel_card_msg;
669 switch (cs->subtyp) {
672 cs->irq_func = &gazel_interrupt;
676 "Gazel: wrong HSCX versions check IO address\n");
677 release_io_gazel(cs);
683 cs->irq_func = &gazel_interrupt_ipac;