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
--- Begin Message ---
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: signature.asc
Description: This is a digitally signed message part

--- End Message ---

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to