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