linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).