From: Vitaly Rodionov <vitalyr@opensource.cirrus.com> To: Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com> Cc: <alsa-devel@alsa-project.org>, <patches@opensource.cirrus.com>, <linux-kernel@vger.kernel.org>, Stefan Binding <sbinding@opensource.cirrus.com> Subject: [PATCH v2 27/27] ALSA: hda/cs8409: Unmute/Mute codec when stream starts/stops Date: Wed, 28 Jul 2021 14:44:08 +0100 [thread overview] Message-ID: <20210728134408.369396-28-vitalyr@opensource.cirrus.com> (raw) In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> From: Stefan Binding <sbinding@opensource.cirrus.com> Codec is muted on init, and then unmuted when the stream starts. Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com> Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com> Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 20 ++--- sound/pci/hda/patch_cs8409.c | 123 +++++++++++++++++++++++----- sound/pci/hda/patch_cs8409.h | 7 ++ 3 files changed, 120 insertions(+), 30 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index a9a0b8e3b2a9..0fb0a428428b 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -81,7 +81,7 @@ static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { { 0x1010, 0xB0 }, { 0x1D01, 0x00 }, { 0x1D02, 0x06 }, - { 0x1D03, 0x00 }, + { 0x1D03, 0x9F }, { 0x1107, 0x01 }, { 0x1009, 0x02 }, { 0x1007, 0x03 }, @@ -111,8 +111,8 @@ static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { { 0x2901, 0x01 }, { 0x1101, 0x0A }, { 0x1102, 0x84 }, - { 0x2301, 0x00 }, - { 0x2303, 0x00 }, + { 0x2301, 0x3F }, + { 0x2303, 0x3F }, { 0x2302, 0x3f }, { 0x2001, 0x03 }, { 0x1B75, 0xB6 }, @@ -284,7 +284,7 @@ static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = { { 0x1010, 0xB0 }, { 0x1D01, 0x00 }, { 0x1D02, 0x06 }, - { 0x1D03, 0x00 }, + { 0x1D03, 0x9F }, { 0x1107, 0x01 }, { 0x1009, 0x02 }, { 0x1007, 0x03 }, @@ -309,8 +309,8 @@ static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = { { 0x1101, 0x0A }, { 0x1102, 0x84 }, { 0x2001, 0x03 }, - { 0x2301, 0x00 }, - { 0x2303, 0x00 }, + { 0x2301, 0x3F }, + { 0x2303, 0x3F }, { 0x2302, 0x3f }, { 0x1B75, 0xB6 }, { 0x1B73, 0xC2 }, @@ -340,7 +340,7 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { { 0x1010, 0xB0 }, { 0x1D01, 0x00 }, { 0x1D02, 0x06 }, - { 0x1D03, 0x00 }, + { 0x1D03, 0x9F }, { 0x1107, 0x01 }, { 0x1009, 0x02 }, { 0x1007, 0x03 }, @@ -365,8 +365,8 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { { 0x1101, 0x0E }, { 0x1102, 0x84 }, { 0x2001, 0x01 }, - { 0x2301, 0x00 }, - { 0x2303, 0x00 }, + { 0x2301, 0x3F }, + { 0x2303, 0x3F }, { 0x2302, 0x3f }, { 0x1B75, 0xB6 }, { 0x1B73, 0xC2 }, @@ -377,7 +377,7 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { { 0x1112, 0x00 }, { 0x1113, 0x80 }, { 0x1C03, 0xC0 }, - { 0x1101, 0x02 }, + { 0x1101, 0x06 }, { 0x1316, 0xff }, { 0x1317, 0xff }, { 0x1318, 0xff }, diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 0baed8bebfbb..bd81004fc81e 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -454,6 +454,38 @@ int cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc return 0; } +static void cs42l42_mute(struct sub_codec *cs42l42, int vol_type, + unsigned int chs, bool mute) +{ + if (mute) { + if (vol_type == CS42L42_VOL_DAC) { + if (chs & BIT(0)) + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, 0x3f); + if (chs & BIT(1)) + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, 0x3f); + } else if (vol_type == CS42L42_VOL_ADC) { + if (chs & BIT(0)) + cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, 0x9f); + } + } else { + if (vol_type == CS42L42_VOL_DAC) { + if (chs & BIT(0)) + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, + -(cs42l42->vol[CS42L42_DAC_CH0_VOL_OFFSET]) + & CS42L42_REG_HS_VOL_MASK); + if (chs & BIT(1)) + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, + -(cs42l42->vol[CS42L42_DAC_CH1_VOL_OFFSET]) + & CS42L42_REG_HS_VOL_MASK); + } else if (vol_type == CS42L42_VOL_ADC) { + if (chs & BIT(0)) + cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, + cs42l42->vol[CS42L42_ADC_VOL_OFFSET] + & CS42L42_REG_AMIC_VOL_MASK); + } + } +} + int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) { struct hda_codec *codec = snd_kcontrol_chip(kctrl); @@ -465,25 +497,20 @@ int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc switch (ofs) { case CS42L42_VOL_DAC: - if (chs & BIT(0)) { + if (chs & BIT(0)) cs42l42->vol[ofs] = *valp; - cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, - -(cs42l42->vol[ofs]) & CS42L42_REG_HS_VOL_MASK); - } if (chs & BIT(1)) { - ofs++; valp++; - cs42l42->vol[ofs] = *valp; - cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, - -(cs42l42->vol[ofs]) & CS42L42_REG_HS_VOL_MASK); + cs42l42->vol[ofs + 1] = *valp; } + if (spec->playback_started) + cs42l42_mute(cs42l42, CS42L42_VOL_DAC, chs, false); break; case CS42L42_VOL_ADC: - if (chs & BIT(0)) { + if (chs & BIT(0)) cs42l42->vol[ofs] = *valp; - cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, - cs42l42->vol[ofs] & CS42L42_REG_AMIC_VOL_MASK); - } + if (spec->capture_started) + cs42l42_mute(cs42l42, CS42L42_VOL_ADC, chs, false); break; default: break; @@ -492,6 +519,64 @@ int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc return 0; } +static void cs42l42_playback_pcm_hook(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream, + int action) +{ + struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42; + int i; + bool mute; + + switch (action) { + case HDA_GEN_PCM_ACT_PREPARE: + mute = false; + spec->playback_started = 1; + break; + case HDA_GEN_PCM_ACT_CLEANUP: + mute = true; + spec->playback_started = 0; + break; + default: + return; + } + + for (i = 0; i < spec->num_scodecs; i++) { + cs42l42 = spec->scodecs[i]; + cs42l42_mute(cs42l42, CS42L42_VOL_DAC, 0x3, mute); + } +} + +static void cs42l42_capture_pcm_hook(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream, + int action) +{ + struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42; + int i; + bool mute; + + switch (action) { + case HDA_GEN_PCM_ACT_PREPARE: + mute = false; + spec->capture_started = 1; + break; + case HDA_GEN_PCM_ACT_CLEANUP: + mute = true; + spec->capture_started = 0; + break; + default: + return; + } + + for (i = 0; i < spec->num_scodecs; i++) { + cs42l42 = spec->scodecs[i]; + cs42l42_mute(cs42l42, CS42L42_VOL_ADC, 0x3, mute); + } +} + /* Configure CS42L42 slave codec for jack autodetect */ static void cs42l42_enable_jack_detect(struct sub_codec *cs42l42) { @@ -637,14 +722,6 @@ static void cs42l42_resume(struct sub_codec *cs42l42) /* Clear interrupts, by reading interrupt status registers */ cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs)); - /* Restore Volumes after Resume */ - cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, - -(cs42l42->vol[1]) & CS42L42_REG_HS_VOL_MASK); - cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, - -(cs42l42->vol[2]) & CS42L42_REG_HS_VOL_MASK); - cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, - cs42l42->vol[0] & CS42L42_REG_AMIC_VOL_MASK); - if (cs42l42->full_scale_vol) cs8409_i2c_write(cs42l42, 0x2001, 0x01); @@ -897,6 +974,9 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, /* Fix Sample Rate to 48kHz */ spec->gen.stream_analog_playback = &cs42l42_48k_pcm_analog_playback; spec->gen.stream_analog_capture = &cs42l42_48k_pcm_analog_capture; + /* add hooks */ + spec->gen.pcm_playback_hook = cs42l42_playback_pcm_hook; + spec->gen.pcm_capture_hook = cs42l42_capture_pcm_hook; /* Set initial DMIC volume to -26 dB */ snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, HDA_INPUT, 0, 0xff, 0x19); @@ -1092,6 +1172,9 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac /* Fix Sample Rate to 48kHz */ spec->gen.stream_analog_playback = &cs42l42_48k_pcm_analog_playback; spec->gen.stream_analog_capture = &cs42l42_48k_pcm_analog_capture; + /* add hooks */ + spec->gen.pcm_playback_hook = cs42l42_playback_pcm_hook; + spec->gen.pcm_capture_hook = cs42l42_capture_pcm_hook; snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume", &cs42l42_dac_volume_mixer); snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume", &cs42l42_adc_volume_mixer); diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 09987daa9cbf..207315ad5bf6 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -280,6 +280,10 @@ enum { CS42L42_VOL_DAC, }; +#define CS42L42_ADC_VOL_OFFSET (CS42L42_VOL_ADC) +#define CS42L42_DAC_CH0_VOL_OFFSET (CS42L42_VOL_DAC) +#define CS42L42_DAC_CH1_VOL_OFFSET (CS42L42_VOL_DAC + 1) + struct cs8409_i2c_param { unsigned int addr; unsigned int value; @@ -327,6 +331,9 @@ struct cs8409_spec { unsigned int dev_addr; struct delayed_work i2c_clk_work; + unsigned int playback_started:1; + unsigned int capture_started:1; + /* verb exec op override */ int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, unsigned int flags, unsigned int *res); -- 2.25.1
prev parent reply other threads:[~2021-07-28 13:47 UTC|newest] Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-07-28 13:43 [PATCH v2 00/27] ALSA: hda/cirrus: Split generic cirrus HDA codecs and CS8490 bridge into separate modules Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 01/27] ALSA: hda/cirrus: Move CS8409 HDA bridge to separate module Vitaly Rodionov 2021-07-29 9:50 ` Takashi Iwai 2021-07-28 13:43 ` [PATCH v2 02/27] ALSA: hda/cs8409: Move arrays of configuration to a new file Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 03/27] ALSA: hda/cs8409: Use enums for register names and coefficients Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 04/27] ALSA: hda/cs8409: Mask all CS42L42 interrupts on initialization Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 05/27] ALSA: hda/cs8409: Reduce HS pops/clicks for Cyborg Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 06/27] ALSA: hda/cs8409: Disable unnecessary Ring Sense for Cyborg/Warlock/Bullseye Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 07/27] ALSA: hda/cs8409: Disable unsolicited responses during suspend Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 08/27] ALSA: hda/cs8409: Disable unsolicited response for the first boot Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 09/27] ALSA: hda/cs8409: Mask CS42L42 wake events Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 10/27] ALSA: hda/cs8409: Simplify CS42L42 jack detect Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 11/27] ALSA: hda/cs8409: Prevent I2C access during suspend time Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 12/27] ALSA: hda/cs8409: Generalize volume controls Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 13/27] ALSA: hda/cs8409: Dont disable I2C clock between consecutive accesses Vitaly Rodionov 2021-07-29 9:48 ` Takashi Iwai 2021-07-28 13:43 ` [PATCH v2 14/27] ALSA: hda/cs8409: Avoid setting the same I2C address for every access Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 15/27] ALSA: hda/cs8409: Avoid re-setting the same page as the last access Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 16/27] ALSA: hda/cs8409: Support i2c bulk read/write functions Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 17/27] ALSA: hda/cs8409: Separate CS8409, CS42L42 and project functions Vitaly Rodionov 2021-07-28 13:43 ` [PATCH v2 18/27] ALSA: hda/cs8409: Move codec properties to its own struct Vitaly Rodionov 2021-07-28 13:44 ` [PATCH v2 19/27] ALSA: hda/cs8409: Support multiple sub_codecs for Suspend/Resume/Unsol events Vitaly Rodionov 2021-07-28 13:44 ` [PATCH v2 20/27] ALSA: hda/cs8409: Add Support to disable jack type detection for CS42L42 Vitaly Rodionov 2021-07-28 13:44 ` [PATCH v2 21/27] ALSA: hda/cs8409: Add support for dolphin Vitaly Rodionov 2021-07-28 13:44 ` [PATCH v2 22/27] ALSA: hda/cs8409: Enable Full Scale Volume for Line Out Codec on Dolphin Vitaly Rodionov 2021-07-28 13:44 ` [PATCH v2 23/27] ALSA: hda/cs8409: Set fixed sample rate of 48kHz for CS42L42 Vitaly Rodionov 2021-07-28 13:44 ` [PATCH v2 24/27] ALSA: hda/cs8409: Use timeout rather than retries for I2C transaction waits Vitaly Rodionov 2021-07-28 13:44 ` [PATCH v2 25/27] ALSA: hda/cs8409: Remove unnecessary delays Vitaly Rodionov 2021-07-28 13:44 ` [PATCH v2 26/27] ALSA: hda/cs8409: Follow correct CS42L42 power down sequence for suspend Vitaly Rodionov 2021-07-28 13:44 ` Vitaly Rodionov [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210728134408.369396-28-vitalyr@opensource.cirrus.com \ --to=vitalyr@opensource.cirrus.com \ --cc=alsa-devel@alsa-project.org \ --cc=linux-kernel@vger.kernel.org \ --cc=patches@opensource.cirrus.com \ --cc=perex@perex.cz \ --cc=sbinding@opensource.cirrus.com \ --cc=tiwai@suse.com \ --subject='Re: [PATCH v2 27/27] ALSA: hda/cs8409: Unmute/Mute codec when stream starts/stops' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).