diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-26 16:59:39 +0000 | 
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-26 20:24:10 +0000 | 
| commit | 58e8a4741b519910cdabdd55c23f258e40cf6a3a (patch) | |
| tree | 2781f2a841319e2320c0108046309687081277c3 /sound/arm | |
| parent | e831d80b453a3586f1e1664a705c153a4ced39b8 (diff) | |
| download | linux-58e8a4741b519910cdabdd55c23f258e40cf6a3a.tar.bz2 | |
ALSA: AACI: fix channel mask selection
When double-rate mode was selected, we weren't setting the additional
two channel mask bits to allow double-rate to work.  Rearrange the
hw_params code to allow the correct channel mask to be selected.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'sound/arm')
| -rw-r--r-- | sound/arm/aaci.c | 70 | 
1 files changed, 20 insertions, 50 deletions
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index ab66d462d865..8915e56d1b51 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -490,12 +490,21 @@ static int aaci_pcm_hw_free(struct snd_pcm_substream *substream)  	return 0;  } +/* Channel to slot mask */ +static const u32 channels_to_slotmask[] = { +	[2] = CR_SL3 | CR_SL4, +	[4] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8, +	[6] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8 | CR_SL6 | CR_SL9, +}; +  static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, -			      struct aaci_runtime *aacirun,  			      struct snd_pcm_hw_params *params)  { +	struct aaci_runtime *aacirun = substream->runtime->private_data; +	unsigned int channels = params_channels(params); +	unsigned int rate = params_rate(params); +	int dbl = rate > 48000;  	int err; -	struct aaci *aaci = substream->private_data;  	aaci_pcm_hw_free(substream);  	if (aacirun->pcm_open) { @@ -503,18 +512,21 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,  		aacirun->pcm_open = 0;  	} +	/* channels is already limited to 2, 4, or 6 by aaci_rule_channels */ +	if (dbl && channels != 2) +		return -EINVAL; +  	err = snd_pcm_lib_malloc_pages(substream,  				       params_buffer_bytes(params));  	if (err >= 0) { -		unsigned int rate = params_rate(params); -		int dbl = rate > 48000; +		struct aaci *aaci = substream->private_data; -		err = snd_ac97_pcm_open(aacirun->pcm, rate, -					params_channels(params), +		err = snd_ac97_pcm_open(aacirun->pcm, rate, channels,  					aacirun->pcm->r[dbl].slots);  		aacirun->pcm_open = err == 0;  		aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; +		aacirun->cr |= channels_to_slotmask[channels + dbl * 2];  		aacirun->fifosz = aaci->fifosize * 4;  		if (aacirun->cr & CR_COMPACT) @@ -551,34 +563,6 @@ static snd_pcm_uframes_t aaci_pcm_pointer(struct snd_pcm_substream *substream)  /*   * Playback specific ALSA stuff   */ -static const u32 channels_to_txmask[] = { -	[2] = CR_SL3 | CR_SL4, -	[4] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8, -	[6] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8 | CR_SL6 | CR_SL9, -}; - -static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, -				       struct snd_pcm_hw_params *params) -{ -	struct aaci_runtime *aacirun = substream->runtime->private_data; -	unsigned int channels = params_channels(params); -	int ret; - -	WARN_ON(channels >= ARRAY_SIZE(channels_to_txmask) || -		!channels_to_txmask[channels]); - -	ret = aaci_pcm_hw_params(substream, aacirun, params); - -	/* -	 * Enable FIFO, compact mode, 16 bits per sample. -	 * FIXME: double rate slots? -	 */ -	if (ret >= 0) -		aacirun->cr |= channels_to_txmask[channels]; - -	return ret; -} -  static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun)  {  	u32 ie; @@ -648,27 +632,13 @@ static struct snd_pcm_ops aaci_playback_ops = {  	.open		= aaci_pcm_open,  	.close		= aaci_pcm_close,  	.ioctl		= snd_pcm_lib_ioctl, -	.hw_params	= aaci_pcm_playback_hw_params, +	.hw_params	= aaci_pcm_hw_params,  	.hw_free	= aaci_pcm_hw_free,  	.prepare	= aaci_pcm_prepare,  	.trigger	= aaci_pcm_playback_trigger,  	.pointer	= aaci_pcm_pointer,  }; -static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream, -				      struct snd_pcm_hw_params *params) -{ -	struct aaci_runtime *aacirun = substream->runtime->private_data; -	int ret; - -	ret = aaci_pcm_hw_params(substream, aacirun, params); -	if (ret >= 0) -		/* Line in record: slot 3 and 4 */ -		aacirun->cr |= CR_SL3 | CR_SL4; - -	return ret; -} -  static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun)  {  	u32 ie; @@ -765,7 +735,7 @@ static struct snd_pcm_ops aaci_capture_ops = {  	.open		= aaci_pcm_open,  	.close		= aaci_pcm_close,  	.ioctl		= snd_pcm_lib_ioctl, -	.hw_params	= aaci_pcm_capture_hw_params, +	.hw_params	= aaci_pcm_hw_params,  	.hw_free	= aaci_pcm_hw_free,  	.prepare	= aaci_pcm_capture_prepare,  	.trigger	= aaci_pcm_capture_trigger,  |