Commit d1d60dbd authored by John W. Linville's avatar John W. Linville Committed by Jeff Garzik

[sound/oss i810] add MMIO DSP support

Enclosed is a patch for the i810_audio OSS driver to support using
memory-mapped I/O for those chipsets that support it.

 o Added a family of macros -- I810_IOREADx() and I810_IOWRITEx() -- that
key off the existing card->use_mmio flag to select between using readx/writex
or inx/outx for I/O operations.

 o Converted existing inx/outx invocations to use
I810_IOREADx/I810_IOWRITEx instead.

 o Changed GET_CIV(), GET_LVI, and CIV_TO_LVI() not only to use
I810_IOREADx/I810_IOWRITEx but also to take "card" (i.e. struct i810_card)
paramter.

 o Removed check for "Pure MMIO interfaces" in i810_probe() -- replaced w/
(relocated) check for no I/O resources available.
parent 3ac5a367
...@@ -450,12 +450,34 @@ struct i810_card { ...@@ -450,12 +450,34 @@ struct i810_card {
/* extract register offset from codec struct */ /* extract register offset from codec struct */
#define IO_REG_OFF(codec) (((struct i810_card *) codec->private_data)->ac97_id_map[codec->id]) #define IO_REG_OFF(codec) (((struct i810_card *) codec->private_data)->ac97_id_map[codec->id])
#define GET_CIV(port) MODULOP2(inb((port) + OFF_CIV), SG_LEN) #define I810_IOREAD(size, type, card, off) \
#define GET_LVI(port) MODULOP2(inb((port) + OFF_LVI), SG_LEN) ({ \
type val; \
if (card->use_mmio) val=read##size(card->iobase_mmio+off); \
else val=in##size(card->iobase+off); \
val; \
})
#define I810_IOREADL(card, off) I810_IOREAD(l, u32, card, off)
#define I810_IOREADW(card, off) I810_IOREAD(w, u16, card, off)
#define I810_IOREADB(card, off) I810_IOREAD(b, u8, card, off)
#define I810_IOWRITE(size, val, card, off) \
({ \
if (card->use_mmio) write##size(val, card->iobase_mmio+off); \
else out##size(val, card->iobase+off); \
})
#define I810_IOWRITEL(val, card, off) I810_IOWRITE(l, val, card, off)
#define I810_IOWRITEW(val, card, off) I810_IOWRITE(w, val, card, off)
#define I810_IOWRITEB(val, card, off) I810_IOWRITE(b, val, card, off)
#define GET_CIV(card, port) MODULOP2(I810_IOREADB((card), (port) + OFF_CIV), SG_LEN)
#define GET_LVI(card, port) MODULOP2(I810_IOREADB((card), (port) + OFF_LVI), SG_LEN)
/* set LVI from CIV */ /* set LVI from CIV */
#define CIV_TO_LVI(port, off) \ #define CIV_TO_LVI(card, port, off) \
outb(MODULOP2(GET_CIV((port)) + (off), SG_LEN), (port) + OFF_LVI) I810_IOWRITEB(MODULOP2(GET_CIV((card), (port)) + (off), SG_LEN), (card), (port) + OFF_LVI)
static struct i810_card *devs = NULL; static struct i810_card *devs = NULL;
...@@ -714,9 +736,9 @@ static inline unsigned i810_get_dma_addr(struct i810_state *state, int rec) ...@@ -714,9 +736,9 @@ static inline unsigned i810_get_dma_addr(struct i810_state *state, int rec)
return 0; return 0;
if (rec) if (rec)
port = state->card->iobase + dmabuf->read_channel->port; port = dmabuf->read_channel->port;
else else
port = state->card->iobase + dmabuf->write_channel->port; port = dmabuf->write_channel->port;
if(state->card->pci_id == PCI_DEVICE_ID_SI_7012) { if(state->card->pci_id == PCI_DEVICE_ID_SI_7012) {
port_picb = port + OFF_SR; port_picb = port + OFF_SR;
...@@ -725,8 +747,8 @@ static inline unsigned i810_get_dma_addr(struct i810_state *state, int rec) ...@@ -725,8 +747,8 @@ static inline unsigned i810_get_dma_addr(struct i810_state *state, int rec)
port_picb = port + OFF_PICB; port_picb = port + OFF_PICB;
do { do {
civ = GET_CIV(port); civ = GET_CIV(state->card, port);
offset = inw(port_picb); offset = I810_IOREADW(state->card, port_picb);
/* Must have a delay here! */ /* Must have a delay here! */
if(offset == 0) if(offset == 0)
udelay(1); udelay(1);
...@@ -745,7 +767,7 @@ static inline unsigned i810_get_dma_addr(struct i810_state *state, int rec) ...@@ -745,7 +767,7 @@ static inline unsigned i810_get_dma_addr(struct i810_state *state, int rec)
* that we won't have to worry about the chip still being * that we won't have to worry about the chip still being
* out of sync with reality ;-) * out of sync with reality ;-)
*/ */
} while (civ != GET_CIV(port) || offset != inw(port_picb)); } while (civ != GET_CIV(state->card, port) || offset != I810_IOREADW(state->card, port_picb));
return (((civ + 1) * dmabuf->fragsize - (bytes * offset)) return (((civ + 1) * dmabuf->fragsize - (bytes * offset))
% dmabuf->dmasize); % dmabuf->dmasize);
...@@ -758,15 +780,15 @@ static inline void __stop_adc(struct i810_state *state) ...@@ -758,15 +780,15 @@ static inline void __stop_adc(struct i810_state *state)
struct i810_card *card = state->card; struct i810_card *card = state->card;
dmabuf->enable &= ~ADC_RUNNING; dmabuf->enable &= ~ADC_RUNNING;
outb(0, card->iobase + PI_CR); I810_IOWRITEB(0, card, PI_CR);
// wait for the card to acknowledge shutdown // wait for the card to acknowledge shutdown
while( inb(card->iobase + PI_CR) != 0 ) ; while( I810_IOREADB(card, PI_CR) != 0 ) ;
// now clear any latent interrupt bits (like the halt bit) // now clear any latent interrupt bits (like the halt bit)
if(card->pci_id == PCI_DEVICE_ID_SI_7012) if(card->pci_id == PCI_DEVICE_ID_SI_7012)
outb( inb(card->iobase + PI_PICB), card->iobase + PI_PICB ); I810_IOWRITEB( I810_IOREADB(card, PI_PICB), card, PI_PICB );
else else
outb( inb(card->iobase + PI_SR), card->iobase + PI_SR ); I810_IOWRITEB( I810_IOREADB(card, PI_SR), card, PI_SR );
outl( inl(card->iobase + GLOB_STA) & INT_PI, card->iobase + GLOB_STA); I810_IOWRITEL( I810_IOREADL(card, GLOB_STA) & INT_PI, card, GLOB_STA);
} }
static void stop_adc(struct i810_state *state) static void stop_adc(struct i810_state *state)
...@@ -787,7 +809,7 @@ static inline void __start_adc(struct i810_state *state) ...@@ -787,7 +809,7 @@ static inline void __start_adc(struct i810_state *state)
(dmabuf->trigger & PCM_ENABLE_INPUT)) { (dmabuf->trigger & PCM_ENABLE_INPUT)) {
dmabuf->enable |= ADC_RUNNING; dmabuf->enable |= ADC_RUNNING;
// Interrupt enable, LVI enable, DMA enable // Interrupt enable, LVI enable, DMA enable
outb(0x10 | 0x04 | 0x01, state->card->iobase + PI_CR); I810_IOWRITEB(0x10 | 0x04 | 0x01, state->card, PI_CR);
} }
} }
...@@ -808,15 +830,15 @@ static inline void __stop_dac(struct i810_state *state) ...@@ -808,15 +830,15 @@ static inline void __stop_dac(struct i810_state *state)
struct i810_card *card = state->card; struct i810_card *card = state->card;
dmabuf->enable &= ~DAC_RUNNING; dmabuf->enable &= ~DAC_RUNNING;
outb(0, card->iobase + PO_CR); I810_IOWRITEB(0, card, PO_CR);
// wait for the card to acknowledge shutdown // wait for the card to acknowledge shutdown
while( inb(card->iobase + PO_CR) != 0 ) ; while( I810_IOREADB(card, PO_CR) != 0 ) ;
// now clear any latent interrupt bits (like the halt bit) // now clear any latent interrupt bits (like the halt bit)
if(card->pci_id == PCI_DEVICE_ID_SI_7012) if(card->pci_id == PCI_DEVICE_ID_SI_7012)
outb( inb(card->iobase + PO_PICB), card->iobase + PO_PICB ); I810_IOWRITEB( I810_IOREADB(card, PO_PICB), card, PO_PICB );
else else
outb( inb(card->iobase + PO_SR), card->iobase + PO_SR ); I810_IOWRITEB( I810_IOREADB(card, PO_SR), card, PO_SR );
outl( inl(card->iobase + GLOB_STA) & INT_PO, card->iobase + GLOB_STA); I810_IOWRITEL( I810_IOREADL(card, GLOB_STA) & INT_PO, card, GLOB_STA);
} }
static void stop_dac(struct i810_state *state) static void stop_dac(struct i810_state *state)
...@@ -837,7 +859,7 @@ static inline void __start_dac(struct i810_state *state) ...@@ -837,7 +859,7 @@ static inline void __start_dac(struct i810_state *state)
(dmabuf->trigger & PCM_ENABLE_OUTPUT)) { (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
dmabuf->enable |= DAC_RUNNING; dmabuf->enable |= DAC_RUNNING;
// Interrupt enable, LVI enable, DMA enable // Interrupt enable, LVI enable, DMA enable
outb(0x10 | 0x04 | 0x01, state->card->iobase + PO_CR); I810_IOWRITEB(0x10 | 0x04 | 0x01, state->card, PO_CR);
} }
} }
static void start_dac(struct i810_state *state) static void start_dac(struct i810_state *state)
...@@ -1000,12 +1022,12 @@ static int prog_dmabuf(struct i810_state *state, unsigned rec) ...@@ -1000,12 +1022,12 @@ static int prog_dmabuf(struct i810_state *state, unsigned rec)
sg++; sg++;
} }
spin_lock_irqsave(&state->card->lock, flags); spin_lock_irqsave(&state->card->lock, flags);
outb(2, state->card->iobase+c->port+OFF_CR); /* reset DMA machine */ I810_IOWRITEB(2, state->card, c->port+OFF_CR); /* reset DMA machine */
while( inb(state->card->iobase+c->port+OFF_CR) & 0x02 ) ; while( I810_IOREADB(state->card, c->port+OFF_CR) & 0x02 ) ;
outl((u32)state->card->chandma + I810_IOWRITEL((u32)state->card->chandma +
c->num*sizeof(struct i810_channel), c->num*sizeof(struct i810_channel),
state->card->iobase+c->port+OFF_BDBAR); state->card, c->port+OFF_BDBAR);
CIV_TO_LVI(state->card->iobase+c->port, 0); CIV_TO_LVI(state->card, c->port, 0);
spin_unlock_irqrestore(&state->card->lock, flags); spin_unlock_irqrestore(&state->card->lock, flags);
...@@ -1037,14 +1059,13 @@ static void __i810_update_lvi(struct i810_state *state, int rec) ...@@ -1037,14 +1059,13 @@ static void __i810_update_lvi(struct i810_state *state, int rec)
void (*start)(struct i810_state *); void (*start)(struct i810_state *);
count = dmabuf->count; count = dmabuf->count;
port = state->card->iobase;
if (rec) { if (rec) {
port += dmabuf->read_channel->port; port = dmabuf->read_channel->port;
trigger = PCM_ENABLE_INPUT; trigger = PCM_ENABLE_INPUT;
start = __start_adc; start = __start_adc;
count = dmabuf->dmasize - count; count = dmabuf->dmasize - count;
} else { } else {
port += dmabuf->write_channel->port; port = dmabuf->write_channel->port;
trigger = PCM_ENABLE_OUTPUT; trigger = PCM_ENABLE_OUTPUT;
start = __start_dac; start = __start_dac;
} }
...@@ -1059,14 +1080,14 @@ static void __i810_update_lvi(struct i810_state *state, int rec) ...@@ -1059,14 +1080,14 @@ static void __i810_update_lvi(struct i810_state *state, int rec)
return; return;
start(state); start(state);
while (!(inb(port + OFF_CR) & ((1<<4) | (1<<2)))) while (!(I810_IOREADB(state->card, port + OFF_CR) & ((1<<4) | (1<<2))))
; ;
} }
/* MASKP2(swptr, fragsize) - 1 is the tail of our transfer */ /* MASKP2(swptr, fragsize) - 1 is the tail of our transfer */
x = MODULOP2(MASKP2(dmabuf->swptr, fragsize) - 1, dmabuf->dmasize); x = MODULOP2(MASKP2(dmabuf->swptr, fragsize) - 1, dmabuf->dmasize);
x >>= dmabuf->fragshift; x >>= dmabuf->fragshift;
outb(x, port + OFF_LVI); I810_IOWRITEB(x, state->card, port + OFF_LVI);
} }
static void i810_update_lvi(struct i810_state *state, int rec) static void i810_update_lvi(struct i810_state *state, int rec)
...@@ -1108,8 +1129,8 @@ static void i810_update_ptr(struct i810_state *state) ...@@ -1108,8 +1129,8 @@ static void i810_update_ptr(struct i810_state *state)
/* this is normal for the end of a read */ /* this is normal for the end of a read */
/* only give an error if we went past the */ /* only give an error if we went past the */
/* last valid sg entry */ /* last valid sg entry */
if (GET_CIV(state->card->iobase + PI_BASE) != if (GET_CIV(state->card, PI_BASE) !=
GET_LVI(state->card->iobase + PI_BASE)) { GET_LVI(state->card, PI_BASE)) {
printk(KERN_WARNING "i810_audio: DMA overrun on read\n"); printk(KERN_WARNING "i810_audio: DMA overrun on read\n");
dmabuf->error++; dmabuf->error++;
} }
...@@ -1133,13 +1154,13 @@ static void i810_update_ptr(struct i810_state *state) ...@@ -1133,13 +1154,13 @@ static void i810_update_ptr(struct i810_state *state)
/* this is normal for the end of a write */ /* this is normal for the end of a write */
/* only give an error if we went past the */ /* only give an error if we went past the */
/* last valid sg entry */ /* last valid sg entry */
if (GET_CIV(state->card->iobase + PO_BASE) != if (GET_CIV(state->card, PO_BASE) !=
GET_LVI(state->card->iobase + PO_BASE)) { GET_LVI(state->card, PO_BASE)) {
printk(KERN_WARNING "i810_audio: DMA overrun on write\n"); printk(KERN_WARNING "i810_audio: DMA overrun on write\n");
printk("i810_audio: CIV %d, LVI %d, hwptr %x, " printk("i810_audio: CIV %d, LVI %d, hwptr %x, "
"count %d\n", "count %d\n",
GET_CIV(state->card->iobase + PO_BASE), GET_CIV(state->card, PO_BASE),
GET_LVI(state->card->iobase + PO_BASE), GET_LVI(state->card, PO_BASE),
dmabuf->hwptr, dmabuf->count); dmabuf->hwptr, dmabuf->count);
dmabuf->error++; dmabuf->error++;
} }
...@@ -1287,7 +1308,7 @@ static void i810_channel_interrupt(struct i810_card *card) ...@@ -1287,7 +1308,7 @@ static void i810_channel_interrupt(struct i810_card *card)
struct i810_state *state = card->states[i]; struct i810_state *state = card->states[i];
struct i810_channel *c; struct i810_channel *c;
struct dmabuf *dmabuf; struct dmabuf *dmabuf;
unsigned long port = card->iobase; unsigned long port;
u16 status; u16 status;
if(!state) if(!state)
...@@ -1302,12 +1323,12 @@ static void i810_channel_interrupt(struct i810_card *card) ...@@ -1302,12 +1323,12 @@ static void i810_channel_interrupt(struct i810_card *card)
} else /* This can occur going from R/W to close */ } else /* This can occur going from R/W to close */
continue; continue;
port+=c->port; port = c->port;
if(card->pci_id == PCI_DEVICE_ID_SI_7012) if(card->pci_id == PCI_DEVICE_ID_SI_7012)
status = inw(port + OFF_PICB); status = I810_IOREADW(card, port + OFF_PICB);
else else
status = inw(port + OFF_SR); status = I810_IOREADW(card, port + OFF_SR);
#ifdef DEBUG_INTERRUPTS #ifdef DEBUG_INTERRUPTS
printk("NUM %d PORT %X IRQ ( ST%d ", c->num, c->port, status); printk("NUM %d PORT %X IRQ ( ST%d ", c->num, c->port, status);
...@@ -1340,7 +1361,7 @@ static void i810_channel_interrupt(struct i810_card *card) ...@@ -1340,7 +1361,7 @@ static void i810_channel_interrupt(struct i810_card *card)
if(dmabuf->enable & ADC_RUNNING) if(dmabuf->enable & ADC_RUNNING)
count = dmabuf->dmasize - count; count = dmabuf->dmasize - count;
if (count >= (int)dmabuf->fragsize) { if (count >= (int)dmabuf->fragsize) {
outb(inb(port+OFF_CR) | 1, port+OFF_CR); I810_IOWRITEB(I810_IOREADB(card, port+OFF_CR) | 1, card, port+OFF_CR);
#ifdef DEBUG_INTERRUPTS #ifdef DEBUG_INTERRUPTS
printk(" CONTINUE "); printk(" CONTINUE ");
#endif #endif
...@@ -1356,9 +1377,9 @@ static void i810_channel_interrupt(struct i810_card *card) ...@@ -1356,9 +1377,9 @@ static void i810_channel_interrupt(struct i810_card *card)
} }
} }
if(card->pci_id == PCI_DEVICE_ID_SI_7012) if(card->pci_id == PCI_DEVICE_ID_SI_7012)
outw(status & DMA_INT_MASK, port + OFF_PICB); I810_IOWRITEW(status & DMA_INT_MASK, card, port + OFF_PICB);
else else
outw(status & DMA_INT_MASK, port + OFF_SR); I810_IOWRITEW(status & DMA_INT_MASK, card, port + OFF_SR);
} }
#ifdef DEBUG_INTERRUPTS #ifdef DEBUG_INTERRUPTS
printk(")\n"); printk(")\n");
...@@ -1372,7 +1393,7 @@ static irqreturn_t i810_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1372,7 +1393,7 @@ static irqreturn_t i810_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_lock(&card->lock); spin_lock(&card->lock);
status = inl(card->iobase + GLOB_STA); status = I810_IOREADL(card, GLOB_STA);
if(!(status & INT_MASK)) if(!(status & INT_MASK))
{ {
...@@ -1384,7 +1405,7 @@ static irqreturn_t i810_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1384,7 +1405,7 @@ static irqreturn_t i810_interrupt(int irq, void *dev_id, struct pt_regs *regs)
i810_channel_interrupt(card); i810_channel_interrupt(card);
/* clear 'em */ /* clear 'em */
outl(status & INT_MASK, card->iobase + GLOB_STA); I810_IOWRITEL(status & INT_MASK, card, GLOB_STA);
spin_unlock(&card->lock); spin_unlock(&card->lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -1784,13 +1805,13 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -1784,13 +1805,13 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
__stop_adc(state); __stop_adc(state);
} }
if (c != NULL) { if (c != NULL) {
outb(2, state->card->iobase+c->port+OFF_CR); /* reset DMA machine */ I810_IOWRITEB(2, state->card, c->port+OFF_CR); /* reset DMA machine */
while ( inb(state->card->iobase+c->port+OFF_CR) & 2 ) while ( I810_IOREADB(state->card, c->port+OFF_CR) & 2 )
cpu_relax(); cpu_relax();
outl((u32)state->card->chandma + I810_IOWRITEL((u32)state->card->chandma +
c->num*sizeof(struct i810_channel), c->num*sizeof(struct i810_channel),
state->card->iobase+c->port+OFF_BDBAR); state->card, c->port+OFF_BDBAR);
CIV_TO_LVI(state->card->iobase+c->port, 0); CIV_TO_LVI(state->card, c->port, 0);
} }
spin_unlock_irqrestore(&state->card->lock, flags); spin_unlock_irqrestore(&state->card->lock, flags);
...@@ -1920,7 +1941,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -1920,7 +1941,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
/* Global Status and Global Control register are now */ /* Global Status and Global Control register are now */
/* used to indicate this. */ /* used to indicate this. */
i_glob_cnt = inl(state->card->iobase + GLOB_CNT); i_glob_cnt = I810_IOREADL(state->card, GLOB_CNT);
/* Current # of channels enabled */ /* Current # of channels enabled */
if ( i_glob_cnt & 0x0100000 ) if ( i_glob_cnt & 0x0100000 )
...@@ -1932,14 +1953,14 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -1932,14 +1953,14 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch ( val ) { switch ( val ) {
case 2: /* 2 channels is always supported */ case 2: /* 2 channels is always supported */
outl(i_glob_cnt & 0xffcfffff, I810_IOWRITEL(i_glob_cnt & 0xffcfffff,
state->card->iobase + GLOB_CNT); state->card, GLOB_CNT);
/* Do we need to change mixer settings???? */ /* Do we need to change mixer settings???? */
break; break;
case 4: /* Supported on some chipsets, better check first */ case 4: /* Supported on some chipsets, better check first */
if ( state->card->channels >= 4 ) { if ( state->card->channels >= 4 ) {
outl((i_glob_cnt & 0xffcfffff) | 0x100000, I810_IOWRITEL((i_glob_cnt & 0xffcfffff) | 0x100000,
state->card->iobase + GLOB_CNT); state->card, GLOB_CNT);
/* Do we need to change mixer settings??? */ /* Do we need to change mixer settings??? */
} else { } else {
val = ret; val = ret;
...@@ -1947,8 +1968,8 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -1947,8 +1968,8 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
break; break;
case 6: /* Supported on some chipsets, better check first */ case 6: /* Supported on some chipsets, better check first */
if ( state->card->channels >= 6 ) { if ( state->card->channels >= 6 ) {
outl((i_glob_cnt & 0xffcfffff) | 0x200000, I810_IOWRITEL((i_glob_cnt & 0xffcfffff) | 0x200000,
state->card->iobase + GLOB_CNT); state->card, GLOB_CNT);
/* Do we need to change mixer settings??? */ /* Do we need to change mixer settings??? */
} else { } else {
val = ret; val = ret;
...@@ -2477,8 +2498,8 @@ static int i810_open(struct inode *inode, struct file *file) ...@@ -2477,8 +2498,8 @@ static int i810_open(struct inode *inode, struct file *file)
} else { } else {
i810_set_dac_rate(state, 8000); i810_set_dac_rate(state, 8000);
/* Put the ACLink in 2 channel mode by default */ /* Put the ACLink in 2 channel mode by default */
i = inl(card->iobase + GLOB_CNT); i = I810_IOREADL(card, GLOB_CNT);
outl(i & 0xffcfffff, card->iobase + GLOB_CNT); I810_IOWRITEL(i & 0xffcfffff, card, GLOB_CNT);
} }
} }
...@@ -2569,7 +2590,7 @@ static u16 i810_ac97_get_io(struct ac97_codec *dev, u8 reg) ...@@ -2569,7 +2590,7 @@ static u16 i810_ac97_get_io(struct ac97_codec *dev, u8 reg)
int count = 100; int count = 100;
u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f); u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f);
while(count-- && (inb(card->iobase + CAS) & 1)) while(count-- && (I810_IOREADB(card, CAS) & 1))
udelay(1); udelay(1);
return inw(card->ac97base + reg_set); return inw(card->ac97base + reg_set);
...@@ -2597,7 +2618,7 @@ static void i810_ac97_set_io(struct ac97_codec *dev, u8 reg, u16 data) ...@@ -2597,7 +2618,7 @@ static void i810_ac97_set_io(struct ac97_codec *dev, u8 reg, u16 data)
int count = 100; int count = 100;
u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f); u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f);
while(count-- && (inb(card->iobase + CAS) & 1)) while(count-- && (I810_IOREADB(card, CAS) & 1))
udelay(1); udelay(1);
outw(data, card->ac97base + reg_set); outw(data, card->ac97base + reg_set);
...@@ -2686,7 +2707,7 @@ static /*const*/ struct file_operations i810_mixer_fops = { ...@@ -2686,7 +2707,7 @@ static /*const*/ struct file_operations i810_mixer_fops = {
static inline int i810_ac97_exists(struct i810_card *card, int ac97_number) static inline int i810_ac97_exists(struct i810_card *card, int ac97_number)
{ {
u32 reg = inl(card->iobase + GLOB_STA); u32 reg = I810_IOREADL(card, GLOB_STA);
switch (ac97_number) { switch (ac97_number) {
case 0: case 0:
return reg & (1<<8); return reg & (1<<8);
...@@ -2757,7 +2778,7 @@ static inline int ich_use_mmio(struct i810_card *card) ...@@ -2757,7 +2778,7 @@ static inline int ich_use_mmio(struct i810_card *card)
static int i810_ac97_power_up_bus(struct i810_card *card) static int i810_ac97_power_up_bus(struct i810_card *card)
{ {
u32 reg = inl(card->iobase + GLOB_CNT); u32 reg = I810_IOREADL(card, GLOB_CNT);
int i; int i;
int primary_codec_id = 0; int primary_codec_id = 0;
...@@ -2769,14 +2790,14 @@ static int i810_ac97_power_up_bus(struct i810_card *card) ...@@ -2769,14 +2790,14 @@ static int i810_ac97_power_up_bus(struct i810_card *card)
reg&=~8; /* ACLink on */ reg&=~8; /* ACLink on */
/* At this point we deassert AC_RESET # */ /* At this point we deassert AC_RESET # */
outl(reg , card->iobase + GLOB_CNT); I810_IOWRITEL(reg , card, GLOB_CNT);
/* We must now allow time for the Codec initialisation. /* We must now allow time for the Codec initialisation.
600mS is the specified time */ 600mS is the specified time */
for(i=0;i<10;i++) for(i=0;i<10;i++)
{ {
if((inl(card->iobase+GLOB_CNT)&4)==0) if((I810_IOREADL(card, GLOB_CNT)&4)==0)
break; break;
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
...@@ -2796,7 +2817,8 @@ static int i810_ac97_power_up_bus(struct i810_card *card) ...@@ -2796,7 +2817,8 @@ static int i810_ac97_power_up_bus(struct i810_card *card)
* before we start doing DMA stuff * before we start doing DMA stuff
*/ */
/* see i810_ac97_init for the next 7 lines (jsaw) */ /* see i810_ac97_init for the next 7 lines (jsaw) */
inw(card->ac97base); if (card->use_mmio) readw(card->ac97base_mmio);
else inw(card->ac97base);
if (ich_use_mmio(card)) { if (ich_use_mmio(card)) {
primary_codec_id = (int) readl(card->iobase_mmio + SDM) & 0x3; primary_codec_id = (int) readl(card->iobase_mmio + SDM) & 0x3;
printk(KERN_INFO "i810_audio: Primary codec has ID %d\n", printk(KERN_INFO "i810_audio: Primary codec has ID %d\n",
...@@ -2814,7 +2836,8 @@ static int i810_ac97_power_up_bus(struct i810_card *card) ...@@ -2814,7 +2836,8 @@ static int i810_ac97_power_up_bus(struct i810_card *card)
else else
printk("no response.\n"); printk("no response.\n");
} }
inw(card->ac97base); if (card->use_mmio) readw(card->ac97base_mmio);
else inw(card->ac97base);
return 1; return 1;
} }
...@@ -2839,15 +2862,15 @@ static int __devinit i810_ac97_init(struct i810_card *card) ...@@ -2839,15 +2862,15 @@ static int __devinit i810_ac97_init(struct i810_card *card)
/* to check.... */ /* to check.... */
card->channels = 2; card->channels = 2;
reg = inl(card->iobase + GLOB_STA); reg = I810_IOREADL(card, GLOB_STA);
if ( reg & 0x0200000 ) if ( reg & 0x0200000 )
card->channels = 6; card->channels = 6;
else if ( reg & 0x0100000 ) else if ( reg & 0x0100000 )
card->channels = 4; card->channels = 4;
printk(KERN_INFO "i810_audio: Audio Controller supports %d channels.\n", card->channels); printk(KERN_INFO "i810_audio: Audio Controller supports %d channels.\n", card->channels);
printk(KERN_INFO "i810_audio: Defaulting to base 2 channel mode.\n"); printk(KERN_INFO "i810_audio: Defaulting to base 2 channel mode.\n");
reg = inl(card->iobase + GLOB_CNT); reg = I810_IOREADL(card, GLOB_CNT);
outl(reg & 0xffcfffff, card->iobase + GLOB_CNT); I810_IOWRITEL(reg & 0xffcfffff, card, GLOB_CNT);
for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++)
card->ac97_codec[num_ac97] = NULL; card->ac97_codec[num_ac97] = NULL;
...@@ -3062,7 +3085,7 @@ static void __devinit i810_configure_clocking (void) ...@@ -3062,7 +3085,7 @@ static void __devinit i810_configure_clocking (void)
goto config_out; goto config_out;
} }
dmabuf->count = dmabuf->dmasize; dmabuf->count = dmabuf->dmasize;
CIV_TO_LVI(card->iobase+dmabuf->write_channel->port, -1); CIV_TO_LVI(card, dmabuf->write_channel->port, -1);
local_irq_save(flags); local_irq_save(flags);
start_dac(state); start_dac(state);
offset = i810_get_dma_addr(state, 0); offset = i810_get_dma_addr(state, 0);
...@@ -3106,13 +3129,6 @@ static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device ...@@ -3106,13 +3129,6 @@ static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device
return -ENODEV; return -ENODEV;
} }
if( pci_resource_start(pci_dev, 1) == 0)
{
/* MMIO only ICH5 .. here be dragons .. */
printk(KERN_ERR "i810_audio: Pure MMIO interfaces not yet supported.\n");
return -ENODEV;
}
if ((card = kmalloc(sizeof(struct i810_card), GFP_KERNEL)) == NULL) { if ((card = kmalloc(sizeof(struct i810_card), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "i810_audio: out of memory\n"); printk(KERN_ERR "i810_audio: out of memory\n");
return -ENOMEM; return -ENOMEM;
...@@ -3125,6 +3141,11 @@ static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device ...@@ -3125,6 +3141,11 @@ static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device
card->ac97base = pci_resource_start (pci_dev, 0); card->ac97base = pci_resource_start (pci_dev, 0);
card->iobase = pci_resource_start (pci_dev, 1); card->iobase = pci_resource_start (pci_dev, 1);
if (!(card->ac97base) || !(card->iobase)) {
card->ac97base = 0;
card->iobase = 0;
}
/* if chipset could have mmio capability, check it */ /* if chipset could have mmio capability, check it */
if (card_cap[pci_id->driver_data].flags & CAP_MMIO) { if (card_cap[pci_id->driver_data].flags & CAP_MMIO) {
card->ac97base_mmio_phys = pci_resource_start (pci_dev, 2); card->ac97base_mmio_phys = pci_resource_start (pci_dev, 2);
...@@ -3139,6 +3160,11 @@ static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device ...@@ -3139,6 +3160,11 @@ static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device
} }
} }
if (!(card->use_mmio) && !(card->iobase)) {
printk(KERN_ERR "i810_audio: No I/O resources available.\n");
goto out_mem;
}
card->irq = pci_dev->irq; card->irq = pci_dev->irq;
card->next = devs; card->next = devs;
card->magic = I810_CARD_MAGIC; card->magic = I810_CARD_MAGIC;
......
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