All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Good <psgood@petesinternet.net>
To: alsa-devel@lists.sourceforge.net
Subject: [Fwd: Re: [PATCH] cs46xx DAC volume's mechanism rewrite, minor bugfixes]
Date: 11 Nov 2002 09:53:58 +1000	[thread overview]
Message-ID: <1036972438.4956.0.camel@pete> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 238 bytes --]

Dammit, forgot to cc to here heh.
-- 
"I am neither especially clever nor especially 
gifted. I am only very, very curious." Einstein.

Peter Good
Pete's Internet Services
GnuPG Public Key: http://www.petesinternet.net/public.gpg

[-- Attachment #1.2: Forwarded message - Re: [Alsa-devel] [PATCH] cs46xx DAC volume's mechanism rewrite, minor bugfixes --]
[-- Type: message/rfc822, Size: 27966 bytes --]

[-- Attachment #1.2.1.1: Type: text/plain, Size: 27016 bytes --]

Ok, that's fixed the bass problem I had here.
One thing though. Benny, do you have any idea what these values "should"
be?

iec958:AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2

Now that's what xine gives me, but, I know that can be reset via xine's
config file. mplayer on the other hand gives this.

alsa-init: testing and bugreports are welcome.
alsa-init: requested format: 48000 Hz, 2 channels, AC3
alsa-init: compiled for ALSA-0.9.0rc5
alsa-spdif-init: playing AC3, 2 channels
alsa-init: soundcard set to iec958:AES0=0x2,AES1=0x82,AES2=0x0,AES3=0x2
ALSA lib pcm.c:1719:(snd_pcm_open_conf) Invalid type for PCM
iec958:AES0=0x2,AES1=0x82,AES2=0x0,AES3=0x2 definition (id: iec958,
value: cards.pcm.iec958)
alsa-init: playback open error: Invalid argument
couldn't open/init audio device -> NOSOUND

hehe, any ideas on what the values should be would be appreciated.

Peter


On Mon, 2002-11-11 at 05:38, Benny Sjostrand wrote:
> Hi!
> 
> This patch changes the way the DAC volume are set on DSP SCB tasks. I 
> would like to know
> if maybe this fixes the "bass"  problem that some users have experienced 
> with the cs46xx driver.
> 
> Still some more attempts to have AC3 through IEC958, but no success yet ...
> 
> Summary:
> - DAC volume mechanism  rewrite (added cs46xx_dsp_set_dac_volume (...) 
> in dsp_spos.c)
> - IEC958 input volume mechanism rewrite (added 
> cs46xx_dsp_set_iec958_volume (...) in dsp_spos.c)
> - Enable IEC958 hw if not done in cs46xx_iec958_pre_open (...)
> - Added "AC3 Mode Switch" in mixer, when enabled appropiate status
> bit's (non-audio, profesional) are set in IEC958 stream and PCM channel 
> is locked to 48Khz
> - Typo fix in constant name DSP_SDPIF... -> DSP_SPDIF...
> - Some code cleanups
> 
> /Benny
> ----
> 

> diff --exclude=Makefile --exclude=CVS -Naur alsa-kernel/include/cs46xx_dsp_spos.h ../cvs/alsa-kernel/include/cs46xx_dsp_spos.h
> --- alsa-kernel/include/cs46xx_dsp_spos.h	Mon Nov  4 19:49:48 2002
> +++ ../cvs/alsa-kernel/include/cs46xx_dsp_spos.h	Sun Nov 10 14:35:17 2002
> @@ -60,9 +60,10 @@
>  #define DSP_PCM_LFE_CHANNEL     4
>  #define DSP_IEC958_CHANNEL      5
>  
> -#define DSP_SDPIF_STATUS_OUTPUT_ENABLED 1
> -#define DSP_SDPIF_STATUS_PLAYBACK_OPEN  2
> -#define DSP_SDPIF_STATUS_HW_ENABLED     4
> +#define DSP_SPDIF_STATUS_OUTPUT_ENABLED 1
> +#define DSP_SPDIF_STATUS_PLAYBACK_OPEN  2
> +#define DSP_SPDIF_STATUS_HW_ENABLED     4
> +#define DSP_SPDIF_STATUS_AC3_MODE       8
>  
>  struct _dsp_module_desc_t;
>  
> @@ -155,6 +156,8 @@
>  
>  	/* Main PCM playback mixer */
>  	dsp_scb_descriptor_t * master_mix_scb;
> +	u16 dac_volume_right;
> +	u16 dac_volume_left;
>  
>  	/* Rear PCM playback mixer */
>  	dsp_scb_descriptor_t * rear_mix_scb;
> @@ -191,7 +194,8 @@
>  	/* SPDIF status */
>  	int spdif_status_out;
>  	int spdif_status_in;
> -	u32 spdif_input_volume;
> +	u16 spdif_input_volume_right;
> +	u16 spdif_input_volume_left;
>  
>  	/* SPDIF input sample rate converter */
>  	dsp_scb_descriptor_t * spdif_in_src;
> @@ -221,4 +225,3 @@
>  } dsp_spos_instance_t;
>  
>  #endif /* __DSP_SPOS_H__ */
> -
> diff --exclude=Makefile --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx_lib.c ../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.c
> --- alsa-kernel/pci/cs46xx/cs46xx_lib.c	Mon Nov  4 19:49:57 2002
> +++ ../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.c	Sun Nov 10 15:10:22 2002
> @@ -952,7 +952,9 @@
>  			snd_cs46xx_playback_transfer(substream, 0);
>  
>  		/* raise playback volume */
> -		snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 0xE) << 2, 0x80008000);
> +		cs46xx_dsp_scb_set_volume (chip,cpcm->pcm_channel->pcm_reader_scb,
> +					   chip->dsp_spos_instance->dac_volume_right,
> +					   chip->dsp_spos_instance->dac_volume_left);
>  #else
>  		if (substream->runtime->periods != CS46XX_FRAGS)
>  			snd_cs46xx_playback_transfer(substream, 0);
> @@ -966,8 +968,9 @@
>  	case SNDRV_PCM_TRIGGER_STOP:
>  	case SNDRV_PCM_TRIGGER_SUSPEND:
>  #ifdef CONFIG_SND_CS46XX_NEW_DSP
> -        /* mute channel */
> -		snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 0xE) << 2, 0xffffffff);
> +		/* mute channel */
> +		cs46xx_dsp_scb_set_volume (chip,cpcm->pcm_channel->pcm_reader_scb,0,0);
> +
>  		if (!cpcm->pcm_channel->unlinked)
>  			cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel);
>  #else
> @@ -1020,36 +1023,27 @@
>  	return result;
>  }
>  
> -static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
> -					 snd_pcm_hw_params_t * hw_params)
> +static int _cs46xx_adjust_sample_rate (cs46xx_t *chip, cs46xx_pcm_t *cpcm,
> +				       int sample_rate) 
>  {
> -	/*cs46xx_t *chip = snd_pcm_substream_chip(substream);*/
> -	snd_pcm_runtime_t *runtime = substream->runtime;
> -	cs46xx_pcm_t *cpcm;
> -	int err;
> -	cs46xx_t *chip = snd_pcm_substream_chip(substream);
> -	int sample_rate = params_rate(hw_params);
> -	int period_size = params_period_size(hw_params);
> -	cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO);
> -
> -#ifdef CONFIG_SND_CS46XX_NEW_DSP
> -	down (&chip->spos_mutex);
> -
> -	snd_assert (cpcm->pcm_channel != NULL);
> -
> +	/* if this is the only PCMReaderSCB child under current
> +	   SrcTask then there no need to re-create pcm-channel */
>  	if ( cpcm->pcm_channel->src_scb->ref_count == 1 &&
>  	     cpcm->pcm_channel->sample_rate != sample_rate &&
>  	     /* never set a 0 khz sample rate */
>  	     sample_rate) {
>  		/* sample rate not set or we can reuse
>  		   the same SRC*/
> -
>  		cs46xx_dsp_set_src_sample_rate (chip,cpcm->pcm_channel->src_scb,sample_rate);
>  		cpcm->pcm_channel->sample_rate = sample_rate;
>  	} 
>  
> -	if (cpcm->pcm_channel->sample_rate != runtime->rate &&
> -	    cpcm->pcm_channel->src_scb->ref_count != 1) {
> +	/* if there is more then 1 PCMReaderSCB child's under current
> +	   SrcTask then we must recreate channel */
> +	if (cpcm->pcm_channel->sample_rate != sample_rate &&
> +	    cpcm->pcm_channel->src_scb->ref_count != 1 &&
> +	    /* never set a 0 khz sample rate */
> +	    sample_rate) {
>  		int unlinked = cpcm->pcm_channel->unlinked;
>  		cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel);
>  
> @@ -1065,6 +1059,34 @@
>  		cpcm->pcm_channel->sample_rate = sample_rate;
>  	}
>  
> +	return 0;
> +}
> +static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
> +					 snd_pcm_hw_params_t * hw_params)
> +{
> +	/*cs46xx_t *chip = snd_pcm_substream_chip(substream);*/
> +	snd_pcm_runtime_t *runtime = substream->runtime;
> +	cs46xx_pcm_t *cpcm;
> +	int err;
> +	cs46xx_t *chip = snd_pcm_substream_chip(substream);
> +	int sample_rate = params_rate(hw_params);
> +	int period_size = params_period_size(hw_params);
> +	cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO);
> +
> +#ifdef CONFIG_SND_CS46XX_NEW_DSP
> +	down (&chip->spos_mutex);
> +
> +	snd_assert (cpcm->pcm_channel != NULL);
> +
> +	/* if IEC958 is opened in AC3 mode dont adjust SRCTask is not
> +	   used so dont adjust sample rate */
> +	if (cpcm->pcm_channel->pcm_channel_id != DSP_IEC958_CHANNEL ||
> +	    !(chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE)) {
> +		if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) {
> +			return -ENXIO;
> +		}
> +	}
> +
>  	if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size * 4)) {
>  		 up (&chip->spos_mutex);
>  		 return -EINVAL;
> @@ -1825,7 +1847,7 @@
>  	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
>  	uinfo->count = 2;
>  	uinfo->value.integer.min = 0;
> -	uinfo->value.integer.max = 32767;
> +	uinfo->value.integer.max = 0x7fff;
>  	return 0;
>  }
>  
> @@ -1847,26 +1869,9 @@
>  			    (0xffff - ucontrol->value.integer.value[1]));
>  	unsigned int old = snd_cs46xx_peek(chip, reg);
>  	int change = (old != val);
> +
>  	if (change) {
>  		snd_cs46xx_poke(chip, reg, val);
> -#ifdef CONFIG_SND_CS46XX_NEW_DSP
> -		/* NOTE: this updates the current left and right volume
> -		   that should be automatically updated by the DSP and
> -		   not touched by the host. But for some strange reason
> -		   the DSP only updates the right channel volume, so with
> -		   this dirty hack we force updating the right and left
> -		   channel volume. 
> -		*/
> -		snd_cs46xx_poke(chip, reg + 4, val);
> -
> -		/* shadow the SPDIF input volume */
> -		if (reg == (ASYNCRX_SCB_ADDR + 0xE) << 2) {
> -			/* FIXME: I known this is uggly ...
> -			   any other suggestion ? 
> -			*/
> -			chip->dsp_spos_instance->spdif_input_volume = val;
> -		}
> -#endif
>  	}
>  
>  	return change;
> @@ -1874,6 +1879,57 @@
>  
>  #ifdef CONFIG_SND_CS46XX_NEW_DSP
>  
> +static int snd_cs46xx_vol_dac_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
> +{
> +	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
> +
> +	ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_right;
> +	ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_left;
> +
> +	return 0;
> +}
> +
> +static int snd_cs46xx_vol_dac_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
> +{
> +	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
> +	int change = 0;
> +
> +	if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] ||
> +	    chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) {
> +		cs46xx_dsp_set_dac_volume(chip,
> +					  ucontrol->value.integer.value[0],
> +					  ucontrol->value.integer.value[1]);
> +		change = 1;
> +	}
> +
> +	return change;
> +}
> +
> +static int snd_cs46xx_vol_iec958_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
> +{
> +	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
> +
> +	ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_right;
> +	ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_left;
> +	return 0;
> +}
> +
> +static int snd_cs46xx_vol_iec958_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
> +{
> +	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
> +	int change = 0;
> +
> +	if (chip->dsp_spos_instance->spdif_input_volume_right != ucontrol->value.integer.value[0] ||
> +	    chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->value.integer.value[1]) {
> +		cs46xx_dsp_set_iec958_volume (chip,
> +					      ucontrol->value.integer.value[0],
> +					      ucontrol->value.integer.value[1]);
> +		change = 1;
> +	}
> +
> +	return change;
> +}
> +
>  static int snd_mixer_boolean_info(snd_kcontrol_t *kcontrol, 
>  				  snd_ctl_elem_info_t *uinfo)
>  {
> @@ -1891,7 +1947,7 @@
>  	int reg = kcontrol->private_value;
>  
>  	if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT)
> -		ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SDPIF_STATUS_OUTPUT_ENABLED);
> +		ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
>  	else
>  		ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in;
>  
> @@ -1907,13 +1963,13 @@
>  	switch (kcontrol->private_value) {
>  	case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT:
>  		down (&chip->spos_mutex);
> -		change = (chip->dsp_spos_instance->spdif_status_out & DSP_SDPIF_STATUS_OUTPUT_ENABLED);
> +		change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
>  		if (ucontrol->value.integer.value[0] && !change) 
>  			cs46xx_dsp_enable_spdif_out(chip);
>  		else if (change && !ucontrol->value.integer.value[0])
>  			cs46xx_dsp_disable_spdif_out(chip);
>  
> -		res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SDPIF_STATUS_OUTPUT_ENABLED));
> +		res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED));
>  		up (&chip->spos_mutex);
>  		break;
>  	case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:
> @@ -1979,6 +2035,35 @@
>  	return 0;
>  }
>  
> +static int snd_cs46xx_iec958_ac3_mode_get(snd_kcontrol_t *kcontrol, 
> +					  snd_ctl_elem_value_t *ucontrol) 
> +{
> +	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
> +	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
> +
> +	if (!ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE) 
> +		ucontrol->value.integer.value[0] = 1;
> +	else
> +		ucontrol->value.integer.value[0] = 0;
> +
> +	return 0;
> +}
> +
> +static int snd_cs46xx_iec958_ac3_mode_put(snd_kcontrol_t *kcontrol, 
> +                                      snd_ctl_elem_value_t *ucontrol) 
> +{
> +	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
> +	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
> +	int old = ins->spdif_status_out;
> +
> +	if (ucontrol->value.integer.value[0]) 
> +		ins->spdif_status_out |= DSP_SPDIF_STATUS_AC3_MODE;
> +	else
> +		ins->spdif_status_out &= ~DSP_SPDIF_STATUS_AC3_MODE;
> +
> +	return (old != ins->spdif_status_out);
> +}
> +
>  static int snd_cs46xx_pcm_capture_put(snd_kcontrol_t *kcontrol, 
>                                        snd_ctl_elem_value_t *ucontrol)
>  {
> @@ -2013,7 +2098,7 @@
>  }
>  
>  /*
> - *	Game Theatre XP card - EGPIO[0] is used to select SDPIF input optical or coaxial.
> + *	Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
>   */ 
>  static int snd_herc_spdif_select_put(snd_kcontrol_t *kcontrol, 
>                                         snd_ctl_elem_value_t *ucontrol)
> @@ -2111,13 +2196,13 @@
>  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
>  	.name = "DAC Volume",
>  	.info = snd_cs46xx_vol_info,
> +#ifndef CONFIG_SND_CS46XX_NEW_DSP
>  	.get = snd_cs46xx_vol_get,
>  	.put = snd_cs46xx_vol_put,
> -
> -#ifndef CONFIG_SND_CS46XX_NEW_DSP
>  	.private_value = BA1_PVOL,
>  #else
> -	.private_value = (MASTERMIX_SCB_ADDR + 0xE) << 2,
> +	.get = snd_cs46xx_vol_dac_get,
> +	.put = snd_cs46xx_vol_dac_put,
>  #endif
>  },
>  
> @@ -2158,6 +2243,13 @@
>  },
>  {
>  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> +	.name = "IEC 958 AC3 Mode Switch",
> +	.info = snd_mixer_boolean_info,
> +	.get = snd_cs46xx_iec958_ac3_mode_get,
> +	.put = snd_cs46xx_iec958_ac3_mode_put,
> +},
> +{
> +	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
>  	.name = "IEC 958 Input Switch",
>  	.info = snd_mixer_boolean_info,
>  	.get = snd_cs46xx_iec958_get,
> @@ -2168,8 +2260,8 @@
>  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
>  	.name = "IEC 958 Input Volume",
>  	.info = snd_cs46xx_vol_info,
> -	.get = snd_cs46xx_vol_get,
> -	.put = snd_cs46xx_vol_put,
> +	.get = snd_cs46xx_vol_iec958_get,
> +	.put = snd_cs46xx_vol_iec958_put,
>  	.private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2,
>  },
>  #endif
> diff --exclude=Makefile --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx_lib.h ../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.h
> --- alsa-kernel/pci/cs46xx/cs46xx_lib.h	Mon Nov  4 19:49:57 2002
> +++ ../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.h	Sun Nov 10 02:18:12 2002
> @@ -217,4 +217,6 @@
>  							       int period_size);
>  int                        cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
>  							      int period_size);
> +int                        cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 right,u16 left);
> +int                        cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 right,u16 left);
>  #endif /* __CS46XX_LIB_H__ */
> diff --exclude=Makefile --exclude=CVS -Naur alsa-kernel/pci/cs46xx/dsp_spos.c ../cvs/alsa-kernel/pci/cs46xx/dsp_spos.c
> --- alsa-kernel/pci/cs46xx/dsp_spos.c	Mon Nov  4 19:49:57 2002
> +++ ../cvs/alsa-kernel/pci/cs46xx/dsp_spos.c	Sun Nov 10 14:37:34 2002
> @@ -257,7 +257,10 @@
>  	ins->spdif_in_sample_rate = 48000;
>  
>  	/* maximize volume */
> -	ins->spdif_input_volume = 0x80008000;
> +	ins->dac_volume_right = 0x8000;
> +	ins->dac_volume_left = 0x8000;
> +	ins->spdif_input_volume_right = 0x8000;
> +	ins->spdif_input_volume_left = 0x8000;
>  
>  	return ins;
>  }
> @@ -1549,7 +1552,7 @@
>  	cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 << 12));
>  
>  	/* monitor state */
> -	ins->spdif_status_out |= DSP_SDPIF_STATUS_HW_ENABLED;
> +	ins->spdif_status_out |= DSP_SPDIF_STATUS_HW_ENABLED;
>  
>  	return 0;
>  }
> @@ -1585,8 +1588,10 @@
>  	cs46xx_src_link(chip,ins->spdif_in_src);
>  
>  	/* restore SPDIF input volume */
> -	snd_cs46xx_poke(chip, (ASYNCRX_SCB_ADDR + 0xE) << 2, ins->spdif_input_volume);
> -	snd_cs46xx_poke(chip, (ASYNCRX_SCB_ADDR + 0xF) << 2, ins->spdif_input_volume);
> +	cs46xx_dsp_scb_set_volume (chip,ins->spdif_in_src,
> +				   ins->spdif_input_volume_right,
> +				   ins->spdif_input_volume_left);
> +
>  	spin_unlock_irq(&chip->reg_lock);
>  
>  	/* set SPDIF input sample rate and unmute
> @@ -1716,6 +1721,44 @@
>  		snd_printk(KERN_ERR "dsp_spos: SPIOWriteTask not responding\n");
>  		return -EBUSY;
>  	}
> +
> +	return 0;
> +}
> +
> +int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 right,u16 left)
> +{
> +	int i;
> +	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
> +
> +	down(&chip->spos_mutex);
> +
> +	ins->dac_volume_right = right;
> +	ins->dac_volume_left = left;
> +
> +	for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) {
> +		if (ins->pcm_channels[i].active &&
> +		    !ins->pcm_channels[i].unlinked) {
> +			cs46xx_dsp_scb_set_volume (chip,ins->pcm_channels[i].pcm_reader_scb,
> +						   right,left);
> +			
> +		}
> +	}
> +
> +	up(&chip->spos_mutex);
> +
> +	return 0;
> +}
> +
> +int cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 right,u16 left) {
> +	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
> +
> +	down(&chip->spos_mutex);
> +	cs46xx_dsp_scb_set_volume (chip,ins->spdif_in_src,
> +				   right,left);
> +
> +	ins->spdif_input_volume_right = right;
> +	ins->spdif_input_volume_left = left;
> +	up(&chip->spos_mutex);
>  
>  	return 0;
>  }
> diff --exclude=Makefile --exclude=CVS -Naur alsa-kernel/pci/cs46xx/dsp_spos.h ../cvs/alsa-kernel/pci/cs46xx/dsp_spos.h
> --- alsa-kernel/pci/cs46xx/dsp_spos.h	Mon Nov  4 19:49:57 2002
> +++ ../cvs/alsa-kernel/pci/cs46xx/dsp_spos.h	Sun Nov 10 17:03:50 2002
> @@ -76,6 +76,7 @@
>  #define MIX_SAMPLE_BUF2          0x2D00
>  #define MIX_SAMPLE_BUF3          0x2E00
>  #define MIX_SAMPLE_BUF4          0x2F00
> +#define MIX_SAMPLE_BUF5          0x3000
>  
>  /* Task stack address */
>  #define HFG_STACK                0x066A
> @@ -127,6 +128,7 @@
>  #define SCBfuncEntryPtr      0xA
>  #define SRCCorPerGof         0x2
>  #define SRCPhiIncr6Int26Frac 0xd
> +#define SCBVolumeCtrl        0xe
>  
>  /* conf */
>  #define UseASER1Input 1
> @@ -190,6 +192,14 @@
>  			(scb->address + SCBsubListPtr) << 2,
>  			(scb->sub_list_ptr->address << 0x10) |
>  			(scb->next_scb_ptr->address));	
> +}
> +
> +static inline void cs46xx_dsp_scb_set_volume (cs46xx_t * chip,dsp_scb_descriptor_t * scb,
> +					      u16 right,u16 left) {
> +	unsigned int val = ((0xffff - right) << 16 | (0xffff - left));	
> +
> +	snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
> +	snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);
>  }
>  
>  #endif /* __DSP_SPOS_H__ */
> diff --exclude=Makefile --exclude=CVS -Naur alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c ../cvs/alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c
> --- alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c	Mon Nov  4 19:49:57 2002
> +++ ../cvs/alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c	Sun Nov 10 17:55:24 2002
> @@ -603,7 +603,7 @@
>  		src_buffer_addr << 0x10,
>  		0x04000000,
>  		{ 
> -			0xffff,0xffff,
> +			0x8000,0x8000,
>  			0xffff,0xffff
>  		}
>  	};
> @@ -658,7 +658,7 @@
>  		/* D */ 0,
>  		{
>  			/* E */ 0x8000,0x8000,
> -			/* F */ 0x8000,0x8000
> +			/* F */ 0xffff,0xffff
>  		}
>  	};
>  
> @@ -825,7 +825,7 @@
>  		0x0058,0x0028,      /* Min Delta 7 dwords == 28 bytes */
>  		/* : Max delta 25 dwords == 100 bytes */
>  		0,hfg_scb_address,  /* Point to HFG task SCB */
> -		0,0,				/* Initialize current Delta and Consumer ptr adjustment count */
> +		0,0,		    /* Initialize current Delta and Consumer ptr adjustment count */
>  		0,                  /* Initialize accumulated Phi to 0 */
>  		0,0x2aab,           /* Const 1/3 */
>      
> @@ -840,13 +840,13 @@
>      
>  		RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_256, /* Stereo, 256 dword */
>  		(asynch_buffer_address) << 0x10,  /* This should be automagically synchronized
> -                                             to the producer pointer */
> +                                                     to the producer pointer */
>      
>  		/* There is no correct initial value, it will depend upon the detected
>  		   rate etc  */
>  		0x18000000,                     /* Phi increment for approx 32k operation */
>  		0x8000,0x8000,                  /* Volume controls are unused at this time */
> -		0x8000,0x8000
> +		0xffff,0xffff
>  	};
>    
>  	scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_tx_scb,
> @@ -1114,7 +1114,13 @@
>  		snd_assert(0);
>  		break;
>  	case DSP_IEC958_CHANNEL:
> +		snd_assert (ins->asynch_tx_scb != NULL, return NULL);
>  		mixer_scb = ins->asynch_tx_scb;
> +		if (ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE) {
> +			snd_printdd ("IEC958 opened in AC3 mode\n");
> +			/*src_scb = ins->asynch_tx_scb;
> +			  ins->asynch_tx_scb->ref_count ++;*/
> +		}
>  		break;
>  	default:
>  		snd_assert (0);
> @@ -1192,7 +1198,9 @@
>  			return NULL;
>  		}
>  
> -		cs46xx_dsp_set_src_sample_rate(chip,src_scb,sample_rate);
> +		if (pcm_channel_id != DSP_IEC958_CHANNEL ||
> +		    !(ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE))
> +			cs46xx_dsp_set_src_sample_rate(chip,src_scb,sample_rate);
>  
>  		ins->nsrc_scb ++;
>  	} 
> @@ -1454,14 +1462,16 @@
>  	spin_lock_irqsave(&chip->reg_lock, flags);
>  
>  	/* mute SCB */
> -	snd_cs46xx_poke(chip, (src->address + 0xE) << 2, 0xffffffff);
> +	/* cs46xx_dsp_scb_set_volume (chip,src,0,0); */
> +
>  	snd_cs46xx_poke(chip, (src->address + SRCCorPerGof) << 2,
>  	  ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
>  
>  	snd_cs46xx_poke(chip, (src->address + SRCPhiIncr6Int26Frac) << 2, phiIncr);
>  
>  	/* raise volume */
> -	snd_cs46xx_poke(chip, (src->address + 0xE) << 2, 0x80008000);
> +	/* cs46xx_dsp_scb_set_volume (chip,src,0x7fff,0x7fff); */
> +	
>  	spin_unlock_irqrestore(&chip->reg_lock, flags);
>  }
>  
> @@ -1495,7 +1505,7 @@
>  	snd_assert (src->parent_scb_ptr != NULL,  return -EINVAL );
>  
>  	/* mute SCB */
> -	snd_cs46xx_poke(chip, (src->address + 0xE) << 2, 0xffffffff);
> +	cs46xx_dsp_scb_set_volume (chip,src,0,0);
>  
>  	_dsp_unlink_scb (chip,src);
>  
> @@ -1530,16 +1540,16 @@
>  {
>  	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
>  
> -	if ( ! (ins->spdif_status_out & DSP_SDPIF_STATUS_PLAYBACK_OPEN) ) {
> +	if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) ) {
>  		cs46xx_dsp_enable_spdif_hw (chip);
>  	}
>  
>  	/* dont touch anything if SPDIF is open */
> -	if ( ins->spdif_status_out & DSP_SDPIF_STATUS_PLAYBACK_OPEN) {
> +	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
>  		/* when cs46xx_iec958_post_close(...) is called it
>  		   will call this function if necesary depending on
>  		   this bit */
> -		ins->spdif_status_out |= DSP_SDPIF_STATUS_OUTPUT_ENABLED;
> +		ins->spdif_status_out |= DSP_SPDIF_STATUS_OUTPUT_ENABLED;
>  
>  		return -EBUSY;
>  	}
> @@ -1569,7 +1579,7 @@
>  	if (!ins->spdif_pcm_input_scb) return -ENOMEM;
>  
>  	/* monitor state */
> -	ins->spdif_status_out |= DSP_SDPIF_STATUS_OUTPUT_ENABLED;
> +	ins->spdif_status_out |= DSP_SPDIF_STATUS_OUTPUT_ENABLED;
>  
>  	return 0;
>  }
> @@ -1579,8 +1589,8 @@
>  	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
>  
>  	/* dont touch anything if SPDIF is open */
> -	if ( ins->spdif_status_out & DSP_SDPIF_STATUS_PLAYBACK_OPEN) {
> -		ins->spdif_status_out &= ~DSP_SDPIF_STATUS_OUTPUT_ENABLED;
> +	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
> +		ins->spdif_status_out &= ~DSP_SPDIF_STATUS_OUTPUT_ENABLED;
>  		return -EBUSY;
>  	}
>  
> @@ -1600,7 +1610,7 @@
>  	_dsp_clear_sample_buffer(chip,SPDIFO_IP_OUTPUT_BUFFER1,256);
>  
>  	/* monitor state */
> -	ins->spdif_status_out  &= ~DSP_SDPIF_STATUS_OUTPUT_ENABLED;
> +	ins->spdif_status_out  &= ~DSP_SPDIF_STATUS_OUTPUT_ENABLED;
>  
>  
>  	return 0;
> @@ -1610,12 +1620,17 @@
>  {
>  	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
>  
> -	if ( ins->spdif_status_out & DSP_SDPIF_STATUS_OUTPUT_ENABLED ) {
> +	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED ) {
>  		/* remove AsynchFGTxSCB and and PCMSerialInput_II */
>  		cs46xx_dsp_disable_spdif_out (chip);
>  
>  		/* save state */
> -		ins->spdif_status_out |= DSP_SDPIF_STATUS_OUTPUT_ENABLED;
> +		ins->spdif_status_out |= DSP_SPDIF_STATUS_OUTPUT_ENABLED;
> +	}
> +	
> +	/* if not enabled already */
> +	if (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) {
> +		cs46xx_dsp_enable_spdif_hw (chip);
>  	}
>  
>  	/* Create the asynch. transfer task  for playback */
> @@ -1625,10 +1640,12 @@
>  								ins->master_mix_scb,
>  								SCB_ON_PARENT_NEXT_SCB);
>  
> -	/* cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 15) | 
> -	   (1 << 14) | (1 << 2) | (1 << 3)); */
>  
> -	ins->spdif_status_out  |= DSP_SDPIF_STATUS_PLAYBACK_OPEN;
> +	if (ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE) 
> +		/* set left (13), right validity bit (12) , and non-audio(1) and profsional bit (0) */
> +		cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 << 12) | (1 << 1) | 1);
> +
> +	ins->spdif_status_out  |= DSP_SPDIF_STATUS_PLAYBACK_OPEN;
>  
>  	return 0;
>  }
> @@ -1639,16 +1656,17 @@
>  
>  	snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL);
>  
> -	ins->spdif_status_out  &= ~DSP_SDPIF_STATUS_PLAYBACK_OPEN;
> +	ins->spdif_status_out  &= ~DSP_SPDIF_STATUS_PLAYBACK_OPEN;
>  
> -	/*cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 << 12));*/
> +	/* restore settings */
> +	cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x00000000 | (1 << 13) | (1 << 12));
>  	
>  	/* deallocate stuff */
>  	cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
>  	ins->asynch_tx_scb = NULL;
>  
>  	/* restore state */
> -	if ( ins->spdif_status_out & DSP_SDPIF_STATUS_OUTPUT_ENABLED ) {
> +	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED ) {
>  		cs46xx_dsp_enable_spdif_out (chip);
>  	}
>  	
-- 
"I am neither especially clever nor especially 
gifted. I am only very, very curious." Einstein.

Peter Good
Pete's Internet Services
GnuPG Public Key: http://www.petesinternet.net/public.gpg

[-- Attachment #1.2.1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 196 bytes --]

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

             reply	other threads:[~2002-11-10 23:53 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-11-10 23:53 Peter Good [this message]
2002-11-11  8:56 ` [Fwd: Re: [PATCH] cs46xx DAC volume's mechanism rewrite, minor bugfixes] Benny Sjostrand
2002-11-11  8:49   ` Jaroslav Kysela
2002-11-11 12:32     ` Benny Sjostrand
2002-11-11 17:07       ` Jaroslav Kysela

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1036972438.4956.0.camel@pete \
    --to=psgood@petesinternet.net \
    --cc=alsa-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.