From nobody Tue Dec 2 01:04:47 2025 Received: from mail-qk1-f182.google.com (mail-qk1-f182.google.com [209.85.222.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 725732E1EE7 for ; Mon, 24 Nov 2025 06:50:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763967041; cv=none; b=Kv5iWQeYdDUmVOV+0EFrnPmleRpStueQU+9UL5MI2+1Xb27ZmTa4sr2GoxNJwPRlStio0qID3Xru10GpYiLSg2Xpfa8vN38Fbt7a50A+EMmXlAcLqqhixBOqH/MfsdqR5Bl1a2ymASNAEkCMn7Lqc/rN5zDBw3kBRDbQJufgk7c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763967041; c=relaxed/simple; bh=ODKZZ6llYfgYgWR/6DbA7mxg/k8lgmUIfV1DzxX9fS4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s3DoiDgnt7erhBHC8dObVp/2Pa1WYxExdJJ9ALxTXqPR4fUm5yXZx6s2viVEsqObFfInkiaWHJYtW6JLfhl8u5GrxISxJnY233L3yYLPKzbugrM1IrdotjrDMR9T+IvVTseV9Z5Q5p1ewiP1RmmmtJMGp8xCQpuAExCVeTTMGsg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=marek.ca; spf=pass smtp.mailfrom=marek.ca; dkim=pass (2048-bit key) header.d=marek.ca header.i=@marek.ca header.b=DXeIr3C4; arc=none smtp.client-ip=209.85.222.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=marek.ca Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marek.ca Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marek.ca header.i=@marek.ca header.b="DXeIr3C4" Received: by mail-qk1-f182.google.com with SMTP id af79cd13be357-8b28f983333so399751685a.3 for ; Sun, 23 Nov 2025 22:50:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marek.ca; s=google; t=1763967038; x=1764571838; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vyGmcBay0+DkW1QEBakkTS1fQ2rSDF+O9yJM76nIi/s=; b=DXeIr3C4hVT3OH7+yuu6U5c9isGid6hXkwBply/Kf2nmbxDAnFtxaw/uT6Lo6wFSgB iCafZOw6fUR9U8Yc4HXk//qNZQMrqlQ6Uzdh8ZR73HBvfh3bOybfoBg2js2k7ty4NIxR T7142pqDRCjVmRqI4byZyKekR4yeBJ/MuxSh5tM/mDG4RBt26jwTizYGys0BdydRg3Jc o2pL5PpeKQMGhtnXoSelZtqq7oe4P1IhREetWqgWErOwAzxVoDshuV3HQxFSstuzXub9 U/CW2Arz3KIRCfs8xEH52b9kE5l00Gu9xcYutgmnB1ZBWp9BzZNFDvfb4l5VEC0oPh5O kblQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763967038; x=1764571838; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=vyGmcBay0+DkW1QEBakkTS1fQ2rSDF+O9yJM76nIi/s=; b=RXFW//4BxWGqmwNtG5XBxDZbBsjQUxUQrxAmMOgUo/f1JlX9YlhpIkvznb6P95zZ2j sY4TEyGTdshUwI0PPIZWzQWV5KX7ZNkVCTy4v9QsZfR4sDS7KMfjOkEhfkyggQxkXO4s MzF6JQ0VjUTAZ6cc0DucTQRUTm7YzptmUiopL20WIVXZbyj2lT+8D5GkKPOm0D3gD2tQ aImjxuYZSez/XWwcUQhtKoI7f8fds6v05IAPGBUhytDdIvKFzgU6iG83sCL/rgBYYGBH iveaRX+GDykLNkpoX0RjpAXObqMvuIwje5h90BvoaR5Or+zCBhLs3m3bY2NOPBspc8jp iJVA== X-Forwarded-Encrypted: i=1; AJvYcCWGRoTM2VA8xS37oLnXozOemCyYM+tWoPMDFemheuDNV1SvlUoZ0ewR26xZwi6bGCFUpz22zZ7J7Y6HYn0=@vger.kernel.org X-Gm-Message-State: AOJu0Yxp2xiEt8HG3RgPZovI00OjOAt8X58ZFW5YjGaXd0TQ+xZYxkdo 5k0RO7YGUwEfx2xPFzAOqMIcJXKdM0iN/niU+/OcbHC0S8GOHng1odzXgTHPzZ134Zg= X-Gm-Gg: ASbGncuW7RtKXpAmGZufjfVY3t1I7pmRz4KUDj8ig6/MhWP2y1QapoChSdybA/+1Mlg HmTDptgQ9ELxZuqBHkK8bWo6mQ7kM7uk9FYx0dAyUOwrM8OIDbgi/crduf1Z+AUdrbwLP1/0lpZ br1bY0Lxx5gKrzmifJjgYYnnpXtBTuII706e4QZ/oumu8XUPBRQ0XY7QsEM62KS6HDUkegl/KHt UdBpB/vsPI1w7X18dFtyUJVWMU9XTX2S5H9T2b+ZNv4P1Z3vPDIpItlm1g95JiyI3IN+0wmlDRn WYkNKhuzvc95ZOFJN5d1PoYqV/ULX5ZR6cKfcJEozbG+hb9f+iYcnXBu+Nk0Maa+gW6fzA8eFX1 PvDYyNaKyuiGqQldlWkenTi14RBJz1ktmD1Kt2w0jUnCFuHdd5mne2bst3dReITByosQF6Ud6AE ttSvTM+5RXNGx8n1RFGgyrm9zIBi4AbJJ4xv1JHNnp/EqYJPKrzjtqGRP0dk9ZpgMQlA== X-Google-Smtp-Source: AGHT+IEGinri7FfzNXmmlyC2Q7pb+oH0NVL9SOp/e15LApRFrCRvqXP61oERVCDhDxN1m/8j+Rq6/g== X-Received: by 2002:a05:620a:c44:b0:849:d117:e86a with SMTP id af79cd13be357-8b33d4734d4mr1291646985a.59.1763967038248; Sun, 23 Nov 2025 22:50:38 -0800 (PST) Received: from localhost.localdomain (modemcable125.110-19-135.mc.videotron.ca. [135.19.110.125]) by smtp.gmail.com with ESMTPSA id af79cd13be357-8b3295db8b1sm889075185a.40.2025.11.23.22.50.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Nov 2025 22:50:37 -0800 (PST) From: Jonathan Marek To: linux-arm-msm@vger.kernel.org Cc: Srinivas Kandagatla , Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai , linux-sound@vger.kernel.org (open list:QCOM AUDIO (ASoC) DRIVERS), linux-kernel@vger.kernel.org (open list) Subject: [PATCH 3/6] ASoC: codecs: wcd939x: fix headphone pop/click sound Date: Mon, 24 Nov 2025 01:45:56 -0500 Message-ID: <20251124064850.15419-4-jonathan@marek.ca> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251124064850.15419-1-jonathan@marek.ca> References: <20251124064850.15419-1-jonathan@marek.ca> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" PA enable must happen while the soundwire stream is enabled (between sdw_enable_stream and sdw_disable_stream) to avoid issues. This is between the link prepare and hw_free for qcom drivers. Move the PA enable/disable to a mute_stream callback, which satisfies this condition. Note the dapm events already cleared HPHL_ENABLE/etc. bits, so only writes to set them need to be added. I used the DAC events to determine if PA should be enabled, which is not exactly the same as before, but practically it shouldn't make a difference. Signed-off-by: Jonathan Marek --- sound/soc/codecs/wcd939x.c | 84 ++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/sound/soc/codecs/wcd939x.c b/sound/soc/codecs/wcd939x.c index e74e6f0131318..48f82a92722dd 100644 --- a/sound/soc/codecs/wcd939x.c +++ b/sound/soc/codecs/wcd939x.c @@ -209,6 +209,8 @@ struct wcd939x_priv { bool comp1_enable; bool comp2_enable; bool ldoh; + bool hphl_enable; + bool hphr_enable; }; =20 static const char * const wcd939x_supplies[] =3D { @@ -508,6 +510,7 @@ static int wcd939x_codec_hphl_dac_event(struct snd_soc_= dapm_widget *w, =20 switch (event) { case SND_SOC_DAPM_PRE_PMU: + wcd939x->hphl_enable =3D true; snd_soc_component_write_field(component, WCD939X_HPH_RDAC_CLK_CTL1, WCD939X_RDAC_CLK_CTL1_OPAMP_CHOP_CLK_EN, false); @@ -547,6 +550,7 @@ static int wcd939x_codec_hphl_dac_event(struct snd_soc_= dapm_widget *w, WCD939X_RDAC_HD2_CTL_L_HD2_RES_DIV_CTL_L, 1); snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_HPH_GAIN_CT= L, WCD939X_CDC_HPH_GAIN_CTL_HPHL_RX_EN, false); + wcd939x->hphl_enable =3D false; break; } =20 @@ -565,6 +569,7 @@ static int wcd939x_codec_hphr_dac_event(struct snd_soc_= dapm_widget *w, =20 switch (event) { case SND_SOC_DAPM_PRE_PMU: + wcd939x->hphr_enable =3D true; snd_soc_component_write_field(component, WCD939X_HPH_RDAC_CLK_CTL1, WCD939X_RDAC_CLK_CTL1_OPAMP_CHOP_CLK_EN, false); @@ -603,6 +608,7 @@ static int wcd939x_codec_hphr_dac_event(struct snd_soc_= dapm_widget *w, WCD939X_RDAC_HD2_CTL_R_HD2_RES_DIV_CTL_R, 1); snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_HPH_GAIN_CT= L, WCD939X_CDC_HPH_GAIN_CTL_HPHR_RX_EN, false); + wcd939x->hphr_enable =3D false; break; } =20 @@ -641,16 +647,12 @@ static int wcd939x_codec_ear_dac_event(struct snd_soc= _dapm_widget *w, return 0; } =20 -static int wcd939x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) +static void wcd939x_codec_enable_hphr_pa(struct snd_soc_component *compone= nt, int enable) { - struct snd_soc_component *component =3D snd_soc_dapm_to_component(w->dapm= ); struct wcd939x_priv *wcd939x =3D snd_soc_component_get_drvdata(component); int hph_mode =3D wcd939x->hph_mode; =20 - switch (event) { - case SND_SOC_DAPM_PRE_PMU: + if (enable) { if (wcd939x->ldoh) snd_soc_component_write_field(component, WCD939X_LDOH_MODE, WCD939X_MODE_LDOH_EN, true); @@ -679,8 +681,7 @@ static int wcd939x_codec_enable_hphr_pa(struct snd_soc_= dapm_widget *w, set_bit(HPH_PA_DELAY, &wcd939x->status_mask); snd_soc_component_write_field(component, WCD939X_DIGITAL_PDM_WD_CTL1, WCD939X_PDM_WD_CTL1_PDM_WD_EN, 3); - break; - case SND_SOC_DAPM_POST_PMU: + /* * 7ms sleep is required if compander is enabled as per * HW requirement. If compander is disabled, then @@ -708,9 +709,11 @@ static int wcd939x_codec_enable_hphr_pa(struct snd_soc= _dapm_widget *w, WCD939X_RX_SUPPLIES_REGULATOR_MODE, true); =20 + snd_soc_component_write_field(component, WCD939X_ANA_HPH, + WCD939X_HPH_HPHR_ENABLE, true); + enable_irq(wcd939x->hphr_pdm_wd_int); - break; - case SND_SOC_DAPM_PRE_PMD: + } else { disable_irq_nosync(wcd939x->hphr_pdm_wd_int); /* * 7ms sleep is required if compander is enabled as per @@ -728,8 +731,7 @@ static int wcd939x_codec_enable_hphr_pa(struct snd_soc_= dapm_widget *w, wcd_mbhc_event_notify(wcd939x->wcd_mbhc, WCD_EVENT_PRE_HPHR_PA_OFF); set_bit(HPH_PA_DELAY, &wcd939x->status_mask); - break; - case SND_SOC_DAPM_POST_PMD: + /* * 7ms sleep is required if compander is enabled as per * HW requirement. If compander is disabled, then @@ -755,25 +757,15 @@ static int wcd939x_codec_enable_hphr_pa(struct snd_so= c_dapm_widget *w, if (wcd939x->ldoh) snd_soc_component_write_field(component, WCD939X_LDOH_MODE, WCD939X_MODE_LDOH_EN, false); - break; } - - return 0; } =20 -static int wcd939x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) +static void wcd939x_codec_enable_hphl_pa(struct snd_soc_component *compone= nt, bool enable) { - struct snd_soc_component *component =3D snd_soc_dapm_to_component(w->dapm= ); struct wcd939x_priv *wcd939x =3D snd_soc_component_get_drvdata(component); int hph_mode =3D wcd939x->hph_mode; =20 - dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, - w->name, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: + if (enable) { if (wcd939x->ldoh) snd_soc_component_write_field(component, WCD939X_LDOH_MODE, WCD939X_MODE_LDOH_EN, true); @@ -802,8 +794,7 @@ static int wcd939x_codec_enable_hphl_pa(struct snd_soc_= dapm_widget *w, set_bit(HPH_PA_DELAY, &wcd939x->status_mask); snd_soc_component_write_field(component, WCD939X_DIGITAL_PDM_WD_CTL0, WCD939X_PDM_WD_CTL0_PDM_WD_EN, 3); - break; - case SND_SOC_DAPM_POST_PMU: + /* * 7ms sleep is required if compander is enabled as per * HW requirement. If compander is disabled, then @@ -829,9 +820,12 @@ static int wcd939x_codec_enable_hphl_pa(struct snd_soc= _dapm_widget *w, snd_soc_component_write_field(component, WCD939X_ANA_RX_SUPPLIES, WCD939X_RX_SUPPLIES_REGULATOR_MODE, true); + + snd_soc_component_write_field(component, WCD939X_ANA_HPH, + WCD939X_HPH_HPHL_ENABLE, true); + enable_irq(wcd939x->hphl_pdm_wd_int); - break; - case SND_SOC_DAPM_PRE_PMD: + } else { disable_irq_nosync(wcd939x->hphl_pdm_wd_int); /* * 7ms sleep is required if compander is enabled as per @@ -848,8 +842,7 @@ static int wcd939x_codec_enable_hphl_pa(struct snd_soc_= dapm_widget *w, =20 wcd_mbhc_event_notify(wcd939x->wcd_mbhc, WCD_EVENT_PRE_HPHL_PA_OFF); set_bit(HPH_PA_DELAY, &wcd939x->status_mask); - break; - case SND_SOC_DAPM_POST_PMD: + /* * 7ms sleep is required if compander is enabled as per * HW requirement. If compander is disabled, then @@ -873,10 +866,7 @@ static int wcd939x_codec_enable_hphl_pa(struct snd_soc= _dapm_widget *w, if (wcd939x->ldoh) snd_soc_component_write_field(component, WCD939X_LDOH_MODE, WCD939X_MODE_LDOH_EN, false); - break; } - - return 0; } =20 static int wcd939x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, @@ -2736,14 +2726,6 @@ static const struct snd_soc_dapm_widget wcd939x_dapm= _widgets[] =3D { wcd939x_codec_enable_ear_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("HPHL PGA", WCD939X_ANA_HPH, 7, 0, NULL, 0, - wcd939x_codec_enable_hphl_pa, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("HPHR PGA", WCD939X_ANA_HPH, 6, 0, NULL, 0, - wcd939x_codec_enable_hphr_pa, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), =20 SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0, wcd939x_codec_hphl_dac_event, @@ -2858,8 +2840,7 @@ static const struct snd_soc_dapm_route wcd939x_audio_= map[] =3D { {"RX1", NULL, "RXCLK"}, {"RDAC1", NULL, "RX1"}, {"HPHL_RDAC", "Switch", "RDAC1"}, - {"HPHL PGA", NULL, "HPHL_RDAC"}, - {"HPHL", NULL, "HPHL PGA"}, + {"HPHL", NULL, "HPHL_RDAC"}, =20 {"IN2_HPHR", NULL, "VDD_BUCK"}, {"IN2_HPHR", NULL, "CLS_H_PORT"}, @@ -2867,8 +2848,7 @@ static const struct snd_soc_dapm_route wcd939x_audio_= map[] =3D { {"RDAC2", NULL, "RX2"}, {"RX2", NULL, "RXCLK"}, {"HPHR_RDAC", "Switch", "RDAC2"}, - {"HPHR PGA", NULL, "HPHR_RDAC"}, - {"HPHR", NULL, "HPHR PGA"}, + {"HPHR", NULL, "HPHR_RDAC"}, =20 {"IN3_EAR", NULL, "VDD_BUCK"}, {"RX3", NULL, "IN3_EAR"}, @@ -3258,6 +3238,19 @@ static int wcd939x_codec_free(struct snd_pcm_substre= am *substream, return wcd939x_sdw_free(wcd, substream, dai); } =20 +static int wcd939x_codec_mute_stream(struct snd_soc_dai *dai, int mute, in= t stream) +{ + struct wcd939x_priv *wcd939x =3D dev_get_drvdata(dai->dev); + struct snd_soc_component *component =3D dai->component; + + if (wcd939x->hphl_enable) + wcd939x_codec_enable_hphl_pa(component, !mute); + if (wcd939x->hphr_enable) + wcd939x_codec_enable_hphr_pa(component, !mute); + + return 0; +} + static int wcd939x_codec_set_sdw_stream(struct snd_soc_dai *dai, void *stream, int direction) { @@ -3270,6 +3263,7 @@ static int wcd939x_codec_set_sdw_stream(struct snd_so= c_dai *dai, static const struct snd_soc_dai_ops wcd939x_sdw_dai_ops =3D { .hw_params =3D wcd939x_codec_hw_params, .hw_free =3D wcd939x_codec_free, + .mute_stream =3D wcd939x_codec_mute_stream, .set_stream =3D wcd939x_codec_set_sdw_stream, }; =20 --=20 2.51.0