Commit b59b6557 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN/HiSax: Generate D/B channel access functions for IPAC

IPAC is basically a combined HSCX/ISAC chip, so we can generate
the D- and B-channel access functions knowing how to access the IPAC.
  
For performance reasons, this happens in a macro.
parent bfb4d184
......@@ -113,37 +113,6 @@ static struct dc_hw_ops isac_ops = {
.write_fifo = isac_write_fifo,
};
static u8
ipac_dc_read(struct IsdnCardState *cs, u8 offset)
{
return readreg(cs, cs->hw.asus.isac, offset+0x80);
}
static void
ipac_dc_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
writereg(cs, cs->hw.asus.isac, offset+0x80, value);
}
static void
ipac_dc_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
readfifo(cs, cs->hw.asus.isac, 0x80, data, size);
}
static void
ipac_dc_write_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
writefifo(cs, cs->hw.asus.isac, 0x80, data, size);
}
static struct dc_hw_ops ipac_dc_ops = {
.read_reg = ipac_dc_read,
.write_reg = ipac_dc_write,
.read_fifo = ipac_dc_read_fifo,
.write_fifo = ipac_dc_write_fifo,
};
static u8
hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
{
......@@ -175,18 +144,50 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static u8
ipac_read(struct IsdnCardState *cs, u8 offset)
static inline u8
ipac_read(struct IsdnCardState *cs, u8 off)
{
return ipac_dc_read(cs, offset - 0x80);
u8 ret;
unsigned long flags;
spin_lock_irqsave(&asuscom_lock, flags);
byteout(cs->hw.asus.adr, off);
ret = bytein(cs->hw.asus.isac);
spin_unlock_irqrestore(&asuscom_lock, flags);
return ret;
}
static void
ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
static inline void
ipac_write(struct IsdnCardState *cs, u8 off, u8 data)
{
ipac_dc_write(cs, offset - 0x80, value);
unsigned long flags;
spin_lock_irqsave(&asuscom_lock, flags);
byteout(cs->hw.asus.adr, off);
byteout(cs->hw.asus.isac, data);
spin_unlock_irqrestore(&asuscom_lock, flags);
}
static inline void
ipac_readfifo(struct IsdnCardState *cs, u8 off, u8 * data, int size)
{
byteout(cs->hw.asus.adr, off);
insb(cs->hw.asus.isac, data, size);
}
static inline void
ipac_writefifo(struct IsdnCardState *cs, u8 off, u8 * data, int size)
{
byteout(cs->hw.asus.adr, off);
outsb(cs->hw.asus.isac, data, size);
}
/* This will generate ipac_dc_ops and ipac_bc_ops using the functions
* above */
BUILD_IPAC_OPS(ipac);
static void
asuscom_ipac_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
......@@ -381,7 +382,6 @@ setup_asuscom(struct IsdnCard *card)
}
printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n",
cs->hw.asus.cfg_reg, cs->irq);
cs->bc_hw_ops = &hscx_ops;
cs->cardmsg = &Asus_card_msg;
cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE;
val = readreg(cs, cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID);
......@@ -392,6 +392,7 @@ setup_asuscom(struct IsdnCard *card)
cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA;
test_and_set_bit(HW_IPAC, &cs->HW_Flags);
cs->dc_hw_ops = &ipac_dc_ops;
cs->bc_hw_ops = &ipac_bc_ops;
printk(KERN_INFO "Asus: IPAC version %x\n", val);
} else {
cs->subtyp = ASUS_ISACHSCX;
......@@ -402,6 +403,7 @@ setup_asuscom(struct IsdnCard *card)
cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7;
cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS;
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
ISACVersion(cs, "ISDNLink:");
if (HscxVersion(cs, "ISDNLink:")) {
printk(KERN_WARNING
......
......@@ -42,7 +42,7 @@ static const char *sct_quadro_subtypes[] =
#define wordin(addr) inw(addr)
static inline u8
readreg(struct IsdnCardState *cs, u8 off)
ipac_read(struct IsdnCardState *cs, u8 off)
{
u8 ret;
unsigned long flags;
......@@ -51,13 +51,14 @@ readreg(struct IsdnCardState *cs, u8 off)
wordout(cs->hw.ax.base, off);
ret = wordin(cs->hw.ax.data_adr) & 0xFF;
spin_unlock_irqrestore(&bkm_a8_lock, flags);
return (ret);
return ret;
}
static inline void
writereg(struct IsdnCardState *cs, u8 off, u8 data)
ipac_write(struct IsdnCardState *cs, u8 off, u8 data)
{
unsigned long flags;
spin_lock_irqsave(&bkm_a8_lock, flags);
wordout(cs->hw.ax.base, off);
wordout(cs->hw.ax.data_adr, data);
......@@ -65,7 +66,7 @@ writereg(struct IsdnCardState *cs, u8 off, u8 data)
}
static inline void
readfifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
ipac_readfifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
{
int i;
......@@ -75,7 +76,7 @@ readfifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
}
static inline void
writefifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
ipac_writefifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
{
int i;
......@@ -84,86 +85,17 @@ writefifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
wordout(cs->hw.ax.data_adr, data[i]);
}
static u8
ipac_dc_read(struct IsdnCardState *cs, u8 offset)
{
return readreg(cs, offset + 0x80);
}
static void
ipac_dc_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
writereg(cs, offset + 0x80, value);
}
static void
ipac_dc_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
readfifo(cs, 0x80, data, size);
}
static void
ipac_dc_write_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
writefifo(cs, 0x80, data, size);
}
static struct dc_hw_ops ipac_dc_ops = {
.read_reg = ipac_dc_read,
.write_reg = ipac_dc_write,
.read_fifo = ipac_dc_read_fifo,
.write_fifo = ipac_dc_write_fifo,
};
static u8
hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
{
return readreg(cs, offset + (hscx ? 0x40 : 0));
}
static void
hscx_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value)
{
writereg(cs, offset + (hscx ? 0x40 : 0), value);
}
static void
hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)
{
readfifo(cs, hscx ? 0x40 : 0, data, size);
}
static void
hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)
{
writefifo(cs, hscx ? 0x40 : 0, data, size);
}
static struct bc_hw_ops hscx_ops = {
.read_reg = hscx_read,
.write_reg = hscx_write,
.read_fifo = hscx_read_fifo,
.write_fifo = hscx_write_fifo,
};
static u8
ipac_read(struct IsdnCardState *cs, u8 offset)
{
return ipac_dc_read(cs, offset - 0x80);
}
static void
ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
ipac_dc_write(cs, offset - 0x80, value);
}
/* This will generate ipac_dc_ops and ipac_bc_ops using the functions
* above */
BUILD_IPAC_OPS(ipac);
/* Set the specific ipac to active */
static void
set_ipac_active(struct IsdnCardState *cs, u_int active)
{
/* set irq mask */
writereg(cs, IPAC_MASK, active ? 0xc0 : 0xff);
ipac_write(cs, IPAC_MASK, active ? 0xc0 : 0xff);
}
static void
......@@ -180,7 +112,7 @@ bkm_a8_interrupt(int intno, void *dev_id, struct pt_regs *regs)
if (cs->debug & L1_DEB_IPAC)
debugl1(cs, "IPAC ISTA %02X", ista);
if (ista & 0x0f) {
val = hscx_read(cs, 1, HSCX_ISTA);
val = ipac_bc_read(cs, 1, HSCX_ISTA);
if (ista & 0x01)
val |= 0x01;
if (ista & 0x04)
......@@ -438,7 +370,7 @@ setup_sct_quadro(struct IsdnCard *card)
break;
}
cs->hw.ax.data_adr = cs->hw.ax.base + 4;
writereg(cs, IPAC_MASK, 0xFF);
ipac_write(cs, IPAC_MASK, 0xFF);
printk(KERN_INFO "HiSax: %s (%s) configured at 0x%.4lX, 0x%.4lX, 0x%.4lX and IRQ %d\n",
CardType[card->typ],
......@@ -451,14 +383,14 @@ setup_sct_quadro(struct IsdnCard *card)
test_and_set_bit(HW_IPAC, &cs->HW_Flags);
cs->dc_hw_ops = &ipac_dc_ops;
cs->bc_hw_ops = &hscx_ops;
cs->bc_hw_ops = &ipac_bc_ops;
cs->cardmsg = &BKM_card_msg;
cs->card_ops = &bkm_a8_ops;
printk(KERN_INFO "HiSax: %s (%s): IPAC Version %d\n",
CardType[card->typ],
sct_quadro_subtypes[cs->subtyp],
readreg(cs, IPAC_ID));
ipac_read(cs, IPAC_ID));
return (1);
#else
printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n");
......
......@@ -163,37 +163,6 @@ static struct dc_hw_ops isac_ops = {
.write_fifo = isac_write_fifo,
};
static u8
ipac_dc_read(struct IsdnCardState *cs, u8 offset)
{
return readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset+0x80);
}
static void
ipac_dc_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset+0x80, value);
}
static void
ipac_dc_read_fifo(struct IsdnCardState *cs, u8 *data, int size)
{
readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size);
}
static void
ipac_dc_write_fifo(struct IsdnCardState *cs, u8 *data, int size)
{
writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size);
}
static struct dc_hw_ops ipac_dc_ops = {
.read_reg = ipac_dc_read,
.write_reg = ipac_dc_write,
.read_fifo = ipac_dc_read_fifo,
.write_fifo = ipac_dc_write_fifo,
};
static u8
hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
{
......@@ -227,75 +196,65 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static u8
mem_ipac_dc_read(struct IsdnCardState *cs, u8 offset)
static inline u8
ipac_read(struct IsdnCardState *cs, u8 offset)
{
return memreadreg(cs->hw.diva.cfg_reg, offset+0x80);
return readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset);
}
static void
mem_ipac_dc_write(struct IsdnCardState *cs, u8 offset, u8 value)
static inline void
ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
memwritereg(cs->hw.diva.cfg_reg, offset|0x80, value);
writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, value);
}
static void
mem_ipac_dc_read_fifo(struct IsdnCardState *cs, u8 *data, int size)
static inline void
ipac_readfifo(struct IsdnCardState *cs, u8 offset, u8 *data, int size)
{
while(size--)
*data++ = memreadreg(cs->hw.diva.cfg_reg, 0x80);
readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, data, size);
}
static void
mem_ipac_dc_write_fifo(struct IsdnCardState *cs, u8 *data, int size)
static inline void
ipac_writefifo(struct IsdnCardState *cs, u8 offset, u8 *data, int size)
{
while(size--)
memwritereg(cs->hw.diva.cfg_reg, 0x80, *data++);
writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, data, size);
}
static struct dc_hw_ops mem_ipac_dc_ops = {
.read_reg = mem_ipac_dc_read,
.write_reg = mem_ipac_dc_write,
.read_fifo = mem_ipac_dc_read_fifo,
.write_fifo = mem_ipac_dc_write_fifo,
};
/* This will generate ipac_dc_ops and ipac_bc_ops using the functions
* above */
static u8
mem_hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
BUILD_IPAC_OPS(ipac);
static inline u8
mem_ipac_read(struct IsdnCardState *cs, u8 offset)
{
return memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0));
return memreadreg(cs->hw.diva.cfg_reg, offset);
}
static void
mem_hscx_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value)
static inline void
mem_ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value);
memwritereg(cs->hw.diva.cfg_reg, offset, value);
}
static void
mem_hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int len)
static inline void
mem_ipac_readfifo(struct IsdnCardState *cs, u8 offset, u8 *data, int size)
{
int i;
for (i = 0; i < len; i++)
*data++ = memreadreg(cs->hw.diva.cfg_reg, hscx ? 0x40 : 0);
while(size--)
*data++ = memreadreg(cs->hw.diva.cfg_reg, offset);
}
static void
mem_hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int len)
static inline void
mem_ipac_writefifo(struct IsdnCardState *cs, u8 offset, u8 *data, int size)
{
int i;
for (i = 0; i < len; i++)
memwritereg(cs->hw.diva.cfg_reg, hscx ? 0x40 : 0, *data++);
while(size--)
memwritereg(cs->hw.diva.cfg_reg, offset, *data++);
}
static struct bc_hw_ops mem_hscx_ops = {
.read_reg = mem_hscx_read,
.write_reg = mem_hscx_write,
.read_fifo = mem_hscx_read_fifo,
.write_fifo = mem_hscx_write_fifo,
};
/* This will generate mem_ipac_dc_ops and mem_ipac_bc_ops using the functions
* above */
BUILD_IPAC_OPS(mem_ipac);
/* IO-Functions for IPACX type cards */
static u8
......@@ -374,18 +333,6 @@ diva_interrupt(int intno, void *dev_id, struct pt_regs *regs)
printk(KERN_WARNING "Diva: IRQ LOOP\n");
}
static u8
ipac_read(struct IsdnCardState *cs, u8 offset)
{
return ipac_dc_read(cs, offset - 0x80);
}
static void
ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
ipac_dc_write(cs, offset - 0x80, value);
}
static void
diva_ipac_isa_irq(int intno, void *dev_id, struct pt_regs *regs)
{
......@@ -434,18 +381,6 @@ diva_ipac_isa_irq(int intno, void *dev_id, struct pt_regs *regs)
ipac_write(cs, IPAC_MASK, 0xC0);
}
static u8
mem_ipac_read(struct IsdnCardState *cs, u8 offset)
{
return mem_ipac_dc_read(cs, offset - 0x80);
}
static void
mem_ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
mem_ipac_dc_write(cs, offset - 0x80, value);
}
static void
diva_ipac_pci_irq(int intno, void *dev_id, struct pt_regs *regs)
{
......@@ -462,7 +397,7 @@ diva_ipac_pci_irq(int intno, void *dev_id, struct pt_regs *regs)
if (cs->debug & L1_DEB_IPAC)
debugl1(cs, "IPAC ISTA %02X", ista);
if (ista & 0x0f) {
val = mem_hscx_read(cs, 1, HSCX_ISTA);
val = mem_ipac_bc_read(cs, 1, HSCX_ISTA);
if (ista & 0x01)
val |= 0x01;
if (ista & 0x04)
......@@ -962,14 +897,14 @@ setup_diva(struct IsdnCard *card)
if (cs->subtyp == DIVA_IPAC_ISA) {
diva_ipac_isa_reset(cs);
cs->dc_hw_ops = &ipac_dc_ops;
cs->bc_hw_ops = &hscx_ops;
cs->bc_hw_ops = &ipac_bc_ops;
cs->card_ops = &diva_ipac_isa_ops;
val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID);
printk(KERN_INFO "Diva: IPAC version %x\n", val);
} else if (cs->subtyp == DIVA_IPAC_PCI) {
diva_ipac_pci_reset(cs);
cs->dc_hw_ops = &mem_ipac_dc_ops;
cs->bc_hw_ops = &mem_hscx_ops;
cs->bc_hw_ops = &mem_ipac_bc_ops;
cs->card_ops = &diva_ipac_pci_ops;
val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID);
printk(KERN_INFO "Diva: IPAC version %x\n", val);
......
......@@ -211,37 +211,6 @@ static struct dc_hw_ops isac_ops = {
.write_fifo = isac_write_fifo,
};
static u8
ipac_dc_read(struct IsdnCardState *cs, u8 offset)
{
return readreg(cs, cs->hw.elsa.isac, offset+0x80);
}
static void
ipac_dc_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
writereg(cs, cs->hw.elsa.isac, offset+0x80, value);
}
static void
ipac_dc_read_fifo(struct IsdnCardState *cs, u8 *data, int size)
{
readfifo(cs, cs->hw.elsa.isac, 0x80, data, size);
}
static void
ipac_dc_write_fifo(struct IsdnCardState *cs, u8 *data, int size)
{
writefifo(cs, cs->hw.elsa.isac, 0x80, data, size);
}
static struct dc_hw_ops ipac_dc_ops = {
.read_reg = ipac_dc_read,
.write_reg = ipac_dc_write,
.read_fifo = ipac_dc_read_fifo,
.write_fifo = ipac_dc_write_fifo,
};
static u8
hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
{
......@@ -273,6 +242,35 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static inline u8
ipac_read(struct IsdnCardState *cs, u8 offset)
{
return readreg(cs, cs->hw.elsa.isac, offset);
}
static inline void
ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
writereg(cs, cs->hw.elsa.isac, offset, value);
}
static inline void
ipac_readfifo(struct IsdnCardState *cs, u8 offset, u8 *data, int size)
{
readfifo(cs, cs->hw.elsa.isac, offset, data, size);
}
static inline void
ipac_writefifo(struct IsdnCardState *cs, u8 offset, u8 *data, int size)
{
writefifo(cs, cs->hw.elsa.isac, offset, data, size);
}
/* This will generate ipac_dc_ops and ipac_bc_ops using the functions
* above */
BUILD_IPAC_OPS(ipac);
static inline u8
readitac(struct IsdnCardState *cs, u8 off)
{
......@@ -356,18 +354,6 @@ elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
byteout(cs->hw.elsa.trig, 0x00);
}
static u8
ipac_read(struct IsdnCardState *cs, u8 offset)
{
return ipac_dc_read(cs, offset - 0x80);
}
static void
ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
ipac_dc_write(cs, offset - 0x80, value);
}
static void
elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
{
......@@ -1168,16 +1154,17 @@ setup_elsa(struct IsdnCard *card)
}
printk(KERN_INFO "Elsa: timer OK; resetting card\n");
}
cs->bc_hw_ops = &hscx_ops;
cs->cardmsg = &Elsa_card_msg;
elsa_reset(cs);
if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) {
cs->dc_hw_ops = &ipac_dc_ops;
cs->bc_hw_ops = &ipac_bc_ops;
cs->card_ops = &elsa_ipac_ops;
val = readreg(cs, cs->hw.elsa.isac, IPAC_ID);
printk(KERN_INFO "Elsa: IPAC version %x\n", val);
} else {
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->card_ops = &elsa_ops;
ISACVersion(cs, "Elsa:");
if (HscxVersion(cs, "Elsa:")) {
......
......@@ -69,45 +69,6 @@ write_fifo(unsigned int adr, u8 * data, int size)
outsb(adr, data, size);
}
static inline u8
readreg_ipac(struct IsdnCardState *cs, u_short off)
{
register u8 ret;
unsigned long flags;
spin_lock_irqsave(&gazel_lock, flags);
byteout(cs->hw.gazel.ipac, off);
ret = bytein(cs->hw.gazel.ipac + 4);
spin_unlock_irqrestore(&gazel_lock, flags);
return ret;
}
static inline void
writereg_ipac(struct IsdnCardState *cs, u_short off, u8 data)
{
unsigned long flags;
spin_lock_irqsave(&gazel_lock, flags);
byteout(cs->hw.gazel.ipac, off);
byteout(cs->hw.gazel.ipac + 4, data);
spin_unlock_irqrestore(&gazel_lock, flags);
}
static inline void
read_fifo_ipac(struct IsdnCardState *cs, u_short off, u8 * data, int size)
{
byteout(cs->hw.gazel.ipac, off);
insb(cs->hw.gazel.ipac + 4, data, size);
}
static void
write_fifo_ipac(struct IsdnCardState *cs, u_short off, u8 * data, int size)
{
byteout(cs->hw.gazel.ipac, off);
outsb(cs->hw.gazel.ipac + 4, data, size);
}
static u8
isac_read(struct IsdnCardState *cs, u8 offset)
{
......@@ -118,9 +79,6 @@ isac_read(struct IsdnCardState *cs, u8 offset)
off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
case R685:
return (readreg(cs->hw.gazel.isac, off2));
case R753:
case R742:
return (readreg_ipac(cs, 0x80 + off2));
}
return 0;
}
......@@ -136,10 +94,6 @@ isac_write(struct IsdnCardState *cs, u8 offset, u8 value)
case R685:
writereg(cs->hw.gazel.isac, off2, value);
break;
case R753:
case R742:
writereg_ipac(cs, 0x80 + off2, value);
break;
}
}
......@@ -151,10 +105,6 @@ isac_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
case R685:
read_fifo(cs->hw.gazel.isacfifo, data, size);
break;
case R753:
case R742:
read_fifo_ipac(cs, 0x80, data, size);
break;
}
}
......@@ -166,10 +116,6 @@ isac_write_fifo(struct IsdnCardState *cs, u8 * data, int size)
case R685:
write_fifo(cs->hw.gazel.isacfifo, data, size);
break;
case R753:
case R742:
write_fifo_ipac(cs, 0x80, data, size);
break;
}
}
......@@ -190,9 +136,6 @@ hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
case R685:
return readreg(cs->hw.gazel.hscx[hscx], off2);
case R753:
case R742:
return readreg_ipac(cs, hscx * 0x40 + off2);
}
return 0;
}
......@@ -208,10 +151,6 @@ hscx_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value)
case R685:
writereg(cs->hw.gazel.hscx[hscx], off2, value);
break;
case R753:
case R742:
writereg_ipac(cs, hscx * 0x40 + off2, value);
break;
}
}
......@@ -223,10 +162,6 @@ hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size)
case R685:
read_fifo(cs->hw.gazel.hscxfifo[hscx], data, size);
break;
case R753:
case R742:
read_fifo_ipac(cs, hscx * 0x40, data, size);
break;
}
}
......@@ -238,10 +173,6 @@ hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size)
case R685:
write_fifo(cs->hw.gazel.hscxfifo[hscx], data, size);
break;
case R753:
case R742:
write_fifo_ipac(cs, hscx * 0x40, data, size);
break;
}
}
......@@ -252,18 +183,50 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static u8
ipac_read(struct IsdnCardState *cs, u8 offset)
static inline u8
ipac_read(struct IsdnCardState *cs, u_short off)
{
return isac_read(cs, offset - 0x80);
register u8 ret;
unsigned long flags;
spin_lock_irqsave(&gazel_lock, flags);
byteout(cs->hw.gazel.ipac, off);
ret = bytein(cs->hw.gazel.ipac + 4);
spin_unlock_irqrestore(&gazel_lock, flags);
return ret;
}
static void
ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
static inline void
ipac_write(struct IsdnCardState *cs, u_short off, u8 data)
{
unsigned long flags;
spin_lock_irqsave(&gazel_lock, flags);
byteout(cs->hw.gazel.ipac, off);
byteout(cs->hw.gazel.ipac + 4, data);
spin_unlock_irqrestore(&gazel_lock, flags);
}
static inline void
ipac_readfifo(struct IsdnCardState *cs, u8 off, u8 * data, int size)
{
isac_write(cs, offset - 0x80, value);
byteout(cs->hw.gazel.ipac, off);
insb(cs->hw.gazel.ipac + 4, data, size);
}
static inline void
ipac_writefifo(struct IsdnCardState *cs, u8 off, u8 * data, int size)
{
byteout(cs->hw.gazel.ipac, off);
outsb(cs->hw.gazel.ipac + 4, data, size);
}
/* This will generate ipac_dc_ops and ipac_bc_ops using the functions
* above */
BUILD_IPAC_OPS(ipac);
#define MAXCOUNT 5
static void
......@@ -382,28 +345,28 @@ gazel_ipac_reset(struct IsdnCardState *cs)
plxcntrl = inl(addr + PLX_CNTRL);
plxcntrl |= (RESET_9050 + RESET_GAZEL);
outl(plxcntrl, addr + PLX_CNTRL);
writereg_ipac(cs, IPAC_POTA2, 0x20);
ipac_write(cs, IPAC_POTA2, 0x20);
HZDELAY(4);
plxcntrl &= ~(RESET_9050 + RESET_GAZEL);
outl(plxcntrl, addr + PLX_CNTRL);
HZDELAY(10);
writereg_ipac(cs, IPAC_POTA2, 0x00);
writereg_ipac(cs, IPAC_ACFG, 0xff);
writereg_ipac(cs, IPAC_AOE, 0x0);
writereg_ipac(cs, IPAC_MASK, 0xff);
writereg_ipac(cs, IPAC_CONF, 0x1);
ipac_write(cs, IPAC_POTA2, 0x00);
ipac_write(cs, IPAC_ACFG, 0xff);
ipac_write(cs, IPAC_AOE, 0x0);
ipac_write(cs, IPAC_MASK, 0xff);
ipac_write(cs, IPAC_CONF, 0x1);
outb(INT_IPAC_EN + INT_PCI_EN, addr + PLX_INCSR);
writereg_ipac(cs, IPAC_MASK, 0xc0);
ipac_write(cs, IPAC_MASK, 0xc0);
break;
case R742:
writereg_ipac(cs, IPAC_POTA2, 0x20);
ipac_write(cs, IPAC_POTA2, 0x20);
HZDELAY(4);
writereg_ipac(cs, IPAC_POTA2, 0x00);
writereg_ipac(cs, IPAC_ACFG, 0xff);
writereg_ipac(cs, IPAC_AOE, 0x0);
writereg_ipac(cs, IPAC_MASK, 0xff);
writereg_ipac(cs, IPAC_CONF, 0x1);
writereg_ipac(cs, IPAC_MASK, 0xc0);
ipac_write(cs, IPAC_POTA2, 0x00);
ipac_write(cs, IPAC_ACFG, 0xff);
ipac_write(cs, IPAC_AOE, 0x0);
ipac_write(cs, IPAC_MASK, 0xff);
ipac_write(cs, IPAC_CONF, 0x1);
ipac_write(cs, IPAC_MASK, 0xc0);
break;
}
return 0;
......@@ -508,7 +471,7 @@ setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs)
// R647 returns FF if not present or not started
// eventually needs improvment
cs->hw.gazel.ipac = card->para[1];
if (readreg_ipac(cs, IPAC_ID) == 1)
if (ipac_read(cs, IPAC_ID) == 1)
cs->subtyp = R742;
else
cs->subtyp = R647;
......@@ -677,13 +640,13 @@ setup_gazel(struct IsdnCard *card)
if (reserve_regions(card, cs)) {
return (0);
}
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->cardmsg = &Gazel_card_msg;
switch (cs->subtyp) {
case R647:
case R685:
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
gazel_reset(cs);
cs->card_ops = &gazel_ops;
ISACVersion(cs, "Gazel:");
......@@ -696,9 +659,11 @@ setup_gazel(struct IsdnCard *card)
break;
case R742:
case R753:
cs->dc_hw_ops = &ipac_dc_ops;
cs->bc_hw_ops = &ipac_bc_ops;
gazel_ipac_reset(cs);
cs->card_ops = &gazel_ipac_ops;
val = readreg_ipac(cs, IPAC_ID);
val = ipac_read(cs, IPAC_ID);
printk(KERN_INFO "Gazel: IPAC version %x\n", val);
break;
}
......
......@@ -27,3 +27,71 @@
#define IPAC_PCFG 0xCA
#define IPAC_SCFG 0xCB
#define IPAC_TIMR2 0xCC
/* Macro to build the needed D- and B-Channel access routines given
* access functions for the IPAC */
#define BUILD_IPAC_OPS(ipac) \
\
static u8 \
ipac ## _dc_read(struct IsdnCardState *cs, u8 offset) \
{ \
return ipac ## _read(cs, offset+0x80); \
} \
\
static void \
ipac ## _dc_write(struct IsdnCardState *cs, u8 offset, u8 value) \
{ \
ipac ## _write(cs, offset+0x80, value); \
} \
\
static void \
ipac ## _dc_read_fifo(struct IsdnCardState *cs, u8 * data, int size) \
{ \
ipac ## _readfifo(cs, 0x80, data, size); \
} \
\
static void \
ipac ## _dc_write_fifo(struct IsdnCardState *cs, u8 * data, int size) \
{ \
ipac ## _writefifo(cs, 0x80, data, size); \
} \
\
static struct dc_hw_ops ipac ## _dc_ops = { \
.read_reg = ipac ## _dc_read, \
.write_reg = ipac ## _dc_write, \
.read_fifo = ipac ## _dc_read_fifo, \
.write_fifo = ipac ## _dc_write_fifo, \
}; \
\
static u8 \
ipac ## _bc_read(struct IsdnCardState *cs, int hscx, u8 offset) \
{ \
return ipac ## _read(cs, offset + (hscx ? 0x40 : 0)); \
} \
\
static void \
ipac ## _bc_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value) \
{ \
ipac ## _write(cs, offset + (hscx ? 0x40 : 0), value); \
} \
\
static void \
ipac ## _bc_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size) \
{ \
ipac ## _readfifo(cs, hscx ? 0x40 : 0, data, size); \
} \
\
static void \
ipac ## _bc_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)\
{ \
ipac ## _writefifo(cs, hscx ? 0x40 : 0, data, size); \
} \
\
static struct bc_hw_ops ipac ## _bc_ops = { \
.read_reg = ipac ## _bc_read, \
.write_reg = ipac ## _bc_write, \
.read_fifo = ipac ## _bc_read_fifo, \
.write_fifo = ipac ## _bc_write_fifo, \
}
......@@ -188,37 +188,6 @@ static struct dc_hw_ops isac_ops = {
.write_fifo = isac_write_fifo,
};
static u8
ipac_dc_read(struct IsdnCardState *cs, u8 offset)
{
return readreg(cs, cs->hw.sedl.isac, offset+0x80);
}
static void
ipac_dc_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
writereg(cs, cs->hw.sedl.isac, offset+0x80, value);
}
static void
ipac_dc_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
readfifo(cs, cs->hw.sedl.isac, 0x80, data, size);
}
static void
ipac_dc_write_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
writefifo(cs, cs->hw.sedl.isac, 0x80, data, size);
}
static struct dc_hw_ops ipac_dc_ops = {
.read_reg = ipac_dc_read,
.write_reg = ipac_dc_write,
.read_fifo = ipac_dc_read_fifo,
.write_fifo = ipac_dc_write_fifo,
};
static u8
hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
{
......@@ -250,6 +219,36 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static inline u8
ipac_read(struct IsdnCardState *cs, u8 offset)
{
return readreg(cs, cs->hw.sedl.isac, offset);
}
static inline void
ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
writereg(cs, cs->hw.sedl.isac, offset, value);
}
static inline void
ipac_readfifo(struct IsdnCardState *cs, u8 offset, u8 *data, int size)
{
readfifo(cs, cs->hw.sedl.isac, offset, data, size);
}
static inline void
ipac_writefifo(struct IsdnCardState *cs, u8 offset, u8 *data, int size)
{
writefifo(cs, cs->hw.sedl.isac, offset, data, size);
}
/* This will generate ipac_dc_ops and ipac_bc_ops using the functions
* above */
BUILD_IPAC_OPS(ipac);
/* ISAR access routines
* mode = 0 access with IRQ on
* mode = 1 access with IRQ off
......@@ -299,18 +298,6 @@ sedlbauer_interrupt(int intno, void *dev_id, struct pt_regs *regs)
hscxisac_irq(intno, dev_id, regs);
}
static u8
ipac_read(struct IsdnCardState *cs, u8 offset)
{
return ipac_dc_read(cs, offset - 0x80);
}
static void
ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
ipac_dc_write(cs, offset - 0x80, value);
}
static void
sedlbauer_ipac_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
......@@ -713,7 +700,6 @@ setup_sedlbauer(struct IsdnCard *card)
cs->hw.sedl.cfg_reg + bytecnt,
cs->irq);
cs->bc_hw_ops = &hscx_ops;
cs->cardmsg = &Sedl_card_msg;
/*
......@@ -760,6 +746,7 @@ setup_sedlbauer(struct IsdnCard *card)
}
test_and_set_bit(HW_IPAC, &cs->HW_Flags);
cs->dc_hw_ops = &ipac_dc_ops;
cs->bc_hw_ops = &ipac_bc_ops;
cs->card_ops = &sedlbauer_ipac_ops;
val = readreg(cs, cs->hw.sedl.isac, IPAC_ID);
......@@ -817,6 +804,7 @@ setup_sedlbauer(struct IsdnCard *card)
cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF;
}
cs->card_ops = &sedlbauer_ops;
cs->bc_hw_ops = &hscx_ops;
ISACVersion(cs, "Sedlbauer:");
if (HscxVersion(cs, "Sedlbauer:")) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment