[alsa-devel] [PATCH] ALSA: oxygen: Fix S/PDIF muting
Laurence Darby
ldarby at tuffmail.com
Sun Jun 28 14:13:37 CEST 2015
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 at 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,
--
2.3.5
More information about the Alsa-devel
mailing list