From 6e38fad1181aa9e8212740cd55ea5ac64873ff23 Mon Sep 17 00:00:00 2001 From: Sairam Peri Date: Mon, 28 Aug 2023 00:05:48 +0530 Subject: [PATCH] asoc: codecs: update max sampling rate of wsa881x analog driver Updated the wsa dailink to support 384Khz HS playback. Picked latest codec fixes to kernel6.0. Change-Id: Ia570dc3f3ed55415ac374e1ba3bb6f2277dade96 Signed-off-by: Sairam Peri --- asoc/codecs/bolero/bolero-cdc.c | 60 ++++++- asoc/codecs/bolero/bolero-cdc.h | 9 + asoc/codecs/bolero/rx-macro.c | 18 +- asoc/codecs/bolero/tx-macro.c | 250 +++++++++++++++++++++++++-- asoc/codecs/bolero/va-macro.c | 42 +++-- asoc/codecs/wcd937x/internal.h | 3 + asoc/codecs/wcd937x/wcd937x.c | 125 ++++++++++++-- asoc/codecs/wsa881x-analog.c | 4 +- asoc/holi.c | 9 + include/asoc/bolero-slave-internal.h | 2 + 10 files changed, 463 insertions(+), 59 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 215fcc0690..b3a19b4f7e 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -21,6 +21,7 @@ #include "internal.h" #include "bolero-clk-rsc.h" #include "asoc/bolero-slave-internal.h" +#include #define DRV_NAME "bolero_codec" @@ -236,8 +237,9 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data) BOLERO_MACRO_EVT_BCS_CLK_OFF, data); break; case SLV_BOLERO_EVT_RX_PA_GAIN_UPDATE: - /* Update PA Gain only for bolero version 2.1 */ - if (priv->version == BOLERO_VERSION_2_1) + /* Update PA Gain for bolero version 2.1 and 2.2*/ + if ((priv->version == BOLERO_VERSION_2_1) || + (priv->version == BOLERO_VERSION_2_2)) if (priv->macro_params[RX_MACRO].event_handler) priv->macro_params[RX_MACRO].event_handler( priv->component, @@ -698,7 +700,8 @@ int bolero_register_macro(struct device *dev, u16 macro_id, if (macro_id == TX_MACRO || macro_id == VA_MACRO) priv->macro_params[macro_id].clk_div_get = ops->clk_div_get; - if (priv->version == BOLERO_VERSION_2_1) { + if ((priv->version == BOLERO_VERSION_2_1) || + (priv->version == BOLERO_VERSION_2_2)) { if (macro_id == VA_MACRO) priv->macro_params[macro_id].reg_wake_irq = ops->reg_wake_irq; @@ -781,6 +784,34 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) } EXPORT_SYMBOL(bolero_unregister_macro); +/** + * bolero_rx_pa_on - Send PA on event from RX macro to slave. + * + * @dev: macro device ptr. + */ +void bolero_rx_pa_on(struct device *dev) +{ + struct bolero_priv *priv; + + if (!dev) { + pr_err("%s: dev is null\n", __func__); + return; + } + if (!bolero_is_valid_child_dev(dev)) { + dev_err(dev, "%s: not a valid child dev\n", + __func__); + return; + } + priv = dev_get_drvdata(dev->parent); + if (!priv) { + dev_err(dev, "%s: priv is null\n", __func__); + return; + } + + bolero_cdc_notifier_call(priv, BOLERO_SLV_EVT_RX_MACRO_PA_ON); +} +EXPORT_SYMBOL_GPL(bolero_rx_pa_on); + void bolero_wsa_pa_on(struct device *dev, bool adie_lb) { struct bolero_priv *priv; @@ -1055,7 +1086,8 @@ int bolero_register_wake_irq(struct snd_soc_component *component, return -EINVAL; } - if (priv->version == BOLERO_VERSION_2_1) { + if ((priv->version == BOLERO_VERSION_2_1) || + (priv->version == BOLERO_VERSION_2_2)) { if (priv->macro_params[VA_MACRO].reg_wake_irq) priv->macro_params[VA_MACRO].reg_wake_irq( component, ipc_wakeup); @@ -1176,7 +1208,7 @@ static int bolero_soc_codec_probe(struct snd_soc_component *component) { struct bolero_priv *priv = dev_get_drvdata(component->dev); int macro_idx, ret = 0; - u8 core_id_0 = 0, core_id_1 = 0; + u8 core_id_0 = 0, core_id_1 = 0, core_id_2 = 0; snd_soc_component_init_regmap(component, priv->regmap); @@ -1201,10 +1233,16 @@ static int bolero_soc_codec_probe(struct snd_soc_component *component) BOLERO_CDC_VA_TOP_CSR_CORE_ID_0); core_id_1 = snd_soc_component_read(component, BOLERO_CDC_VA_TOP_CSR_CORE_ID_1); + core_id_2 = snd_soc_component_read(component, + BOLERO_CDC_VA_TOP_CSR_CORE_ID_2); if ((core_id_0 == 0x01) && (core_id_1 == 0x0F)) priv->version = BOLERO_VERSION_2_0; - if ((core_id_0 == 0x02) && (core_id_1 == 0x0E)) - priv->version = BOLERO_VERSION_2_1; + if ((core_id_0 == 0x02) && (core_id_1 == 0x0E)) { + if (core_id_2 == 0x20) + priv->version = BOLERO_VERSION_2_2; + else + priv->version = BOLERO_VERSION_2_1; + } /* call init for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { @@ -1368,7 +1406,8 @@ static int bolero_probe(struct platform_device *pdev) __func__); ret = 0; } - if (priv->version == BOLERO_VERSION_2_1) { + if ((priv->version == BOLERO_VERSION_2_1) || + (priv->version == BOLERO_VERSION_2_2)) { bolero_reg_access[TX_MACRO] = bolero_tx_reg_access_v2; bolero_reg_access[VA_MACRO] = bolero_va_reg_access_v2; } else if (priv->version == BOLERO_VERSION_2_0) { @@ -1385,6 +1424,9 @@ static int bolero_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s:regmap init failed\n", __func__); return -EINVAL; } + + devm_regmap_qti_debugfs_register(priv->dev, priv->regmap); + priv->read_dev = __bolero_reg_read; priv->write_dev = __bolero_reg_write; diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 19b0c89d92..b8196f9407 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef BOLERO_CDC_H @@ -13,6 +14,7 @@ #define BOLERO_VERSION_1_2 0x0003 #define BOLERO_VERSION_2_0 0x0004 #define BOLERO_VERSION_2_1 0x0005 +#define BOLERO_VERSION_2_2 0x0006 enum { START_MACRO, @@ -115,6 +117,7 @@ int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable); int bolero_get_version(struct device *dev); int bolero_dmic_clk_enable(struct snd_soc_component *component, u32 dmic, u32 tx_mode, bool enable); +void bolero_rx_pa_on(struct device *dev); #else static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) { @@ -215,5 +218,11 @@ static int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable) { return 0; } + +static inline void bolero_rx_pa_on(struct device *dev) +{ + return 0; +} + #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 6d6ec55212..a8d8e29af0 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1,5 +1,6 @@ // 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 @@ -462,6 +463,7 @@ struct rx_macro_priv { u16 default_clk_id; int8_t rx0_gain_val; int8_t rx1_gain_val; + u32 rx_macro_wsa_slv; }; static struct snd_soc_dai_driver rx_macro_dai[]; @@ -1249,7 +1251,11 @@ static int rx_macro_mute_stream(struct snd_soc_dai *dai, int mute, int stream) } } } - break; + + if (rx_priv->rx_macro_wsa_slv) + bolero_rx_pa_on(rx_dev); + break; + default: break; } @@ -4112,7 +4118,7 @@ static int rx_macro_probe(struct platform_device *pdev) struct rx_macro_priv *rx_priv = NULL; u32 rx_base_addr = 0, muxsel = 0; char __iomem *rx_io_base = NULL, *muxsel_io = NULL; - int ret = 0; + int ret = 0, val = 0; u8 bcl_pmic_params[3]; u32 default_clk_id = 0; u32 is_used_rx_swr_gpio = 1; @@ -4144,6 +4150,14 @@ static int rx_macro_probe(struct platform_device *pdev) __func__, "reg"); return ret; } + + ret = of_property_read_u32(pdev->dev.of_node, "qcom,rx-wsa-enable", &val); + if (ret == 0) { + rx_priv->rx_macro_wsa_slv = (val == 1) ? 1 : 0; + dev_info(&pdev->dev, "RX macro wsa slave is %s\n", + (val == 1) ? "connected" : "not connected"); + } + ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id", &default_clk_id); if (ret) { diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 6dc5e519c4..120b429bcb 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1,5 +1,6 @@ // 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 @@ -690,6 +691,92 @@ static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); } +static int tx_macro_put_dec_enum_v2(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val = 0; + u16 mic_sel_reg = 0; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + val = ucontrol->value.enumerated.item[0]; + if (val > e->items - 1) + return -EINVAL; + + dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + switch (e->reg) { + case BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0: + mic_sel_reg = BOLERO_CDC_TX0_TX_PATH_CFG0; + break; + case BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0: + mic_sel_reg = BOLERO_CDC_TX1_TX_PATH_CFG0; + break; + case BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0: + mic_sel_reg = BOLERO_CDC_TX2_TX_PATH_CFG0; + break; + case BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0: + mic_sel_reg = BOLERO_CDC_TX3_TX_PATH_CFG0; + break; + default: + dev_err(component->dev, "%s: e->reg: 0x%x not expected\n", + __func__, e->reg); + return -EINVAL; + } + + if (strnstr(widget->name, "SMIC", strlen(widget->name))) { + if (val != 0) { + snd_soc_component_update_bits(component, + mic_sel_reg, + 1 << 7, 0x0 << 7); + } + } else { + /* DMIC selected */ + if (val != 0) + snd_soc_component_update_bits(component, mic_sel_reg, + 1 << 7, 1 << 7); + } + + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static int tx_macro_put_pcm_in_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val = 0; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + val = ucontrol->value.enumerated.item[0]; + if (val > e->items - 1) + return -EINVAL; + + dev_dbg(component->dev, "%s: wname: %s\n", __func__, widget->name); + + snd_soc_component_update_bits(component, + BOLERO_CDC_TX_TOP_CSR_I2S_CLK, + 0x1, val); + + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -947,7 +1034,8 @@ static int tx_macro_get_bcs_ch_sel(struct snd_kcontrol *kcontrol, if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; - if (tx_priv->version == BOLERO_VERSION_2_1) + if ((tx_priv->version == BOLERO_VERSION_2_1) || + (tx_priv->version == BOLERO_VERSION_2_2)) value = (snd_soc_component_read(component, BOLERO_CDC_VA_TOP_CSR_SWR_CTRL)) & 0x0F; else if (tx_priv->version == BOLERO_VERSION_2_0) @@ -975,7 +1063,8 @@ static int tx_macro_put_bcs_ch_sel(struct snd_kcontrol *kcontrol, return -EINVAL; value = ucontrol->value.integer.value[0]; - if (tx_priv->version == BOLERO_VERSION_2_1) + if ((tx_priv->version == BOLERO_VERSION_2_1) || + (tx_priv->version == BOLERO_VERSION_2_2)) snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F, value); else if (tx_priv->version == BOLERO_VERSION_2_0) @@ -1128,7 +1217,8 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_component_read(component, tx_gain_ctl_reg)); if (tx_priv->bcs_enable) { - if (tx_priv->version == BOLERO_VERSION_2_1) + if ((tx_priv->version == BOLERO_VERSION_2_1) || + (tx_priv->version == BOLERO_VERSION_2_2)) snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F, tx_priv->bcs_ch); @@ -1219,6 +1309,10 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, 0x20, 0x00); snd_soc_component_update_bits(component, dec_cfg_reg, 0x06, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x40, 0x40); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x40, 0x00); snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00); if (tx_priv->bcs_enable) { @@ -1227,7 +1321,8 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00); tx_priv->bcs_clk_en = false; - if (tx_priv->version == BOLERO_VERSION_2_1) + if ((tx_priv->version == BOLERO_VERSION_2_1) || + (tx_priv->version == BOLERO_VERSION_2_2)) snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F, 0x00); @@ -1559,6 +1654,38 @@ TX_MACRO_DAPM_ENUM_EXT(tx_smic7_v3, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +TX_MACRO_DAPM_ENUM_EXT(tx_smic0_v4, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum_v2); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic1_v4, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum_v2); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic2_v4, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum_v2); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic3_v4, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum_v2); + +static const char * const pcm_in0_mux_text[] = { + "SWR_MIC", "RX_SWR_TX_PCM_IN0", +}; + +static const char * const pcm_in1_mux_text[] = { + "SWR_MIC", "RX_SWR_TX_PCM_IN1", +}; + +TX_MACRO_DAPM_ENUM_EXT(rx_swr_tx_pcm_in0, SND_SOC_NOPM, + 0, pcm_in0_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_pcm_in_enum); + +TX_MACRO_DAPM_ENUM_EXT(rx_swr_tx_pcm_in1, SND_SOC_NOPM, + 0, pcm_in1_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_pcm_in_enum); + static const char * const dec_mode_mux_text[] = { "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF", }; @@ -1681,11 +1808,6 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_common[] = { TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2), TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3), - TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v2), - TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v2), - TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v2), - TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v2), - SND_SOC_DAPM_SUPPLY("TX MIC BIAS1", SND_SOC_NOPM, 0, 0, tx_macro_enable_micbias, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1768,6 +1890,12 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v2[] = { SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0, tx_aif3_cap_mixer_v2, ARRAY_SIZE(tx_aif3_cap_mixer_v2)), + + TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v2), + TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v2), + TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v2), + TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v2), + }; static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = { @@ -1788,6 +1916,10 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = { TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6), TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7), + TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v2), + TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v2), + TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v2), + TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v2), TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4_v3), TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5_v3), TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6_v3), @@ -1826,6 +1958,31 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; +static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v4[] = { + SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, + TX_MACRO_AIF1_CAP, 0, + tx_aif1_cap_mixer_v2, ARRAY_SIZE(tx_aif1_cap_mixer_v2)), + + SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, + TX_MACRO_AIF2_CAP, 0, + tx_aif2_cap_mixer_v2, ARRAY_SIZE(tx_aif2_cap_mixer_v2)), + + SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, + TX_MACRO_AIF3_CAP, 0, + tx_aif3_cap_mixer_v2, ARRAY_SIZE(tx_aif3_cap_mixer_v2)), + + TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v4), + TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v4), + TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v4), + TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v4), + + TX_MACRO_DAPM_MUX("RX SWR TX MUX0", 0, rx_swr_tx_pcm_in0), + TX_MACRO_DAPM_MUX("RX SWR TX MUX1", 0, rx_swr_tx_pcm_in1), + + SND_SOC_DAPM_INPUT("RX_SWR_TX_PCM_IN0"), + SND_SOC_DAPM_INPUT("RX_SWR_TX_PCM_IN1"), +}; + static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0, SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0), @@ -2022,8 +2179,6 @@ static const struct snd_soc_dapm_route tx_audio_map_common[] = { {"TX SMIC MUX0", "SWR_MIC7", "TX SWR_INPUT"}, {"TX SMIC MUX0", "SWR_MIC8", "TX SWR_INPUT"}, {"TX SMIC MUX0", "SWR_MIC9", "TX SWR_INPUT"}, - {"TX SMIC MUX0", "SWR_MIC10", "TX SWR_INPUT"}, - {"TX SMIC MUX0", "SWR_MIC11", "TX SWR_INPUT"}, {"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"}, {"TX DMIC MUX1", "DMIC0", "TX DMIC0"}, @@ -2046,8 +2201,6 @@ static const struct snd_soc_dapm_route tx_audio_map_common[] = { {"TX SMIC MUX1", "SWR_MIC7", "TX SWR_INPUT"}, {"TX SMIC MUX1", "SWR_MIC8", "TX SWR_INPUT"}, {"TX SMIC MUX1", "SWR_MIC9", "TX SWR_INPUT"}, - {"TX SMIC MUX1", "SWR_MIC10", "TX SWR_INPUT"}, - {"TX SMIC MUX1", "SWR_MIC11", "TX SWR_INPUT"}, {"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"}, {"TX DMIC MUX2", "DMIC0", "TX DMIC0"}, @@ -2070,8 +2223,6 @@ static const struct snd_soc_dapm_route tx_audio_map_common[] = { {"TX SMIC MUX2", "SWR_MIC7", "TX SWR_INPUT"}, {"TX SMIC MUX2", "SWR_MIC8", "TX SWR_INPUT"}, {"TX SMIC MUX2", "SWR_MIC9", "TX SWR_INPUT"}, - {"TX SMIC MUX2", "SWR_MIC10", "TX SWR_INPUT"}, - {"TX SMIC MUX2", "SWR_MIC11", "TX SWR_INPUT"}, {"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"}, {"TX DMIC MUX3", "DMIC0", "TX DMIC0"}, @@ -2094,11 +2245,35 @@ static const struct snd_soc_dapm_route tx_audio_map_common[] = { {"TX SMIC MUX3", "SWR_MIC7", "TX SWR_INPUT"}, {"TX SMIC MUX3", "SWR_MIC8", "TX SWR_INPUT"}, {"TX SMIC MUX3", "SWR_MIC9", "TX SWR_INPUT"}, +}; + +static const struct snd_soc_dapm_route tx_audio_map_v2[] = { + {"TX SMIC MUX0", "SWR_MIC10", "TX SWR_INPUT"}, + {"TX SMIC MUX0", "SWR_MIC11", "TX SWR_INPUT"}, + + {"TX SMIC MUX1", "SWR_MIC10", "TX SWR_INPUT"}, + {"TX SMIC MUX1", "SWR_MIC11", "TX SWR_INPUT"}, + + {"TX SMIC MUX2", "SWR_MIC10", "TX SWR_INPUT"}, + {"TX SMIC MUX2", "SWR_MIC11", "TX SWR_INPUT"}, + {"TX SMIC MUX3", "SWR_MIC10", "TX SWR_INPUT"}, {"TX SMIC MUX3", "SWR_MIC11", "TX SWR_INPUT"}, }; static const struct snd_soc_dapm_route tx_audio_map_v3[] = { + {"TX SMIC MUX0", "SWR_MIC10", "TX SWR_INPUT"}, + {"TX SMIC MUX0", "SWR_MIC11", "TX SWR_INPUT"}, + + {"TX SMIC MUX1", "SWR_MIC10", "TX SWR_INPUT"}, + {"TX SMIC MUX1", "SWR_MIC11", "TX SWR_INPUT"}, + + {"TX SMIC MUX2", "SWR_MIC10", "TX SWR_INPUT"}, + {"TX SMIC MUX2", "SWR_MIC11", "TX SWR_INPUT"}, + + {"TX SMIC MUX3", "SWR_MIC10", "TX SWR_INPUT"}, + {"TX SMIC MUX3", "SWR_MIC11", "TX SWR_INPUT"}, + {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"}, {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"}, {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"}, @@ -2238,6 +2413,39 @@ static const struct snd_soc_dapm_route tx_audio_map_v3[] = { {"TX SWR_INPUT", NULL, "TX_SWR_PWR"}, }; +static const struct snd_soc_dapm_route tx_audio_map_v4[] = { + {"TX SMIC MUX0", "SWR_MIC10", "RX SWR TX MUX0"}, + {"RX SWR TX MUX0", "SWR_MIC", "TX SWR_INPUT"}, + {"RX SWR TX MUX0", "RX_SWR_TX_PCM_IN0", "RX_SWR_TX_PCM_IN0"}, + {"TX SMIC MUX0", "SWR_MIC11", "RX SWR TX MUX1"}, + {"RX SWR TX MUX1", "SWR_MIC", "TX SWR_INPUT"}, + {"RX SWR TX MUX1", "RX_SWR_TX_PCM_IN1", "RX_SWR_TX_PCM_IN1"}, + + {"TX SMIC MUX1", "SWR_MIC10", "RX SWR TX MUX0"}, + {"RX SWR TX MUX0", "SWR_MIC", "TX SWR_INPUT"}, + {"RX SWR TX MUX0", "RX_SWR_TX_PCM_IN0", "RX_SWR_TX_PCM_IN0"}, + {"TX SMIC MUX1", "SWR_MIC11", "RX SWR TX MUX1"}, + {"RX SWR TX MUX1", "SWR_MIC", "TX SWR_INPUT"}, + {"RX SWR TX MUX1", "RX_SWR_TX_PCM_IN1", "RX_SWR_TX_PCM_IN1"}, + + {"TX SMIC MUX2", "SWR_MIC10", "RX SWR TX MUX0"}, + {"RX SWR TX MUX0", "SWR_MIC", "TX SWR_INPUT"}, + {"RX SWR TX MUX0", "RX_SWR_TX_PCM_IN0", "RX_SWR_TX_PCM_IN0"}, + {"TX SMIC MUX2", "SWR_MIC11", "RX SWR TX MUX1"}, + {"RX SWR TX MUX1", "SWR_MIC", "TX SWR_INPUT"}, + {"RX SWR TX MUX1", "RX_SWR_TX_PCM_IN1", "RX_SWR_TX_PCM_IN1"}, + + {"TX SMIC MUX3", "SWR_MIC10", "RX SWR TX MUX0"}, + {"RX SWR TX MUX0", "SWR_MIC", "TX SWR_INPUT"}, + {"RX SWR TX MUX0", "RX_SWR_TX_PCM_IN0", "RX_SWR_TX_PCM_IN0"}, + {"TX SMIC MUX3", "SWR_MIC11", "RX SWR TX MUX1"}, + {"RX SWR TX MUX1", "SWR_MIC", "TX SWR_INPUT"}, + {"RX SWR TX MUX1", "RX_SWR_TX_PCM_IN1", "RX_SWR_TX_PCM_IN1"}, + + {"RX SWR TX MUX0", NULL, "TX_MCLK"}, + {"RX SWR TX MUX1", NULL, "TX_MCLK"}, +}; + static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX_AIF1 CAP", NULL, "TX_MCLK"}, {"TX_AIF2 CAP", NULL, "TX_MCLK"}, @@ -3125,6 +3333,10 @@ static int tx_macro_init(struct snd_soc_component *component) ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets_v3, ARRAY_SIZE(tx_macro_dapm_widgets_v3)); + else if (tx_priv->version == BOLERO_VERSION_2_2) + ret = snd_soc_dapm_new_controls(dapm, + tx_macro_dapm_widgets_v4, + ARRAY_SIZE(tx_macro_dapm_widgets_v4)); if (ret < 0) { dev_err(tx_dev, "%s: Failed to add controls\n", __func__); @@ -3149,10 +3361,18 @@ static int tx_macro_init(struct snd_soc_component *component) __func__); return ret; } + if (tx_priv->version == BOLERO_VERSION_2_1) + ret = snd_soc_dapm_add_routes(dapm, + tx_audio_map_v2, + ARRAY_SIZE(tx_audio_map_v2)); if (tx_priv->version == BOLERO_VERSION_2_0) ret = snd_soc_dapm_add_routes(dapm, tx_audio_map_v3, ARRAY_SIZE(tx_audio_map_v3)); + if (tx_priv->version == BOLERO_VERSION_2_2) + ret = snd_soc_dapm_add_routes(dapm, + tx_audio_map_v4, + ARRAY_SIZE(tx_audio_map_v4)); if (ret < 0) { dev_err(tx_dev, "%s: Failed to add routes\n", __func__); diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 0c98109b76..6a253fdbe3 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -180,6 +180,7 @@ struct va_macro_priv { int dec_mode[VA_MACRO_NUM_DECIMATORS]; u16 current_clk_id; int pcm_rate[VA_MACRO_NUM_DECIMATORS]; + bool dev_up; }; static bool va_macro_get_data(struct snd_soc_component *component, @@ -325,6 +326,7 @@ static int va_macro_event_handler(struct snd_soc_component *component, trace_printk("%s, enter SSR up\n", __func__); /* reset swr after ssr/pdr */ va_priv->reset_swr = true; + va_priv->dev_up = true; if (va_priv->swr_ctrl_data) swrm_wcd_notify( va_priv->swr_ctrl_data[0].va_swr_pdev, @@ -334,6 +336,7 @@ static int va_macro_event_handler(struct snd_soc_component *component, bolero_rsc_clk_reset(va_dev, VA_CORE_CLK); break; case BOLERO_MACRO_EVT_SSR_DOWN: + va_priv->dev_up = false; if (va_priv->swr_ctrl_data) { swrm_wcd_notify( va_priv->swr_ctrl_data[0].va_swr_pdev, @@ -437,31 +440,31 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, } break; case SND_SOC_DAPM_POST_PMD: - if (va_priv->current_clk_id == VA_CORE_CLK && - va_priv->va_swr_clk_cnt != 0 && - va_priv->tx_clk_status) { + if (va_priv->current_clk_id == VA_CORE_CLK) { ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, TX_CORE_CLK, true); if (ret) { - dev_dbg(component->dev, - "%s: request clock TX_CLK disable failed\n", + dev_err(component->dev, + "%s: request clock TX_CLK enable failed\n", __func__); - break; + if (va_priv->dev_up) + break; } ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, VA_CORE_CLK, false); if (ret) { - dev_dbg(component->dev, + dev_err(component->dev, "%s: request clock VA_CLK disable failed\n", __func__); - bolero_clk_rsc_request_clock(va_priv->dev, - TX_CORE_CLK, - TX_CORE_CLK, - false); + if (va_priv->dev_up) + bolero_clk_rsc_request_clock(va_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); break; } va_priv->current_clk_id = TX_CORE_CLK; @@ -1338,6 +1341,10 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, /* Disable TX CLK */ snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x20, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x40, 0x40); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x40, 0x00); snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00); break; @@ -2750,7 +2757,8 @@ static int va_macro_init(struct snd_soc_component *component) __func__); return ret; } - if (va_priv->version == BOLERO_VERSION_2_1) + if ((va_priv->version == BOLERO_VERSION_2_1) || + (va_priv->version == BOLERO_VERSION_2_2)) ret = snd_soc_dapm_new_controls(dapm, va_macro_dapm_widgets_v2, ARRAY_SIZE(va_macro_dapm_widgets_v2)); @@ -2792,7 +2800,8 @@ static int va_macro_init(struct snd_soc_component *component) return ret; } } - if (va_priv->version == BOLERO_VERSION_2_1) { + if ((va_priv->version == BOLERO_VERSION_2_1) || + (va_priv->version == BOLERO_VERSION_2_2)) { ret = snd_soc_dapm_add_routes(dapm, va_audio_map_v2, ARRAY_SIZE(va_audio_map_v2)); @@ -2867,6 +2876,8 @@ static int va_macro_init(struct snd_soc_component *component) } snd_soc_dapm_sync(dapm); + va_priv->dev_up = true; + for (i = 0; i < VA_MACRO_NUM_DECIMATORS; i++) { va_priv->va_hpf_work[i].va_priv = va_priv; va_priv->va_hpf_work[i].decimator = i; @@ -2882,7 +2893,8 @@ static int va_macro_init(struct snd_soc_component *component) } va_priv->component = component; - if (va_priv->version == BOLERO_VERSION_2_1) { + if ((va_priv->version == BOLERO_VERSION_2_1) || + (va_priv->version == BOLERO_VERSION_2_2)) { snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0, 0xEE, 0xCC); snd_soc_component_update_bits(component, diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index c4b09343ef..a47dfeaabe 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _WCD937X_INTERNAL_H @@ -60,6 +61,7 @@ struct wcd937x_priv { u32 hph_mode; bool comp1_enable; bool comp2_enable; + bool bcs_dis; struct irq_domain *virq; struct wcd_irq_info irq_info; @@ -93,6 +95,7 @@ struct wcd937x_priv { struct snd_info_entry *variant_entry; int ear_rx_path; int ana_clk_count; + int adc_count; struct mutex ana_tx_clk_lock; u8 tx_master_ch_map[WCD937X_MAX_SLAVE_CH_TYPES]; bool usbc_hs_status; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 542011a8c7..540c9c1fd1 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -142,11 +142,6 @@ static int wcd937x_handle_post_irq(void *data) struct wcd937x_priv *wcd937x = data; u32 status1 = 0, status2 = 0, status3 = 0; - /* Clear the ACK registers. Temporary workaround.*/ - regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_0, 0x0); - regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_1, 0x0); - regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_2, 0x0); - regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &status1); regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &status2); regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_2, &status3); @@ -159,8 +154,20 @@ static int wcd937x_handle_post_irq(void *data) static int wcd937x_init_reg(struct snd_soc_component *component) { - snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL, + u32 val = 0; + + val = snd_soc_component_read(component, WCD937X_DIGITAL_EFUSE_REG_29) + & 0x0F; + + if (snd_soc_component_read(component, WCD937X_DIGITAL_EFUSE_REG_16) + == 0x02 || snd_soc_component_read(component, + WCD937X_DIGITAL_EFUSE_REG_17) > 0x09) { + snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL, + 0x0E, val); + } else { + snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL, 0x0E, 0x0E); + } snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL, 0x80, 0x80); usleep_range(1000, 1010); @@ -187,6 +194,28 @@ static int wcd937x_init_reg(struct snd_soc_component *component) 0xFF, 0xFA); snd_soc_component_update_bits(component, WCD937X_MICB3_TEST_CTL_1, 0xFF, 0xFA); + snd_soc_component_update_bits(component, WCD937X_MICB1_TEST_CTL_2, + 0x38, 0x00); + snd_soc_component_update_bits(component, WCD937X_MICB2_TEST_CTL_2, + 0x38, 0x00); + snd_soc_component_update_bits(component, WCD937X_MICB3_TEST_CTL_2, + 0x38, 0x00); + /* Set Bandgap Fine Adjustment to +5mV for Tanggu SMIC part */ + if (snd_soc_component_read(component, WCD937X_DIGITAL_EFUSE_REG_16) + == 0x01) { + snd_soc_component_update_bits(component, + WCD937X_BIAS_VBG_FINE_ADJ, 0xF0, 0xB0); + } else if (snd_soc_component_read(component, + WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) { + snd_soc_component_update_bits(component, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x1F, 0x04); + snd_soc_component_update_bits(component, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x1F, 0x04); + snd_soc_component_update_bits(component, + WCD937X_BIAS_VBG_FINE_ADJ, 0xF0, 0xB0); + snd_soc_component_update_bits(component, + WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xF0, 0x50); + } return 0; } @@ -551,6 +580,12 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: + if ((snd_soc_component_read(component, + WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) && + ((snd_soc_component_read(component, + WCD937X_ANA_HPH) & 0x0C) == 0x0C)) + snd_soc_component_update_bits(component, + WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x90); if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, @@ -592,6 +627,12 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); break; case SND_SOC_DAPM_POST_PMD: + if ((snd_soc_component_read(component, + WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) && + ((snd_soc_component_read(component, + WCD937X_ANA_HPH) & 0x0C) == 0x0C)) + snd_soc_component_update_bits(component, + WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x80); snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x01); @@ -625,6 +666,12 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: + if ((snd_soc_component_read(component, + WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) && + ((snd_soc_component_read(component, + WCD937X_ANA_HPH) & 0x0C) == 0x0C)) + snd_soc_component_update_bits(component, + WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x90); if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, @@ -666,6 +713,12 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); break; case SND_SOC_DAPM_POST_PMD: + if ((snd_soc_component_read(component, + WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) && + ((snd_soc_component_read(component, + WCD937X_ANA_HPH) & 0x0C) == 0x0C)) + snd_soc_component_update_bits(component, + WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x80); snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x0F, 0x01); @@ -1413,8 +1466,12 @@ static int wcd937x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, /* Enable BCS for Headset mic */ if (w->shift == 1 && !(snd_soc_component_read(component, WCD937X_TX_NEW_TX_CH2_SEL) & 0x80)) { - wcd937x_tx_connect_port(component, MBHC, true); - set_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask); + if (!wcd937x->bcs_dis) { + wcd937x_tx_connect_port( + component, MBHC, true); + set_bit(AMIC2_BCS_ENABLE, + &wcd937x->status_mask); + } } wcd937x_tx_connect_port(component, ADC1 + (w->shift), true); } else { @@ -1449,6 +1506,7 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, mutex_lock(&wcd937x->ana_tx_clk_lock); wcd937x->ana_clk_count++; mutex_unlock(&wcd937x->ana_tx_clk_lock); + wcd937x->adc_count++; snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); snd_soc_component_update_bits(component, @@ -1466,8 +1524,13 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, wcd937x_tx_connect_port(component, MBHC, false); clear_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask); } - snd_soc_component_update_bits(component, - WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); + + wcd937x->adc_count--; + if (wcd937x->adc_count <= 0) { + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); + wcd937x->adc_count = 0; + } break; }; @@ -1507,14 +1570,19 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, WCD937X_ANA_TX_CH3, 0x80, 0x80); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_component_update_bits(component, + if (wcd937x->adc_count == 0) { + snd_soc_component_update_bits(component, WCD937X_ANA_TX_CH1, 0x80, 0x00); - snd_soc_component_update_bits(component, + snd_soc_component_update_bits(component, WCD937X_ANA_TX_CH2, 0x80, 0x00); - snd_soc_component_update_bits(component, + snd_soc_component_update_bits(component, WCD937X_ANA_TX_CH3, 0x80, 0x00); - snd_soc_component_update_bits(component, + snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00); + } + mutex_lock(&wcd937x->ana_tx_clk_lock); wcd937x->ana_clk_count--; if (wcd937x->ana_clk_count <= 0) { @@ -1524,8 +1592,6 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, } mutex_unlock(&wcd937x->ana_tx_clk_lock); - snd_soc_component_update_bits(component, - WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00); break; }; return 0; @@ -2185,6 +2251,29 @@ static int wcd937x_tx_master_ch_put(struct snd_kcontrol *kcontrol, return 0; } +static int wcd937x_bcs_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wcd937x->bcs_dis; + return 0; +} + +static int wcd937x_bcs_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + + wcd937x->bcs_dis = ucontrol->value.integer.value[0]; + dev_dbg(component->dev, "%s: BCS Disable %d\n", __func__, wcd937x->bcs_dis); + return 0; +} + static const char * const wcd937x_tx_ch_pwr_level_text[] = { "L0", "L1", "L2", "L3", }; @@ -2216,6 +2305,8 @@ static const struct snd_kcontrol_new wcd937x_snd_controls[] = { wcd937x_get_compander, wcd937x_set_compander), SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, wcd937x_get_compander, wcd937x_set_compander), + SOC_SINGLE_EXT("ADC2_BCS Disable", SND_SOC_NOPM, 0, 1, 0, + wcd937x_bcs_get, wcd937x_bcs_put), SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD937X_HPH_R_EN, 0, 20, 1, line_gain), @@ -2846,6 +2937,8 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component) component, WCD937X_DIGITAL_EFUSE_REG_0) & 0x1E) >> 1; wcd937x->variant = variant; + wcd937x->adc_count = 0; + wcd937x->fw_data = devm_kzalloc(component->dev, sizeof(*(wcd937x->fw_data)), GFP_KERNEL); diff --git a/asoc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c index b5712636bc..fdb46bb9af 100644 --- a/asoc/codecs/wsa881x-analog.c +++ b/asoc/codecs/wsa881x-analog.c @@ -1233,12 +1233,12 @@ static const struct snd_soc_component_driver soc_codec_dev_wsa881x = { static struct snd_soc_dai_driver wsa_dai[] = { { - .name = "", + .name = "wsa_rx0", .playback = { .stream_name = "", .rates = WSA881X_RATES | WSA881X_FRAC_RATES, .formats = WSA881X_FORMATS, - .rate_max = 192000, + .rate_max = 384000, .rate_min = 8000, .channels_min = 1, .channels_max = 2, diff --git a/asoc/holi.c b/asoc/holi.c index 0c433a3cc9..01fad3603c 100644 --- a/asoc/holi.c +++ b/asoc/holi.c @@ -1774,7 +1774,16 @@ err: static int msm_asoc_machine_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = NULL; + struct msm_common_pdata *common_pdata = NULL; + if (card) + pdata = snd_soc_card_get_drvdata(card); + + if (pdata) + common_pdata = pdata->common_pdata; + + msm_common_snd_deinit(common_pdata); snd_event_master_deregister(&pdev->dev); snd_soc_unregister_card(card); diff --git a/include/asoc/bolero-slave-internal.h b/include/asoc/bolero-slave-internal.h index af06c201d1..d9ec507801 100644 --- a/include/asoc/bolero-slave-internal.h +++ b/include/asoc/bolero-slave-internal.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ /* from Slave to bolero events */ @@ -24,4 +25,5 @@ enum { BOLERO_SLV_EVT_PA_ON_POST_FSCLK, BOLERO_SLV_EVT_PA_ON_POST_FSCLK_ADIE_LB, BOLERO_SLV_EVT_CLK_NOTIFY, + BOLERO_SLV_EVT_RX_MACRO_PA_ON, };