* [PATCH 2.4.20-pre4-ac2] fix broken i810_audio DMA (?)
@ 2002-08-29 1:39 Juergen Sawinski
2002-08-29 16:26 ` Juergen Sawinski
0 siblings, 1 reply; 5+ messages in thread
From: Juergen Sawinski @ 2002-08-29 1:39 UTC (permalink / raw)
To: linux-kernel@vger; +Cc: Alan Cox, Jim Radford, Andris Pavenis, Doug Ledford
Changes:
-remove dma reset in stop_{dac,adc}
(from ICH4 manual: contents of all Bus master related registers to be
reset; so, probably some registers are not re-initilized properly on
consecutive re-opening of /dev/dsp ???)
-remove writes to OFF_CIV, instead set LVI relative to CIV
and some stuff that was already in the last diff I send to the list:
-implement a codec ID <-> IO register offset mapping
-in i810_ioctl, case SNDCTL_DSP_CHANNELS: only touch bits 20:21
off GLOB_CNT (multichannel capabilities)
-AMD 8111 has 6 hw channels so I must have mmio (but I don't have
any docs to verify this)
-minor fixes
--
Juergen "George" Sawinski
Max-Planck Institute for Medical Research
Dept. of Biomedical Optics
Jahnstr. 29
D-69120 Heidelberg
Germany
Phone: +49-6221-486-308
Fax: +49-6221-486-325
priv.
Phone: +49-6221-418 858
Mobile: +49-171-532 5302
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2.4.20-pre4-ac2] fix broken i810_audio DMA (?)
2002-08-29 1:39 [PATCH 2.4.20-pre4-ac2] fix broken i810_audio DMA (?) Juergen Sawinski
@ 2002-08-29 16:26 ` Juergen Sawinski
2002-08-29 16:43 ` Andris Pavenis
2002-08-29 16:50 ` Jim Radford
0 siblings, 2 replies; 5+ messages in thread
From: Juergen Sawinski @ 2002-08-29 16:26 UTC (permalink / raw)
To: linux-kernel@vger; +Cc: Alan Cox, Jim Radford, Andris Pavenis, Doug Ledford
[-- Attachment #1: Type: text/plain, Size: 1542 bytes --]
F*ck. This time the patch attached.
Thanx Jim.
George
On Thu, 2002-08-29 at 03:39, Juergen Sawinski wrote:
> Changes:
> -remove dma reset in stop_{dac,adc}
> (from ICH4 manual: contents of all Bus master related registers to be
> reset; so, probably some registers are not re-initilized properly on
> consecutive re-opening of /dev/dsp ???)
> -remove writes to OFF_CIV, instead set LVI relative to CIV
>
> and some stuff that was already in the last diff I send to the list:
> -implement a codec ID <-> IO register offset mapping
> -in i810_ioctl, case SNDCTL_DSP_CHANNELS: only touch bits 20:21
> off GLOB_CNT (multichannel capabilities)
> -AMD 8111 has 6 hw channels so I must have mmio (but I don't have
> any docs to verify this)
> -minor fixes
>
> --
> Juergen "George" Sawinski
> Max-Planck Institute for Medical Research
> Dept. of Biomedical Optics
> Jahnstr. 29
> D-69120 Heidelberg
> Germany
>
> Phone: +49-6221-486-308
> Fax: +49-6221-486-325
>
> priv.
> Phone: +49-6221-418 858
> Mobile: +49-171-532 5302
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
Juergen "George" Sawinski
Max-Planck-Institute for Medical Research
Dept. of Biomedical Optics
Jahnstr. 29
D-69120 Heidelberg
Germany
Phone: +49-6221-486-309
Fax: +49-6221-486-325
priv.
Phone: +49-6221-418 848
Mobile: +49-171-532 5302
[-- Attachment #2: diff-pre4-ac2-jsaw-2 --]
[-- Type: text/plain, Size: 10147 bytes --]
--- linux-2.4.20-pre4-ac2/drivers/sound/i810_audio.c Tue Aug 27 21:44:25 2002
+++ jsaw/drivers/sound/i810_audio.c Thu Aug 29 03:18:16 2002
@@ -69,12 +69,12 @@
*
* ICH 4 caveats
*
- * The ICH4 has the feature, that the codec ID may not be congruent
- * with the AC-link channel.
+ * The ICH4 has the feature, that the codec ID doesn't have to be
+ * congruent with the IO connection.
*
- * Right now, the codec ID is not the real codec ID but the AC-link
- * channel. A ID <-> AC-link mapping has still to be implemented.
- *
+ * Therefore, from driver version 0.23 on, there is a "codec ID" <->
+ * "IO register base offset" mapping (card->ac97_id_map) field.
+ *
* Juergen "George" Sawinski (jsaw)
*/
@@ -207,7 +207,7 @@
CAS = 0x34 /* Codec Write Semaphore Register */
};
-ENUM_ENGINE(MC2,4); /* Mic. 2 */
+ENUM_ENGINE(MC2,4); /* Mic In 2 */
ENUM_ENGINE(PI2,5); /* PCM In 2 */
ENUM_ENGINE(SP,6); /* S/PDIF */
@@ -234,8 +234,7 @@
#define INT_GPI (1<<0)
#define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI)
-
-#define DRIVER_VERSION "0.22"
+#define DRIVER_VERSION "0.23"
/* magic numbers to protect our data structures */
#define I810_CARD_MAGIC 0x5072696E /* "Prin" */
@@ -295,7 +294,7 @@
/*@FIXME to be verified*/ { 2, 0x0000 }, /* SI7012 */
/*@FIXME to be verified*/ { 2, 0x0000 }, /* NVIDIA_NFORCE */
/*@FIXME to be verified*/ { 2, 0x0000 }, /* AMD768 */
- /*@FIXME to be verified*/ { 2, 0x0000 }, /* AMD8111 */
+ /*@FIXME to be verified*/ { 3, 0x0001 }, /* AMD8111 */
};
static struct pci_device_id i810_pci_tbl [] __initdata = {
@@ -417,6 +416,7 @@
int dev_audio;
/* structures for abstraction of hardware facilities, codecs, banks and channels*/
+ u16 ac97_id_map[NR_AC97];
struct ac97_codec *ac97_codec[NR_AC97];
struct i810_state *states[NR_HW_CH];
struct i810_channel *channel; /* 1:1 to states[] but diff. lifetime */
@@ -449,6 +449,12 @@
int initializing;
};
+/* extract register offset from codec struct */
+#define IO_REG_OFF(codec) (((struct i810_card *) codec->private_data)->ac97_id_map[codec->id])
+
+/* set LVI from CIV */
+#define CIV_TO_LVI(port, off) outb((inb(port+OFF_CIV)+off) & 31, port+OFF_LVI)
+
static struct i810_card *devs = NULL;
static int i810_open_mixdev(struct inode *inode, struct file *file);
@@ -786,8 +792,6 @@
outb(0, card->iobase + PI_CR);
// wait for the card to acknowledge shutdown
while( inb(card->iobase + PI_CR) != 0 ) ;
- // reset the dma engine now
- outb(0x02, card->iobase + PI_CR);
// now clear any latent interrupt bits (like the halt bit)
if(card->pci_id == PCI_DEVICE_ID_SI_7012)
outb( inb(card->iobase + PI_PICB), card->iobase + PI_PICB );
@@ -838,8 +842,6 @@
outb(0, card->iobase + PO_CR);
// wait for the card to acknowledge shutdown
while( inb(card->iobase + PO_CR) != 0 ) ;
- // reset the dma engine now
- outb(0x02, card->iobase + PO_CR);
// now clear any latent interrupt bits (like the halt bit)
if(card->pci_id == PCI_DEVICE_ID_SI_7012)
outb( inb(card->iobase + PO_PICB), card->iobase + PO_PICB );
@@ -1033,11 +1035,11 @@
}
spin_lock_irqsave(&state->card->lock, flags);
outb(2, state->card->iobase+c->port+OFF_CR); /* reset DMA machine */
+ while( inb(state->card->iobase+c->port+OFF_CR) & 0x02 ) ;
outl((u32)state->card->chandma +
c->num*sizeof(struct i810_channel),
state->card->iobase+c->port+OFF_BDBAR);
- outb(0, state->card->iobase+c->port+OFF_CIV);
- outb(0, state->card->iobase+c->port+OFF_LVI);
+ CIV_TO_LVI(state->card->iobase+c->port, 0);
spin_unlock_irqrestore(&state->card->lock, flags);
@@ -1083,13 +1085,13 @@
if(rec && dmabuf->count < dmabuf->dmasize &&
(dmabuf->trigger & PCM_ENABLE_INPUT))
{
- outb((inb(port+OFF_CIV)+1)&31, port+OFF_LVI);
+ CIV_TO_LVI(port, 1);
__start_adc(state);
while( !(inb(port + OFF_CR) & ((1<<4) | (1<<2))) ) ;
} else if (!rec && dmabuf->count &&
(dmabuf->trigger & PCM_ENABLE_OUTPUT))
{
- outb((inb(port+OFF_CIV)+1)&31, port+OFF_LVI);
+ CIV_TO_LVI(port, 1);
__start_dac(state);
while( !(inb(port + OFF_CR) & ((1<<4) | (1<<2))) ) ;
}
@@ -1802,11 +1804,11 @@
}
if (c != NULL) {
outb(2, state->card->iobase+c->port+OFF_CR); /* reset DMA machine */
+ while ( inb(state->card->iobase+c->port+OFF_CR) & 2 );
outl((u32)state->card->chandma +
c->num*sizeof(struct i810_channel),
state->card->iobase+c->port+OFF_BDBAR);
- outb(0, state->card->iobase+c->port+OFF_CIV);
- outb(0, state->card->iobase+c->port+OFF_LVI);
+ CIV_TO_LVI(state->card->iobase+c->port, 0);
}
spin_unlock_irqrestore(&state->card->lock, flags);
@@ -1948,13 +1950,13 @@
switch ( val ) {
case 2: /* 2 channels is always supported */
- outl(i_glob_cnt & 0xcfffff,
+ outl(i_glob_cnt & 0xffcfffff,
state->card->iobase + GLOB_CNT);
/* Do we need to change mixer settings???? */
break;
case 4: /* Supported on some chipsets, better check first */
if ( state->card->channels >= 4 ) {
- outl((i_glob_cnt & 0xcfffff) | 0x100000,
+ outl((i_glob_cnt & 0xffcfffff) | 0x100000,
state->card->iobase + GLOB_CNT);
/* Do we need to change mixer settings??? */
} else {
@@ -1963,7 +1965,7 @@
break;
case 6: /* Supported on some chipsets, better check first */
if ( state->card->channels >= 6 ) {
- outl((i_glob_cnt & 0xcfffff) | 0x200000,
+ outl((i_glob_cnt & 0xffcfffff) | 0x200000,
state->card->iobase + GLOB_CNT);
/* Do we need to change mixer settings??? */
} else {
@@ -2553,8 +2555,7 @@
{
struct i810_card *card = dev->private_data;
int count = 100;
- u16 reg_set = ((u16) reg) & 0x7f;
- reg_set |= ((u16) dev->id) << 7;
+ u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f);
while(count-- && (readb(card->iobase_mmio + CAS) & 1))
udelay(1);
@@ -2574,7 +2575,7 @@
{
struct i810_card *card = dev->private_data;
int count = 100;
- u8 reg_set = ((dev->id)?((reg&0x7f)|0x80):(reg&0x7f));
+ u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f);
while(count-- && (inb(card->iobase + CAS) & 1))
udelay(1);
@@ -2586,8 +2587,7 @@
{
struct i810_card *card = dev->private_data;
int count = 100;
- u16 reg_set = ((u16) reg) & 0x7f;
- reg_set |= ((u16) dev->id) << 7;
+ u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f);
while(count-- && (readb(card->iobase_mmio + CAS) & 1))
udelay(1);
@@ -2603,7 +2603,7 @@
{
struct i810_card *card = dev->private_data;
int count = 100;
- u8 reg_set = ((dev->id)?((reg&0x7f)|0x80):(reg&0x7f));
+ u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f);
while(count-- && (inb(card->iobase + CAS) & 1))
udelay(1);
@@ -2779,7 +2779,7 @@
if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4)
&& (card->use_mmio)) {
primary_codec_id = (int) readl(card->iobase_mmio + SDM) & 0x3;
- printk(KERN_INFO "i810_audio: primary codec id %d\n",
+ printk(KERN_INFO "i810_audio: Primary codec has ID %d\n",
primary_codec_id);
}
@@ -2803,6 +2803,7 @@
int num_ac97 = 0;
int ac97_id;
int total_channels = 0;
+ int nr_ac97_max = card_cap[card->pci_id_internal].nr_ac97;
struct ac97_codec *codec;
u16 eid;
u32 reg;
@@ -2828,13 +2829,15 @@
reg = inl(card->iobase + GLOB_CNT);
outl(reg & 0xffcfffff, card->iobase + GLOB_CNT);
- for (num_ac97 = 0; num_ac97 < card_cap[card->pci_id_internal].nr_ac97; num_ac97++) {
+ for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++)
card->ac97_codec[num_ac97] = NULL;
- }
- for (num_ac97 = 0; num_ac97 < card_cap[card->pci_id_internal].nr_ac97; num_ac97++) {
+ /*@FIXME I don't know, if I'm playing to safe here... (jsaw) */
+ if ((nr_ac97_max > 2) && !card->use_mmio) nr_ac97_max = 2;
+
+ for (num_ac97 = 0; num_ac97 < nr_ac97_max; num_ac97++) {
/* codec reset */
- printk(KERN_INFO "i810_audio: resetting hw channel %d\n", num_ac97);
+ printk(KERN_INFO "i810_audio: Resetting connection %d\n", num_ac97);
if (card->use_mmio) readw(card->ac97base_mmio + 0x80*num_ac97);
else inw(card->ac97base + 0x80*num_ac97);
@@ -2846,7 +2849,7 @@
if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4)
&& (card->use_mmio)) {
ac97_id = (int) readl(card->iobase_mmio + SDM) & 0x3;
- printk(KERN_INFO "i810_audio: hw channel %d, codec id %d\n",
+ printk(KERN_INFO "i810_audio: Connection %d with codec id %d\n",
num_ac97, ac97_id);
}
else {
@@ -2869,9 +2872,8 @@
/* initialize some basic codec information, other fields will be filled
in ac97_probe_codec */
codec->private_data = card;
-
- /*@FIXME this will lead to problems!!! id=2 <-> io offset=0*/
- codec->id = num_ac97;
+ codec->id = ac97_id;
+ card->ac97_id_map[ac97_id] = num_ac97 * 0x80;
if (card->use_mmio) {
codec->codec_read = i810_ac97_get_mmio;
@@ -2883,7 +2885,7 @@
}
if(!i810_ac97_probe_and_powerup(card,codec)) {
- printk(KERN_ERR "i810_audio: timed out waiting for codec %d analog ready.\n", num_ac97);
+ printk(KERN_ERR "i810_audio: timed out waiting for codec %d analog ready.\n", ac97_id);
kfree(codec);
break; /* it didn't work */
}
@@ -2903,7 +2905,7 @@
codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L);
if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID))
{
- printk(KERN_WARNING "i810_audio: codec %d is a softmodem - skipping.\n", num_ac97);
+ printk(KERN_WARNING "i810_audio: codec %d is a softmodem - skipping.\n", ac97_id);
kfree(codec);
continue;
}
@@ -3042,8 +3044,7 @@
}
dmabuf->count = dmabuf->dmasize;
stop_dac(state);
- outb(0,card->iobase+dmabuf->write_channel->port+OFF_CIV);
- outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
+ CIV_TO_LVI(card->iobase+dmabuf->write_channel->port, -1);
save_flags(flags);
cli();
start_dac(state);
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2.4.20-pre4-ac2] fix broken i810_audio DMA (?)
2002-08-29 16:26 ` Juergen Sawinski
@ 2002-08-29 16:43 ` Andris Pavenis
2002-08-29 16:50 ` Jim Radford
1 sibling, 0 replies; 5+ messages in thread
From: Andris Pavenis @ 2002-08-29 16:43 UTC (permalink / raw)
To: Juergen Sawinski, linux-kernel@vger; +Cc: Alan Cox, Jim Radford, Doug Ledford
On Thursday 29 August 2002 19:26, Juergen Sawinski wrote:
> F*ck. This time the patch attached.
> Thanx Jim.
Thanks. It works for me (both from KDE-3.1-beta1 and RealPlayer).
Andris
>
> George
>
> On Thu, 2002-08-29 at 03:39, Juergen Sawinski wrote:
> > Changes:
> > -remove dma reset in stop_{dac,adc}
> > (from ICH4 manual: contents of all Bus master related registers to be
> > reset; so, probably some registers are not re-initilized properly on
> > consecutive re-opening of /dev/dsp ???)
> > -remove writes to OFF_CIV, instead set LVI relative to CIV
> >
> > and some stuff that was already in the last diff I send to the list:
> > -implement a codec ID <-> IO register offset mapping
> > -in i810_ioctl, case SNDCTL_DSP_CHANNELS: only touch bits 20:21
> > off GLOB_CNT (multichannel capabilities)
> > -AMD 8111 has 6 hw channels so I must have mmio (but I don't have
> > any docs to verify this)
> > -minor fixes
> >
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2.4.20-pre4-ac2] fix broken i810_audio DMA (?)
2002-08-29 16:26 ` Juergen Sawinski
2002-08-29 16:43 ` Andris Pavenis
@ 2002-08-29 16:50 ` Jim Radford
2002-08-29 16:59 ` Juergen Sawinski
1 sibling, 1 reply; 5+ messages in thread
From: Jim Radford @ 2002-08-29 16:50 UTC (permalink / raw)
To: Juergen Sawinski; +Cc: Linux Kernel
On Thu, Aug 29, 2002 at 06:26:18PM +0200, Juergen Sawinski wrote:
> F*ck. This time the patch attached.
> Thanx Jim.
You're welcome.
It works better, but it's not fixed.
o Playing through oss directly works like before
o No more scratchy sound on artsd startup.
o Playing one song at a time through artsd works.
o Giving two songs to ogg123 to play through artsd
works until you Ctrl-C to skip to the next song.
It then hangs (like before, but with no dmesg output)
Thanks,
-Jim
> On Thu, 2002-08-29 at 03:39, Juergen Sawinski wrote:
> > Changes:
> > -remove dma reset in stop_{dac,adc}
> > (from ICH4 manual: contents of all Bus master related registers to be
> > reset; so, probably some registers are not re-initilized properly on
> > consecutive re-opening of /dev/dsp ???)
> > -remove writes to OFF_CIV, instead set LVI relative to CIV
> >
> > and some stuff that was already in the last diff I send to the list:
> > -implement a codec ID <-> IO register offset mapping
> > -in i810_ioctl, case SNDCTL_DSP_CHANNELS: only touch bits 20:21
> > off GLOB_CNT (multichannel capabilities)
> > -AMD 8111 has 6 hw channels so I must have mmio (but I don't have
> > any docs to verify this)
> > -minor fixes
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2.4.20-pre4-ac2] fix broken i810_audio DMA (?)
2002-08-29 16:50 ` Jim Radford
@ 2002-08-29 16:59 ` Juergen Sawinski
0 siblings, 0 replies; 5+ messages in thread
From: Juergen Sawinski @ 2002-08-29 16:59 UTC (permalink / raw)
To: Jim Radford; +Cc: Linux Kernel
On Thu, 2002-08-29 at 18:50, Jim Radford wrote:
> On Thu, Aug 29, 2002 at 06:26:18PM +0200, Juergen Sawinski wrote:
> > F*ck. This time the patch attached.
> > Thanx Jim.
>
> You're welcome.
>
> It works better, but it's not fixed.
>
> o Playing through oss directly works like before
> o No more scratchy sound on artsd startup.
> o Playing one song at a time through artsd works.
> o Giving two songs to ogg123 to play through artsd
> works until you Ctrl-C to skip to the next song.
> It then hangs (like before, but with no dmesg output)
Can you uncomment the DEBUG defines and try the ogg123 thing again?
> Thanks,
> -Jim
>
> > On Thu, 2002-08-29 at 03:39, Juergen Sawinski wrote:
> > > Changes:
> > > -remove dma reset in stop_{dac,adc}
> > > (from ICH4 manual: contents of all Bus master related registers to be
> > > reset; so, probably some registers are not re-initilized properly on
> > > consecutive re-opening of /dev/dsp ???)
> > > -remove writes to OFF_CIV, instead set LVI relative to CIV
> > >
> > > and some stuff that was already in the last diff I send to the list:
> > > -implement a codec ID <-> IO register offset mapping
> > > -in i810_ioctl, case SNDCTL_DSP_CHANNELS: only touch bits 20:21
> > > off GLOB_CNT (multichannel capabilities)
> > > -AMD 8111 has 6 hw channels so I must have mmio (but I don't have
> > > any docs to verify this)
> > > -minor fixes
--
Juergen "George" Sawinski
Max-Planck-Institute for Medical Research
Dept. of Biomedical Optics
Jahnstr. 29
D-69120 Heidelberg
Germany
Phone: +49-6221-486-309
Fax: +49-6221-486-325
priv.
Phone: +49-6221-418 848
Mobile: +49-171-532 5302
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2002-08-29 16:52 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-29 1:39 [PATCH 2.4.20-pre4-ac2] fix broken i810_audio DMA (?) Juergen Sawinski
2002-08-29 16:26 ` Juergen Sawinski
2002-08-29 16:43 ` Andris Pavenis
2002-08-29 16:50 ` Jim Radford
2002-08-29 16:59 ` Juergen Sawinski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).