From fda16d2b24ca370d0162cfef0418eb503909574a Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Fri, 27 Oct 2023 18:53:56 +0530 Subject: [PATCH 1/4] ASoC: wcd937x: Add flag to decide RX_MUTE for HPHL and EAR Check if HPHL or EAR is enabled before sending RX_MUTE event. Change-Id: I4ffc42a0d79c8edea77745a2f52361a4cf3dddaa Signed-off-by: Soumya Managoli --- asoc/codecs/wcd937x/wcd937x.c | 48 +++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 69ee6c5f2f9a..7641146db392 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -49,6 +50,8 @@ enum { HPH_COMP_DELAY, HPH_PA_DELAY, AMIC2_BCS_ENABLE, + WCD_HPHL_EN, + WCD_EAR_EN, }; static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); @@ -834,6 +837,7 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, set_bit(HPH_PA_DELAY, &wcd937x->status_mask); snd_soc_component_update_bits(component, WCD937X_DIGITAL_PDM_WD_CTL0, 0x17, 0x13); + set_bit(WCD_HPHL_EN, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: /* @@ -864,12 +868,14 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD937X_IRQ_HPHL_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: - wcd_disable_irq(&wcd937x->irq_info, + if (!test_bit(WCD_EAR_EN, &wcd937x->status_mask)) { + wcd_disable_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHL_PDM_WD_INT); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10 | 0x1)); + } blocking_notifier_call_chain(&wcd937x->mbhc->notifier, WCD_EVENT_PRE_HPHL_PA_OFF, &wcd937x->mbhc->wcd_mbhc); @@ -900,6 +906,7 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHL, hph_mode); + clear_bit(WCD_HPHL_EN, &wcd937x->status_mask); break; }; return ret; @@ -988,10 +995,12 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_DIGITAL_PDM_WD_CTL2, 0x05, 0x05); - else + else { snd_soc_component_update_bits(component, WCD937X_DIGITAL_PDM_WD_CTL0, 0x17, 0x13); + set_bit(WCD_EAR_EN, &wcd937x->status_mask); + } if (!wcd937x->comp1_enable) snd_soc_component_update_bits(component, WCD937X_ANA_EAR_COMPANDER_CTL, 0x80, 0x80); @@ -1014,16 +1023,24 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, WCD937X_IRQ_HPHL_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: - if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX) + if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX) { wcd_disable_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT); - else - wcd_disable_irq(&wcd937x->irq_info, + if (wcd937x->update_wcd_event) + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x1)); + } + else { + if(!test_bit(WCD_HPHL_EN, &wcd937x->status_mask)) { + wcd_disable_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHL_PDM_WD_INT); - if (wcd937x->update_wcd_event) - wcd937x->update_wcd_event(wcd937x->handle, + if (wcd937x->update_wcd_event) + wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10 | 0x1)); + } + } break; case SND_SOC_DAPM_POST_PMD: if (!wcd937x->comp1_enable) @@ -1040,10 +1057,12 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_DIGITAL_PDM_WD_CTL2, 0x05, 0x00); - else + else { snd_soc_component_update_bits(component, WCD937X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00); + clear_bit(WCD_EAR_EN, &wcd937x->status_mask); + } usleep_range(10000, 10010); /* disable EAR CnP FSM */ snd_soc_component_update_bits(component, @@ -1109,13 +1128,16 @@ static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, wcd937x_rx_connect_port(component, COMP_L, true); break; case SND_SOC_DAPM_POST_PMD: - wcd937x_rx_connect_port(component, HPH_L, false); - if (wcd937x->comp1_enable) - wcd937x_rx_connect_port(component, COMP_L, false); - wcd937x_rx_clk_disable(component); - snd_soc_component_update_bits(component, + if (!test_bit(WCD_HPHL_EN, &wcd937x->status_mask) && + !test_bit(WCD_EAR_EN, &wcd937x->status_mask)) { + wcd937x_rx_connect_port(component, HPH_L, false); + if (wcd937x->comp1_enable) + wcd937x_rx_connect_port(component, COMP_L, false); + wcd937x_rx_clk_disable(component); + snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00); + } break; }; return 0; From e92c0dc8701fab2bc68400c7af73f1db99822acf Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Mon, 30 Oct 2023 16:40:06 +0530 Subject: [PATCH 2/4] ASoC: bolero: Add check for CMPDR switch Do not disable CMPDR for EAR if ear mode is on as it can lead to mute issues on ear. Change-Id: Ibf54fe6f14c5f08c2004fae36204398109ad53c1 Signed-off-by: Soumya Managoli --- asoc/codecs/bolero/rx-macro.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 9934a86525db..063a1b6f402d 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -2590,7 +2590,8 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_component *component, } if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_component_update_bits(component, + if (!rx_priv->is_ear_mode_on) + snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0x02, 0x00); snd_soc_component_update_bits(component, hph_lut_bypass_reg, From 3d5955a210ed0dd49e0a6434eda758b1230a1e4d Mon Sep 17 00:00:00 2001 From: Raza Kamal Date: Mon, 4 Dec 2023 15:33:09 +0530 Subject: [PATCH 3/4] Audio legacy: Integer overflow in msm_lsm_ioctl_compat during audio playback usecase. size = sizeof(p_info_32) + p_info_32.param_size; This overflow issue may result heap overflow during copying the data: memcpy(param_info_rsp, &p_info_32, sizeof(p_info_32)); The validation check is added so that heap overflow can be avoided. Change-Id: I11dcbe7ebb33e349dfd9f347f3ef25bc781075fc Signed-off-by: Raza Kamal --- asoc/msm-lsm-client.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index f4a8dbdce4fd..409edb3b1d5e 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -2167,8 +2167,13 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, prtd->lsm_client->get_param_payload = NULL; goto done; } + if (__builtin_uadd_overflow(sizeof(p_info_32), p_info_32.param_size, &size)) { + pr_err("%s: param size exceeds limit of %u bytes.\n", + __func__, UINT_MAX); + err = -EINVAL; + goto done; + } - size = sizeof(p_info_32) + p_info_32.param_size; param_info_rsp = kzalloc(size, GFP_KERNEL); if (!param_info_rsp) { From c03b28e4c823575a8d488014eda28165a83ca71a Mon Sep 17 00:00:00 2001 From: Raza Kamal Date: Mon, 4 Dec 2023 15:33:09 +0530 Subject: [PATCH 4/4] Audio legacy: Integer overflow in msm_lsm_ioctl_compat during audio playback usecase. size = sizeof(p_info_32) + p_info_32.param_size; This overflow issue may result heap overflow during copying the data: memcpy(param_info_rsp, &p_info_32, sizeof(p_info_32)); The validation check is added so that heap overflow can be avoided. Change-Id: I11dcbe7ebb33e349dfd9f347f3ef25bc781075fc Signed-off-by: Raza Kamal (cherry picked from commit 3d5955a210ed0dd49e0a6434eda758b1230a1e4d) --- asoc/msm-lsm-client.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index f4a8dbdce4fd..409edb3b1d5e 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -2167,8 +2167,13 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, prtd->lsm_client->get_param_payload = NULL; goto done; } + if (__builtin_uadd_overflow(sizeof(p_info_32), p_info_32.param_size, &size)) { + pr_err("%s: param size exceeds limit of %u bytes.\n", + __func__, UINT_MAX); + err = -EINVAL; + goto done; + } - size = sizeof(p_info_32) + p_info_32.param_size; param_info_rsp = kzalloc(size, GFP_KERNEL); if (!param_info_rsp) {