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