public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] update for ALi Audio Driver (0.14.10)
@ 2002-06-06  6:27 lei_hu
  2002-06-06  6:46 ` David S. Miller
  2002-06-06 12:18 ` Alan Cox
  0 siblings, 2 replies; 8+ messages in thread
From: lei_hu @ 2002-06-06  6:27 UTC (permalink / raw)
  To: alan; +Cc: linux-kernel, jgarzik

[-- Attachment #1: Type: text/plain, Size: 315 bytes --]

Dear all
 I rewrite the part to read/write registers of the audio codec  for Ali 5451
Audio Driver.
 Best Regards

 Lei Hu
 Information about update:
 Updated files:     trident.c
 Location:          drivers/sound
 Driver Version:    0.14.10
 Kernel Version:    2.4.18
 Attach Patch file:
(See attached file: patch)

[-- Attachment #2: patch --]
[-- Type: application/octet-stream, Size: 7739 bytes --]

--- drivers/sound/trident.c.orig	Thu Jun  6 13:07:30 2002
+++ drivers/sound/trident.c	Thu Jun  6 13:59:59 2002
@@ -36,6 +36,9 @@
  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  History
+ *  v0.14.10
+ *      June 6 2002 Lei Hu <Lei_hu@ali.com.tw>
+ *      rewrite the part to read/write registers of audio codec for Ali5451 
  *  v0.14.9d
  *  	October 8 2001 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *	use set_current_state, properly release resources on failure in
@@ -46,7 +49,7 @@
  *	this chip is often found in settop boxes (combined video+audio)
  *  v0.14.9b
  *	Switch to static inline not extern inline (gcc 3)
- *  v0.14.9a
+ *  v0.14.9a 
  *	Aug 6 2001 Alan Cox
  *	0.14.9 crashed on rmmod due to a timer/bh left running. Simplified
  *	the existing logic (the BH doesnt help as ac97 is lock_irqsave)
@@ -180,7 +183,7 @@
 
 #include <linux/pm.h>
 
-#define DRIVER_VERSION "0.14.9d"
+#define DRIVER_VERSION "0.14.10"
 
 /* magic numbers to protect our data structures */
 #define TRIDENT_CARD_MAGIC	0x5072696E /* "Prin" */
@@ -2868,62 +2871,80 @@
 	return ((u16) (data >> 16));
 }
 
-/* Write AC97 codec registers for ALi*/
-static void ali_ac97_set(struct trident_card *card, int secondary, u8 reg, u16 val)
+/* rewrite ac97 read and write mixer register by hulei for ALI*/
+static int acquirecodecaccess(struct trident_card * card )
 {
-	unsigned int address, mask;
-	unsigned int wCount1 = 0xffff;
-	unsigned int wCount2= 0xffff;
-	unsigned long chk1, chk2;
-	unsigned long flags;
-	u32 data;
+	u16 wsemamask=0x6000; /* bit 14..13 */
+	u16 wsemabits;
+        u16 wcontrol ;
+	int block =0;
+	int ncount =25;
+	while(1)
+	{
+		 wcontrol=inw(TRID_REG(card,  ALI_AC97_WRITE));
+                 wsemabits=(wcontrol) & wsemamask;
 
-	data = ((u32) val) << 16;
+		 if(wsemabits==0x4000)
+			 return 1; /* 0x4000 is audio ,then success */
+		 if(ncount--<0)
+			 break;
+         if(wsemabits==0)
+		 {
+unlock:
+          outl(((u32)(wcontrol & 0x1eff)|0x00004000), TRID_REG(card, ALI_AC97_WRITE));
+          continue;
+		 }
+		 udelay(20);
 
-	if(!card)
-		BUG();
-		
-	address = ALI_AC97_WRITE;
-	mask = ALI_AC97_WRITE_ACTION | ALI_AC97_AUDIO_BUSY;
-	if (secondary)
-		mask |= ALI_AC97_SECONDARY;
-	if (card->revision == ALI_5451_V02)
-		mask |= ALI_AC97_WRITE_MIXER_REGISTER;
-		
-	spin_lock_irqsave(&card->lock, flags);
-	while (wCount1--) {
-		if ((inw(TRID_REG(card, address)) & ALI_AC97_BUSY_WRITE) == 0) {
-			data |= (mask | (reg & AC97_REG_ADDR));
-			
-			chk1 = inl(TRID_REG(card,  ALI_STIMER));
-			chk2 = inl(TRID_REG(card,  ALI_STIMER));
-			while (wCount2-- && (chk1 == chk2))
-				chk2 = inl(TRID_REG(card,  ALI_STIMER));
-			if (wCount2 == 0) {
-				spin_unlock_irqrestore(&card->lock, flags);
-				return;
-			}
-			outl(data, TRID_REG(card, address));	//write!
-			spin_unlock_irqrestore(&card->lock, flags);
-			return;	//success
-		}
-		inw(TRID_REG(card, address));	//wait for a read cycle
 	}
+	if(!block)
+	{
+		printk("accesscodecsemaphore : try unlock \n");
+		block=1;
+goto unlock;
+	}
+	printk("accesscodecsemaphore :fail\n");
+	return 0;
+}
 
-	printk(KERN_ERR "ali: AC97 CODEC write timed out.\n");
-	spin_unlock_irqrestore(&card->lock, flags);
-	return;
+static void releasecodecaccess(struct trident_card * card )
+{ 
+	unsigned long wcontrol;
+	wcontrol=inl(TRID_REG(card,  ALI_AC97_WRITE));
+	outl((wcontrol & 0xffff1eff),TRID_REG(card, ALI_AC97_WRITE));
 }
 
+static int waitforstimertick(struct trident_card * card )
+{
+unsigned long chk1, chk2;
+unsigned int wcount= 0xffff;
+chk1 = inl(TRID_REG(card,  ALI_STIMER));
+
+while(1)
+{
+	chk2 = inl(TRID_REG(card,  ALI_STIMER));
+	if( (wcount > 0 )&& chk1!=chk2)
+		return 1;
+	if(wcount <= 0)
+		break;
+     udelay(50);
+
+}
+printk(" waitforstimertick :BIT_CLK is dead \n");
+return 0;
+}
+
+
+
+
 /* Read AC97 codec registers for ALi*/
 static u16 ali_ac97_get(struct trident_card *card, int secondary, u8 reg)
 {
 	unsigned int address, mask;
-        unsigned int wCount1 = 0xffff;
-        unsigned int wCount2= 0xffff;
-        unsigned long chk1, chk2;
-	unsigned long flags;
+	unsigned int ncount;
+        unsigned long aud_reg;
 	u32 data;
+        u16 wcontrol;
 
 	if(!card)
 		BUG();
@@ -2935,37 +2956,126 @@
 	mask = ALI_AC97_READ_ACTION | ALI_AC97_AUDIO_BUSY;
 	if (secondary)
 		mask |= ALI_AC97_SECONDARY;
+    
+		
+	
+   
+    if( !acquirecodecaccess(card))
+    {
+		printk(" access codec fail \n");
+
+    }
+      
+	wcontrol=inw(TRID_REG(card, ALI_AC97_WRITE));
+	wcontrol &=0xfe00;
+	wcontrol |=(0x8000|reg);
+	outw(wcontrol,TRID_REG(card,  ALI_AC97_WRITE));
+
+
+    
 
-	spin_lock_irqsave(&card->lock, flags);
 	data = (mask | (reg & AC97_REG_ADDR));
-	while (wCount1--) {
-		if ((inw(TRID_REG(card, address)) & ALI_AC97_BUSY_READ) == 0) {
-			chk1 = inl(TRID_REG(card,  ALI_STIMER));
-			chk2 = inl(TRID_REG(card,  ALI_STIMER));
-			while (wCount2-- && (chk1 == chk2))
-				chk2 = inl(TRID_REG(card,  ALI_STIMER));
-			if (wCount2 == 0) {
-				printk(KERN_ERR "ali: AC97 CODEC read timed out.\n");
-				spin_unlock_irqrestore(&card->lock, flags);
-				return 0;
-			}
-			outl(data, TRID_REG(card, address));	//read!
-			wCount2 = 0xffff;
-			while (wCount2--) {
-				if ((inw(TRID_REG(card, address)) & ALI_AC97_BUSY_READ) == 0) {
-					data = inl(TRID_REG(card, address));
-					spin_unlock_irqrestore(&card->lock, flags);
-					return ((u16) (data >> 16));
-				}
-			}
-		}
-		inw(TRID_REG(card, address));	//wait a read cycle
+	
+	if(!waitforstimertick(card))
+	{
+				printk(" BIT_CLOCK is dead \n");
+				goto l;
 	}
-	spin_unlock_irqrestore(&card->lock, flags);
+             
+	udelay(20);		
+
+			ncount=10;
+
+			while(1) 
+			{
+            if ((inw(TRID_REG(card,ALI_AC97_WRITE)) & ALI_AC97_BUSY_READ) != 0)
+			 break;
+			if(ncount <=0)
+				break;
+			if(ncount--==1)
+			{
+				printk("ali_ac97_read :try clear busy flag\n");
+                aud_reg = inl(TRID_REG(card,  ALI_AC97_WRITE));
+                outl((aud_reg & 0xffff7fff), TRID_REG(card, ALI_AC97_WRITE));
+			}
+			udelay(10);
+			}
+
+	   data = inl(TRID_REG(card, address));
+					
+	   return ((u16) (data >> 16));
+			
+	
+l:  
+	releasecodecaccess(card);
 	printk(KERN_ERR "ali: AC97 CODEC read timed out.\n");
 	return 0;
 }
 
+
+/* Write AC97 codec registers for hulei*/
+static void ali_ac97_set(struct trident_card *card, int secondary, u8 reg, u16 val)
+{
+	unsigned int address, mask;
+	unsigned int ncount;
+	u32 data;
+        u16 wcontrol;
+
+	data = ((u32) val) << 16;
+
+	if(!card)
+		BUG();
+		
+	address = ALI_AC97_WRITE;
+	mask = ALI_AC97_WRITE_ACTION | ALI_AC97_AUDIO_BUSY;
+	if (secondary)
+		mask |= ALI_AC97_SECONDARY;
+	if (card->revision == ALI_5451_V02)
+		mask |= ALI_AC97_WRITE_MIXER_REGISTER;
+		
+   
+	
+        if(!acquirecodecaccess(card))      
+	printk("access codec fail \n");
+			
+		
+
+      wcontrol = inw(TRID_REG(card, ALI_AC97_WRITE));
+      wcontrol &=0xff00;
+      wcontrol |=(0x8100|reg);/* bit 8=1: (ali1535 )reserved /ali1535+ write */
+      outl(( data |wcontrol), TRID_REG(card,ALI_AC97_WRITE ));
+
+        if(!waitforstimertick(card))
+	{
+				printk(" BIT_CLOCK is dead \n");
+				goto l1;
+	}
+
+        ncount = 10;
+	 while(1)
+		  {
+
+			  wcontrol = inw(TRID_REG(card, ALI_AC97_WRITE));
+			  if(!wcontrol & 0x8000)
+				  break;
+			  if(ncount <=0)
+				  break;
+			  if(ncount--==1)
+			  {
+				  printk(" ali_ac97_set :try clear busy flag!!\n");
+                  outw(wcontrol & 0x7fff, TRID_REG(card, ALI_AC97_WRITE));
+			  }
+			  udelay(10);
+		  }
+
+l1:
+		  releasecodecaccess(card);
+		  return;
+}
+
+
+
+
 static void ali_enable_special_channel(struct trident_state *stat)
 {
 	struct trident_card *card = stat->card;

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] update for ALi Audio Driver (0.14.10)
  2002-06-06  6:27 [PATCH] update for ALi Audio Driver (0.14.10) lei_hu
@ 2002-06-06  6:46 ` David S. Miller
  2002-06-06 12:18 ` Alan Cox
  1 sibling, 0 replies; 8+ messages in thread
From: David S. Miller @ 2002-06-06  6:46 UTC (permalink / raw)
  To: lei_hu; +Cc: alan, linux-kernel, jgarzik


Please read linux/Documentation/CodingStyle

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] update for ALi Audio Driver (0.14.10)
  2002-06-06  6:27 [PATCH] update for ALi Audio Driver (0.14.10) lei_hu
  2002-06-06  6:46 ` David S. Miller
@ 2002-06-06 12:18 ` Alan Cox
  2002-06-06 18:09   ` Jeff Garzik
  1 sibling, 1 reply; 8+ messages in thread
From: Alan Cox @ 2002-06-06 12:18 UTC (permalink / raw)
  To: lei_hu; +Cc: alan, linux-kernel, jgarzik

On Thu, 2002-06-06 at 07:27, lei_hu@ali.com.tw wrote:
> Dear all
>  I rewrite the part to read/write registers of the audio codec  for Ali 5451
> Audio Driver.

The formatting seems to have gone a bit strange but I'll clean that up
and merge the change


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] update for ALi Audio Driver (0.14.10)
  2002-06-06 12:18 ` Alan Cox
@ 2002-06-06 18:09   ` Jeff Garzik
  2002-06-06 23:47     ` Alan Cox
  0 siblings, 1 reply; 8+ messages in thread
From: Jeff Garzik @ 2002-06-06 18:09 UTC (permalink / raw)
  To: Alan Cox; +Cc: lei_hu, alan, linux-kernel

Alan Cox wrote:

>On Thu, 2002-06-06 at 07:27, lei_hu@ali.com.tw wrote:
>  
>
>>Dear all
>> I rewrite the part to read/write registers of the audio codec  for Ali 5451
>>Audio Driver.
>>    
>>
>
>The formatting seems to have gone a bit strange but I'll clean that up
>and merge the change
>  
>


Why?  Hardware semaphores are notorious for causing hangs.  Nobody is 
sharing the hardware under Linux, so I think we should enable access on 
init, and not disable access until driver close.  IMO the mixer should 
be guarded by a Linux kernel semaphore...  I have a patch from Thomas 
Sailer (I think) lying around somewhere that does just that to the via 
audio driver.  Maybe we can adapt it.
(I cc'd this little detail, in my ali/trident.c patch review, to you)

    Jeff





^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] update for ALi Audio Driver (0.14.10)
  2002-06-06 18:09   ` Jeff Garzik
@ 2002-06-06 23:47     ` Alan Cox
  2002-06-07  0:19       ` Jeff Garzik
  0 siblings, 1 reply; 8+ messages in thread
From: Alan Cox @ 2002-06-06 23:47 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Alan Cox, lei_hu, alan, linux-kernel

> Why?  Hardware semaphores are notorious for causing hangs.  Nobody is 
> sharing the hardware under Linux, so I think we should enable access on 
> init, and not disable access until driver close.  IMO the mixer should 
> be guarded by a Linux kernel semaphore...  I have a patch from Thomas 
> Sailer (I think) lying around somewhere that does just that to the via 
> audio driver.  Maybe we can adapt it.
> (I cc'd this little detail, in my ali/trident.c patch review, to you)

So add a timeout to it ?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] update for ALi Audio Driver (0.14.10)
  2002-06-06 23:47     ` Alan Cox
@ 2002-06-07  0:19       ` Jeff Garzik
  0 siblings, 0 replies; 8+ messages in thread
From: Jeff Garzik @ 2002-06-07  0:19 UTC (permalink / raw)
  To: Alan Cox; +Cc: Alan Cox, lei_hu, linux-kernel

Alan Cox wrote:

>>Why?  Hardware semaphores are notorious for causing hangs.  Nobody is 
>>sharing the hardware under Linux, so I think we should enable access on 
>>init, and not disable access until driver close.  IMO the mixer should 
>>be guarded by a Linux kernel semaphore...  I have a patch from Thomas 
>>Sailer (I think) lying around somewhere that does just that to the via 
>>audio driver.  Maybe we can adapt it.
>>(I cc'd this little detail, in my ali/trident.c patch review, to you)
>>    
>>
>
>So add a timeout to it ?
>  
>
There is a problem in via audio, that seems to be present in trident.c 
too:  trident_ioctl_mixdev doesn't protect the call to 
codec->mixer_ioctl, which in turn can read and write to the AC97 codec.

I'm saying, (1) hardware semaphores are error prone and (2) are we using 
the hardware sem to work around this lack of locking on ->mixer_ioctl?

    Jeff





^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] update for ALi Audio Driver (0.14.10)
@ 2002-06-07  1:52 lei_hu
  0 siblings, 0 replies; 8+ messages in thread
From: lei_hu @ 2002-06-07  1:52 UTC (permalink / raw)
  To: davem; +Cc: alan, linux-kernel, jgarzik

[-- Attachment #1: Type: text/plain, Size: 206 bytes --]


Hi David
Think you for help !!!
I recheck my driver and pay attention to codingstyle.
I attach file Patch and Ali5451 AC97 read /write spec .(See attached file:
ali5451 spec.doc)(See attached file: patch)

[-- Attachment #2: ali5451 spec.doc --]
[-- Type: application/octet-stream, Size: 21504 bytes --]

[-- Attachment #3: patch --]
[-- Type: application/octet-stream, Size: 7318 bytes --]

@@ -36,6 +36,9 @@
  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  History
+ *  v0.14.10
+ *      June 6 2002 Lei Hu <Lei_hu@ali.com.tw>
+ *      rewrite the part to read/write registers of audio codec for Ali5451 
  *  v0.14.9d
  *  	October 8 2001 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *	use set_current_state, properly release resources on failure in
@@ -180,7 +183,7 @@
 
 #include <linux/pm.h>
 
-#define DRIVER_VERSION "0.14.9d"
+#define DRIVER_VERSION "0.14.10"
 
 /* magic numbers to protect our data structures */
 #define TRIDENT_CARD_MAGIC	0x5072696E /* "Prin" */
@@ -2868,62 +2871,78 @@
 	return ((u16) (data >> 16));
 }
 
-/* Write AC97 codec registers for ALi*/
-static void ali_ac97_set(struct trident_card *card, int secondary, u8 reg, u16 val)
+/* rewrite ac97 read and write mixer register by hulei for ALI*/
+static int ali_acquire_codec_access(struct trident_card * card )
 {
-	unsigned int address, mask;
-	unsigned int wCount1 = 0xffff;
-	unsigned int wCount2= 0xffff;
-	unsigned long chk1, chk2;
-	unsigned long flags;
-	u32 data;
-
-	data = ((u32) val) << 16;
+	u16 wsemamask = 0x6000; /* bit 14..13 */
+	u16 wsemabits;
+       u16 wcontrol ;
+	int block = 0;
+	int ncount = 25;
+	while ( 1 )
+	{
+		wcontrol = inw(TRID_REG(card,  ALI_AC97_WRITE));
+		wsemabits = (wcontrol) & wsemamask;
 
-	if(!card)
-		BUG();
-		
-	address = ALI_AC97_WRITE;
-	mask = ALI_AC97_WRITE_ACTION | ALI_AC97_AUDIO_BUSY;
-	if (secondary)
-		mask |= ALI_AC97_SECONDARY;
-	if (card->revision == ALI_5451_V02)
-		mask |= ALI_AC97_WRITE_MIXER_REGISTER;
-		
-	spin_lock_irqsave(&card->lock, flags);
-	while (wCount1--) {
-		if ((inw(TRID_REG(card, address)) & ALI_AC97_BUSY_WRITE) == 0) {
-			data |= (mask | (reg & AC97_REG_ADDR));
-			
-			chk1 = inl(TRID_REG(card,  ALI_STIMER));
-			chk2 = inl(TRID_REG(card,  ALI_STIMER));
-			while (wCount2-- && (chk1 == chk2))
-				chk2 = inl(TRID_REG(card,  ALI_STIMER));
-			if (wCount2 == 0) {
-				spin_unlock_irqrestore(&card->lock, flags);
-				return;
-			}
-			outl(data, TRID_REG(card, address));	//write!
-			spin_unlock_irqrestore(&card->lock, flags);
-			return;	//success
+		if (wsemabits == 0x4000)
+			return 1; /* 0x4000 is audio ,then success */
+		if (ncount-- < 0)
+			break;
+                if (wsemabits == 0) {
+unlock:
+		outl(((u32)(wcontrol & 0x1eff)|0x00004000), TRID_REG(card, ALI_AC97_WRITE));
+		continue;
 		}
-		inw(TRID_REG(card, address));	//wait for a read cycle
+		udelay(20);
+
+	}
+	if (!block) {
+		printk("ali_acquire_codec_access : try unlock \n");
+		block = 1;
+		goto unlock;
 	}
+	printk("ali_acquire_codec_access :fail\n");
+	return 0;
+}
 
-	printk(KERN_ERR "ali: AC97 CODEC write timed out.\n");
-	spin_unlock_irqrestore(&card->lock, flags);
-	return;
+static void ali_release_codec_access(struct trident_card * card )
+{ 
+	unsigned long wcontrol;
+	wcontrol = inl(TRID_REG(card,  ALI_AC97_WRITE));
+	outl((wcontrol & 0xffff1eff),TRID_REG(card, ALI_AC97_WRITE));
+}
+
+static int ali_waitfor_stimertick(struct trident_card * card )
+{
+	unsigned long chk1, chk2;
+	unsigned int wcount = 0xffff;
+	chk1 = inl(TRID_REG(card,  ALI_STIMER));
+
+	while(1)
+	{
+		chk2 = inl(TRID_REG(card,  ALI_STIMER));
+		if((wcount > 0)&& chk1 != chk2)
+			return 1;
+		if(wcount <= 0)
+			break;
+		udelay(50);
+
+	}
+	printk(" ali_waitfor_stimertick :BIT_CLK is dead \n");
+	return 0;
 }
 
+
+
+
 /* Read AC97 codec registers for ALi*/
 static u16 ali_ac97_get(struct trident_card *card, int secondary, u8 reg)
 {
 	unsigned int address, mask;
-       unsigned int wCount1 = 0xffff;
-       unsigned int wCount2= 0xffff;
-       unsigned long chk1, chk2;
-	unsigned long flags;
+	unsigned int ncount;
+       unsigned long aud_reg;
 	u32 data;
+       u16 wcontrol;
 
 	if(!card)
 		BUG();
@@ -2935,37 +2954,120 @@
 	mask = ALI_AC97_READ_ACTION | ALI_AC97_AUDIO_BUSY;
 	if (secondary)
 		mask |= ALI_AC97_SECONDARY;
+    
+		
+   
+    	if( !ali_acquire_codec_access(card)) {
+		printk(" access codec fail \n");
+
+	}
+      
+	wcontrol = inw(TRID_REG(card, ALI_AC97_WRITE));
+	wcontrol &= 0xfe00;
+	wcontrol |= (0x8000 | reg);
+	outw(wcontrol,TRID_REG(card,  ALI_AC97_WRITE));
+
+
+    
 
-	spin_lock_irqsave(&card->lock, flags);
 	data = (mask | (reg & AC97_REG_ADDR));
-	while (wCount1--) {
-		if ((inw(TRID_REG(card, address)) & ALI_AC97_BUSY_READ) == 0) {
-			chk1 = inl(TRID_REG(card,  ALI_STIMER));
-			chk2 = inl(TRID_REG(card,  ALI_STIMER));
-			while (wCount2-- && (chk1 == chk2))
-				chk2 = inl(TRID_REG(card,  ALI_STIMER));
-			if (wCount2 == 0) {
-				printk(KERN_ERR "ali: AC97 CODEC read timed out.\n");
-				spin_unlock_irqrestore(&card->lock, flags);
-				return 0;
-			}
-			outl(data, TRID_REG(card, address));	//read!
-			wCount2 = 0xffff;
-			while (wCount2--) {
-				if ((inw(TRID_REG(card, address)) & ALI_AC97_BUSY_READ) == 0) {
-					data = inl(TRID_REG(card, address));
-					spin_unlock_irqrestore(&card->lock, flags);
-					return ((u16) (data >> 16));
-				}
-			}
+	
+	if(!ali_waitfor_stimertick(card))
+	{
+		printk(" BIT_CLOCK is dead \n");
+		goto l;
+	}
+             
+	udelay(20);		
+	ncount = 10;
+
+	while(1) 
+	{
+		if ((inw(TRID_REG(card,ALI_AC97_WRITE)) & ALI_AC97_BUSY_READ) != 0)
+			break;
+	        if (ncount <= 0)
+	            	break;
+		    
+		if (ncount-- == 1) {
+		        printk("ali_ac97_read :try clear busy flag\n");
+                        aud_reg = inl(TRID_REG(card,  ALI_AC97_WRITE));
+                        outl((aud_reg & 0xffff7fff), TRID_REG(card, ALI_AC97_WRITE));
 		}
-		inw(TRID_REG(card, address));	//wait a read cycle
+		udelay(10);
 	}
-	spin_unlock_irqrestore(&card->lock, flags);
+
+	data = inl(TRID_REG(card, address));
+					
+	return ((u16) (data >> 16));
+			
+	
+l:  
+	ali_release_codec_access(card);
 	printk(KERN_ERR "ali: AC97 CODEC read timed out.\n");
 	return 0;
 }
 
+
+/* Write AC97 codec registers for hulei*/
+static void ali_ac97_set(struct trident_card *card, int secondary, u8 reg, u16 val)
+{
+	unsigned int address, mask;
+	unsigned int ncount;
+	u32 data;
+       u16 wcontrol;
+
+	data = ((u32) val) << 16;
+
+	if(!card)
+		BUG();
+		
+	address = ALI_AC97_WRITE;
+	mask = ALI_AC97_WRITE_ACTION | ALI_AC97_AUDIO_BUSY;
+	if (secondary)
+		mask |= ALI_AC97_SECONDARY;
+	if (card->revision == ALI_5451_V02)
+		mask |= ALI_AC97_WRITE_MIXER_REGISTER;
+		
+   
+	
+        if(!ali_acquire_codec_access(card))      
+		printk("access codec fail \n");
+			
+		
+
+      	wcontrol = inw(TRID_REG(card, ALI_AC97_WRITE));
+      	wcontrol &= 0xff00;
+      	wcontrol |= (0x8100|reg);/* bit 8=1: (ali1535 )reserved /ali1535+ write */
+       	outl(( data |wcontrol), TRID_REG(card,ALI_AC97_WRITE ));
+
+        if(!ali_waitfor_stimertick(card)) {
+		printk(" BIT_CLOCK is dead \n");
+		goto l1;
+	}
+
+        ncount = 10;
+	while(1)
+	{
+
+		wcontrol = inw(TRID_REG(card, ALI_AC97_WRITE));
+		if (!wcontrol & 0x8000)
+			break;
+		if (ncount <= 0)
+		        break;
+	        if (ncount-- == 1) {
+			printk(" ali_ac97_set :try clear busy flag!!\n");
+                  	outw(wcontrol & 0x7fff, TRID_REG(card, ALI_AC97_WRITE));
+		}
+		udelay(10);
+	}
+
+l1:
+	ali_release_codec_access(card);
+	return;
+}
+
+
+
 static void ali_enable_special_channel(struct trident_state *stat)
 {
 	struct trident_card *card = stat->card;

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] update for ALi Audio Driver (0.14.10)
@ 2002-06-07  2:49 lei_hu
  0 siblings, 0 replies; 8+ messages in thread
From: lei_hu @ 2002-06-07  2:49 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: alan, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 768 bytes --]


Hi Jeff
Please see my new ali5451 driver (trident.c ) about read /write mixer regiser.
The ali_acquire_codec_access function do not acquire  hardware semaphore. It is
audio driver request to write ac97 mixer register.
Please see ali5451 spec 's ACWR . I think that use Linux kernel semaphore (
spin_lock )is  repeat because I do  read / write  Mixer regiser really till
after 48k Hz then codec clocking is 48k hz .In  the  ali_waitfor_stimertick
function ,You can see it.
Ali5451 (controller ) to codec connection by AC-link,a  AC-link output frame
begin with a low to high transition of SYNC. SYNC is synchronous to rising edge
of BIT_CK. NEXT SYNC and SYNC is 48k Hz . So I think that transmit data is
right.
I attach file ( STIME ) :(See attached file: Stimer.doc)

[-- Attachment #2: Stimer.doc --]
[-- Type: application/octet-stream, Size: 19456 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2002-06-07  2:45 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-06-06  6:27 [PATCH] update for ALi Audio Driver (0.14.10) lei_hu
2002-06-06  6:46 ` David S. Miller
2002-06-06 12:18 ` Alan Cox
2002-06-06 18:09   ` Jeff Garzik
2002-06-06 23:47     ` Alan Cox
2002-06-07  0:19       ` Jeff Garzik
  -- strict thread matches above, loose matches on Subject: below --
2002-06-07  1:52 lei_hu
2002-06-07  2:49 lei_hu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox