The S/PDIF output was muted whenever audio wasn't playing which resulted in a clicking noise from the DAC when resuming (similar to the issue in 3bef1c377d1b (ALSA: hda - stop setup_dig_out_stream() causing clicks)). Also, the mixer control wasn't actually controlling the S/PDIF output.
- Fix the initial state of the mixer to match the initial muted state. - Mute the output at shutdown. - Delete the code that modifies OXYGEN_SPDIF_OUT_ENABLE, and modify it only in oxygen_update_spdif_source(), so only the mixer control controls it.
Signed-off-by: Laurence Darby ldarby@tuffmail.com --- Patch is against master, tested on 4.0.
sound/pci/oxygen/oxygen_lib.c | 5 ++++- sound/pci/oxygen/oxygen_mixer.c | 9 +++++---- sound/pci/oxygen/oxygen_pcm.c | 15 +-------------- 3 files changed, 10 insertions(+), 19 deletions(-)
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index b4ef580..2cca908 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -373,7 +373,7 @@ static void oxygen_init(struct oxygen *chip) for (i = 0; i < 8; ++i) chip->dac_volume[i] = chip->model.dac_volume_min; chip->dac_mute = 1; - chip->spdif_playback_enable = 1; + chip->spdif_playback_enable = 0; chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL | (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT); chip->spdif_pcm_bits = chip->spdif_bits; @@ -575,6 +575,9 @@ static void oxygen_shutdown(struct oxygen *chip) spin_lock_irq(&chip->reg_lock); chip->interrupt_mask = 0; chip->pcm_running = 0; + chip->spdif_playback_enable = 0; + oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, + OXYGEN_SPDIF_OUT_ENABLE); oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); spin_unlock_irq(&chip->reg_lock); diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 6492bca..20a2781 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -252,7 +252,6 @@ void oxygen_update_spdif_source(struct oxygen *chip) old_control = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL); old_routing = oxygen_read16(chip, OXYGEN_PLAY_ROUTING); if (chip->pcm_active & (1 << PCM_SPDIF)) { - new_control = old_control | OXYGEN_SPDIF_OUT_ENABLE; new_routing = (old_routing & ~OXYGEN_PLAY_SPDIF_MASK) | OXYGEN_PLAY_SPDIF_SPDIF; oxygen_rate = (old_control >> OXYGEN_SPDIF_OUT_RATE_SHIFT) @@ -265,13 +264,15 @@ void oxygen_update_spdif_source(struct oxygen *chip) oxygen_rate = oxygen_read16(chip, OXYGEN_I2S_MULTICH_FORMAT) & OXYGEN_I2S_RATE_MASK; new_control = (old_control & ~OXYGEN_SPDIF_OUT_RATE_MASK) | - (oxygen_rate << OXYGEN_SPDIF_OUT_RATE_SHIFT) | - OXYGEN_SPDIF_OUT_ENABLE; + (oxygen_rate << OXYGEN_SPDIF_OUT_RATE_SHIFT); } else { - new_control = old_control & ~OXYGEN_SPDIF_OUT_ENABLE; new_routing = old_routing; oxygen_rate = OXYGEN_RATE_44100; } + if (chip->spdif_playback_enable) + new_control = old_control | OXYGEN_SPDIF_OUT_ENABLE; + else + new_control = old_control & ~OXYGEN_SPDIF_OUT_ENABLE; if (old_routing != new_routing) { oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, new_control & ~OXYGEN_SPDIF_OUT_ENABLE); diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index aa2ebd1..f4a4a48 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -477,8 +477,6 @@ static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
mutex_lock(&chip->mutex); spin_lock_irq(&chip->reg_lock); - oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, - OXYGEN_SPDIF_OUT_ENABLE); oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT, oxygen_format(hw_params) << OXYGEN_SPDIF_FORMAT_SHIFT, OXYGEN_SPDIF_FORMAT_MASK); @@ -544,17 +542,6 @@ static int oxygen_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_pages(substream); }
-static int oxygen_spdif_hw_free(struct snd_pcm_substream *substream) -{ - struct oxygen *chip = snd_pcm_substream_chip(substream); - - spin_lock_irq(&chip->reg_lock); - oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, - OXYGEN_SPDIF_OUT_ENABLE); - spin_unlock_irq(&chip->reg_lock); - return oxygen_hw_free(substream); -} - static int oxygen_prepare(struct snd_pcm_substream *substream) { struct oxygen *chip = snd_pcm_substream_chip(substream); @@ -669,7 +656,7 @@ static struct snd_pcm_ops oxygen_spdif_ops = { .close = oxygen_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = oxygen_spdif_hw_params, - .hw_free = oxygen_spdif_hw_free, + .hw_free = oxygen_hw_free, .prepare = oxygen_prepare, .trigger = oxygen_trigger, .pointer = oxygen_pointer,