Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [Fwd: Re: [PATCH] cs46xx DAC volume's mechanism rewrite, minor bugfixes]
@ 2002-11-10 23:53 Peter Good
  2002-11-11  8:56 ` Benny Sjostrand
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Good @ 2002-11-10 23:53 UTC (permalink / raw)
  To: alsa-devel


[-- 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 --]

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

* Re: [Fwd: Re: [PATCH] cs46xx DAC volume's mechanism rewrite, minor bugfixes]
  2002-11-11  8:56 ` Benny Sjostrand
@ 2002-11-11  8:49   ` Jaroslav Kysela
  2002-11-11 12:32     ` Benny Sjostrand
  0 siblings, 1 reply; 5+ messages in thread
From: Jaroslav Kysela @ 2002-11-11  8:49 UTC (permalink / raw)
  To: Benny Sjostrand; +Cc: Peter Good, alsa-devel@lists.sourceforge.net

On Mon, 11 Nov 2002, Benny Sjostrand wrote:

> >
> >
> >------------------------------------------------------------------------
> >
> >Ok, that's fixed the bass problem I had here.
> >One thing though. Benny, do you have any idea what these values "should"
> >be?
> >  
> >
> But I still dont understand the problem. And reports are not at all 
> consequent ...
> 
> >iec958:AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2
> >  
> >
> I guess you need to add in .asoundrc:
> iec958 {
>   type hw
>   card 0
>   device 2
> }
> 
> Then maybe someone knows what xine uses the 
> AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2 values to,
> do they need to interfaces to the lowlevel driver ???

It's first 32-bits to setup the channel status block in the S/PDIF 
stream. The main job is to tell the remote receiver, that data are 
'non-audio' (bit 1 = 1).

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

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

* Re: [Fwd: Re: [PATCH] cs46xx DAC volume's mechanism rewrite, minor bugfixes]
  2002-11-10 23:53 [Fwd: Re: [PATCH] cs46xx DAC volume's mechanism rewrite, minor bugfixes] Peter Good
@ 2002-11-11  8:56 ` Benny Sjostrand
  2002-11-11  8:49   ` Jaroslav Kysela
  0 siblings, 1 reply; 5+ messages in thread
From: Benny Sjostrand @ 2002-11-11  8:56 UTC (permalink / raw)
  To: Peter Good; +Cc: alsa-devel

>
>
>------------------------------------------------------------------------
>
>Ok, that's fixed the bass problem I had here.
>One thing though. Benny, do you have any idea what these values "should"
>be?
>  
>
But I still dont understand the problem. And reports are not at all 
consequent ...

>iec958:AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2
>  
>
I guess you need to add in .asoundrc:
iec958 {
  type hw
  card 0
  device 2
}

Then maybe someone knows what xine uses the 
AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2 values to,
do they need to interfaces to the lowlevel driver ???

/Benny




-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

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

* Re: [Fwd: Re: [PATCH] cs46xx DAC volume's mechanism rewrite, minor bugfixes]
  2002-11-11  8:49   ` Jaroslav Kysela
@ 2002-11-11 12:32     ` Benny Sjostrand
  2002-11-11 17:07       ` Jaroslav Kysela
  0 siblings, 1 reply; 5+ messages in thread
From: Benny Sjostrand @ 2002-11-11 12:32 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: Peter Good, alsa-devel@lists.sourceforge.net

> > Then maybe someone knows what xine uses the
> > AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2 values to,
> > do they need to interfaces to the lowlevel driver ???
>
> It's first 32-bits to setup the channel status block in the S/PDIF
> stream. The main job is to tell the remote receiver, that data are
> 'non-audio' (bit 1 = 1).

My first guess, how is this values interfaced to the lowlevel driver ?
I believe that I dont need to have any "AC3 Mode" switch in the
mixer if there already is way to know if application is opening
the IEC958 port for AC3/raw-data.

/Benny




-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

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

* Re: [Fwd: Re: [PATCH] cs46xx DAC volume's mechanism rewrite, minor bugfixes]
  2002-11-11 12:32     ` Benny Sjostrand
@ 2002-11-11 17:07       ` Jaroslav Kysela
  0 siblings, 0 replies; 5+ messages in thread
From: Jaroslav Kysela @ 2002-11-11 17:07 UTC (permalink / raw)
  To: Benny Sjostrand; +Cc: alsa-devel@lists.sourceforge.net

On Mon, 11 Nov 2002, Benny Sjostrand wrote:

> > > Then maybe someone knows what xine uses the
> > > AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2 values to,
> > > do they need to interfaces to the lowlevel driver ???
> >
> > It's first 32-bits to setup the channel status block in the S/PDIF
> > stream. The main job is to tell the remote receiver, that data are
> > 'non-audio' (bit 1 = 1).
> 
> My first guess, how is this values interfaced to the lowlevel driver ?
> I believe that I dont need to have any "AC3 Mode" switch in the
> mixer if there already is way to know if application is opening
> the IEC958 port for AC3/raw-data.

It's better to have one PCM device dedicated to a raw S/PDIF stream. Then
we have controls to obtain available channel status block bits and 
global / PCM settings:

  IEC958 [...] [Playback|Capture] Default       /* default or global value - read/write */
  IEC958 [...] [Playback|Capture] Mask          /* consumer and professional mask */
  IEC958 [...] [Playback|Capture] Con Mask      /* consumer mask */
  IEC958 [...] [Playback|Capture] Pro Mask      /* professional mask */
  IEC958 [...] [Playback|Capture] PCM Stream    /* the settings assigned to a PCM stream */

The behaviour implemented in drivers is:

- initialize IEC958 channel status block with value SNDRV_PCM_DEFAULT_CON_SPDIF
- raw S/PDIF open: copy default settings to local PCM settings
- (application optional: modify PCM settings - 'IEC958 Playback PCM Stream')
- raw S/PDIF close: return back the global settings

It seems quite complicated, but with many hardware we have 'mixed mode' 
when we need to output a final (mixed from many resources) stream with 
some IEC958 setup and do also ac3-forward (send raw S/PDIF stream). The 
settings for ac3-forward is valid only for one session (open/close) of 
course.

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

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

end of thread, other threads:[~2002-11-11 17:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-11-10 23:53 [Fwd: Re: [PATCH] cs46xx DAC volume's mechanism rewrite, minor bugfixes] Peter Good
2002-11-11  8:56 ` Benny Sjostrand
2002-11-11  8:49   ` Jaroslav Kysela
2002-11-11 12:32     ` Benny Sjostrand
2002-11-11 17:07       ` Jaroslav Kysela

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