Re: is this card supported by ALSA?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



At Tue, 15 Jul 2008 15:11:09 +0200,I wrote:> > At Tue, 15 Jul 2008 02:11:41 +0200,> Rene Herman wrote:> > > > On 15-07-08 01:36, Landis McGauhey wrote:> > > > It seems there's just a bit too much oddness going on. Takashi, you know > > more about ac97. Also bringing in alsa-devel...> > > > > # cat /proc/asound/AudioPCI/codec97#0/ac97#0-0=> > > > > > 0-0/0: 0x76058384 F�S> > > > Eep? A 0x83847605 would be a SigmaTel STAC9704. And:> > > > [ ... ]> > > > > # cat /proc/asound/AudioPCI/codec97#0/ac97#0-0+regs=> > > > [ ... ]> > > > > 0:7c = 0000> > > 0:7e = 8384> > > > does't fit the above ID. Do we just have a crummy codec that needs delay > > between acceses somewhere or something?> > I guess it's rather the controller code.  Will check this later.
The below is a patch to improve the codec access routines in a bitmore robust way (and clean-ups, too).  Give it a try.

Takashi
---diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.cindex fbf1124..5c962b6 100644--- a/sound/pci/ens1370.c+++ b/sound/pci/ens1370.c@@ -461,8 +461,6 @@ MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);  *  constants  */ -#define POLL_COUNT	0xa000- #ifdef CHIP1370 static unsigned int snd_es1370_fixed_rates[] = 	{5512, 11025, 22050, 44100};@@ -514,14 +512,16 @@ static const unsigned int snd_ensoniq_sample_shift[] =  static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq) {-	unsigned int t, r = 0;+	unsigned int r = 0;+	unsigned long end_time; -	for (t = 0; t < POLL_COUNT; t++) {+	end_time = jiffies + msecs_to_jiffies(100);+	do { 		r = inl(ES_REG(ensoniq, 1371_SMPRATE)); 		if ((r & ES_1371_SRC_RAM_BUSY) == 0) 			return r;-		cond_resched();-	}+		schedule_timeout_uninterruptible(1);+	} while (time_after_eq(end_time, jiffies)); 	snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n", 		   ES_REG(ensoniq, 1371_SMPRATE), r); 	return 0;@@ -529,7 +529,7 @@ static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq)  static unsigned int snd_es1371_src_read(struct ensoniq * ensoniq, unsigned short reg) {-	unsigned int temp, i, orig, r;+	unsigned int temp, orig, r;  	/* wait for ready */ 	temp = orig = snd_es1371_wait_src_ready(ensoniq);@@ -545,11 +545,13 @@ static unsigned int snd_es1371_src_read(struct ensoniq * ensoniq, unsigned short 	 	if ((temp & 0x00870000) != 0x00010000) { 		/* wait for the right state */-		for (i = 0; i < POLL_COUNT; i++) {+		unsigned long end_time = jiffies + msecs_to_jiffies(100);+		do { 			temp = inl(ES_REG(ensoniq, 1371_SMPRATE)); 			if ((temp & 0x00870000) == 0x00010000) 				break;-		}+			schedule_timeout_uninterruptible(1);+		} while (time_after_eq(end_time, jiffies)); 	}  	/* hide the state bits */	@@ -602,104 +604,90 @@ static void snd_es1370_codec_write(struct snd_ak4531 *ak4531,  #ifdef CHIP1371 +static int _es1371_wait_wip(struct ensoniq *ensoniq)+{+	unsigned long end_time;++	end_time = jiffies + msecs_to_jiffies(100);+	do {+		if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP))+			return 0;+	} while (time_after_eq(end_time, jiffies));+	snd_printk(KERN_ERR "codec wait timeout, status = 0x%x\n",+		   inl(ES_REG(ensoniq, 1371_CODEC)));+	return -EINVAL;+}++static void _es1371_codec_write(struct ensoniq *ensoniq,+				unsigned int val)+{+	unsigned int x;+	unsigned long end_time;++	_es1371_wait_wip(ensoniq);+	/* save the current state for latter */+	x = snd_es1371_wait_src_ready(ensoniq);+	outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |+		   ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,+	     ES_REG(ensoniq, 1371_SMPRATE));+	/* wait for not busy (state 0) first to avoid+	   transition states */+	end_time = jiffies + msecs_to_jiffies(100);+	do {+		if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==+		    0x00000000)+			break;+	} while (time_after_eq(end_time, jiffies));+	/* wait for a SAFE time to write addr/data and then do it, dammit */+	end_time = jiffies + msecs_to_jiffies(100);+	do {+		if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==+		    0x00010000)+			break;+	} while (time_after_eq(end_time, jiffies));+	outl(val, ES_REG(ensoniq, 1371_CODEC));+	/* restore SRC reg */+	snd_es1371_wait_src_ready(ensoniq);+	outl(x, ES_REG(ensoniq, 1371_SMPRATE));+}+ static void snd_es1371_codec_write(struct snd_ac97 *ac97, 				   unsigned short reg, unsigned short val) { 	struct ensoniq *ensoniq = ac97->private_data;-	unsigned int t, x;  	mutex_lock(&ensoniq->src_mutex);-	for (t = 0; t < POLL_COUNT; t++) {-		if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {-			/* save the current state for latter */-			x = snd_es1371_wait_src_ready(ensoniq);-			outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |-			           ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,-			     ES_REG(ensoniq, 1371_SMPRATE));-			/* wait for not busy (state 0) first to avoid-			   transition states */-			for (t = 0; t < POLL_COUNT; t++) {-				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==-				    0x00000000)-					break;-			}-			/* wait for a SAFE time to write addr/data and then do it, dammit */-			for (t = 0; t < POLL_COUNT; t++) {-				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==-				    0x00010000)-					break;-			}-			outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC));-			/* restore SRC reg */-			snd_es1371_wait_src_ready(ensoniq);-			outl(x, ES_REG(ensoniq, 1371_SMPRATE));-			mutex_unlock(&ensoniq->src_mutex);-			return;-		}-	}+	_es1371_codec_write(ensoniq, ES_1371_CODEC_WRITE(reg, val)); 	mutex_unlock(&ensoniq->src_mutex);-	snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n",-		   ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC))); }  static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, 					    unsigned short reg) { 	struct ensoniq *ensoniq = ac97->private_data;-	unsigned int t, x, fail = 0;+	unsigned int fail;+	unsigned long end_time; -      __again: 	mutex_lock(&ensoniq->src_mutex);-	for (t = 0; t < POLL_COUNT; t++) {-		if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {-			/* save the current state for latter */-			x = snd_es1371_wait_src_ready(ensoniq);-			outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |-			           ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,-			     ES_REG(ensoniq, 1371_SMPRATE));-			/* wait for not busy (state 0) first to avoid-			   transition states */-			for (t = 0; t < POLL_COUNT; t++) {-				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==-				    0x00000000)-					break;+	for (fail = 0; fail < 10; fail++) {+		_es1371_codec_write(ensoniq, ES_1371_CODEC_READS(reg));+		/* wait for WIP again */+		_es1371_wait_wip(ensoniq);+		/* now wait for the stinkin' data (RDY) */+		end_time = jiffies + msecs_to_jiffies(100);+		do {+			unsigned int x = inl(ES_REG(ensoniq, 1371_CODEC));+			if (x & ES_1371_CODEC_RDY) {+				mutex_unlock(&ensoniq->src_mutex);+				return ES_1371_CODEC_READ(x); 			}-			/* wait for a SAFE time to write addr/data and then do it, dammit */-			for (t = 0; t < POLL_COUNT; t++) {-				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==-				    0x00010000)-					break;-			}-			outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC));-			/* restore SRC reg */-			snd_es1371_wait_src_ready(ensoniq);-			outl(x, ES_REG(ensoniq, 1371_SMPRATE));-			/* wait for WIP again */-			for (t = 0; t < POLL_COUNT; t++) {-				if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP))-					break;		-			}-			/* now wait for the stinkin' data (RDY) */-			for (t = 0; t < POLL_COUNT; t++) {-				if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) {-					mutex_unlock(&ensoniq->src_mutex);-					return ES_1371_CODEC_READ(x);-				}-			}-			mutex_unlock(&ensoniq->src_mutex);-			if (++fail > 10) {-				snd_printk(KERN_ERR "codec read timeout (final) "-					   "at 0x%lx, reg = 0x%x [0x%x]\n",-					   ES_REG(ensoniq, 1371_CODEC), reg,-					   inl(ES_REG(ensoniq, 1371_CODEC)));-				return 0;-			}-			goto __again;-		}+		} while (time_after_eq(end_time, jiffies)); 	}+	snd_printk(KERN_ERR "codec read timeout (final) "+		   "at 0x%lx, reg = 0x%x [0x%x]\n",+		   ES_REG(ensoniq, 1371_CODEC), reg,+		   inl(ES_REG(ensoniq, 1371_CODEC))); 	mutex_unlock(&ensoniq->src_mutex);-	snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n",-		   ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC))); 	return 0; } 
-------------------------------------------------------------------------This SF.Net email is sponsored by the Moblin Your Move Developer's challengeBuild the coolest Linux based applications with Moblin SDK & win great prizesGrand prize is a trip for two to an Open Source event anywhere in the worldhttp://moblin-contest.org/redirect.php?banner_id=100&url=/_______________________________________________Alsa-user mailing listAlsa-user@xxxxxxxxxxxxxxxxxxxxxxxxxx://lists.sourceforge.net/lists/listinfo/alsa-user

[Index of Archives]     [ALSA Devel]     [Linux Audio Users]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

  Powered by Linux