diff --git a/Makefile b/Makefile index 0e8ab5953c..27147bd9f6 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,6 @@ export endif endif - # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE += \ -I$(srctree)/techpack/audio/include/uapi/audio diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index efd9195324..0a81acc0c9 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -169,8 +169,10 @@ ifdef CONFIG_SND_SOC_WSA881X_ANALOG WSA881X_ANALOG_OBJS += wsa881x-analog.o WSA881X_ANALOG_OBJS += wsa881x-tables-analog.o WSA881X_ANALOG_OBJS += wsa881x-regmap-analog.o +ifndef CONFIG_WSA881X_TEMP_SENSOR_DISABLE WSA881X_ANALOG_OBJS += wsa881x-temp-sensor.o endif +endif ifdef CONFIG_SND_SOC_MSM_STUB STUB_OBJS += msm_stub.o endif diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index b4e6d1555d..d3604cf27a 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef CONFIG_AUDIO_PRM #include #else @@ -73,6 +74,7 @@ static int audio_ext_clk_prepare(struct clk_hw *hw) struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info; int ret; + static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1); if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) && (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX) && !clk_priv->clk_cfg.enable) { @@ -83,7 +85,8 @@ static int audio_ext_clk_prepare(struct clk_hw *hw) ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); #endif if (ret < 0) { - pr_err_ratelimited("%s afe_set_digital_codec_core_clock failed\n", + if (__ratelimit(&rtl)) + pr_err_ratelimited("%s afe_set_digital_codec_core_clock failed\n", __func__); return ret; } @@ -110,6 +113,7 @@ static void audio_ext_clk_unprepare(struct clk_hw *hw) struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info; int ret; + static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1); if (pnctrl_info->pinctrl) { ret = pinctrl_select_state(pnctrl_info->pinctrl, @@ -131,9 +135,11 @@ static void audio_ext_clk_unprepare(struct clk_hw *hw) #else ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); #endif - if (ret < 0) - pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n", + if (ret < 0) { + if (__ratelimit(&rtl)) + pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n", __func__, ret); + } } if (pnctrl_info->base) @@ -160,9 +166,10 @@ static u8 audio_ext_clk_get_parent(struct clk_hw *hw) static int lpass_hw_vote_prepare(struct clk_hw *hw) { + struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); + int ret; + static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1); - struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); - int ret; if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) { #ifdef CONFIG_AUDIO_PRM pr_debug("%s: clk_id %d ",__func__, clk_priv->prm_clk_cfg.clk_id); @@ -191,7 +198,8 @@ static int lpass_hw_vote_prepare(struct clk_hw *hw) &clk_priv->lpass_audio_hwvote_client_handle); #endif if (ret < 0) { - pr_err("%s lpass audio hw vote failed %d\n", + if (__ratelimit(&rtl)) + pr_err("%s lpass audio hw vote failed %d\n", __func__, ret); return ret; } diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 1a9eeffef2..d6af655500 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "bolero-cdc.h" #include "internal.h" #include "bolero-clk-rsc.h" @@ -1373,6 +1374,7 @@ static int bolero_probe(struct platform_device *pdev) bolero_reg_access[VA_MACRO] = bolero_va_reg_access_v3; } + BLOCKING_INIT_NOTIFIER_HEAD(&priv->notifier); priv->dev = &pdev->dev; priv->dev_up = true; priv->initial_boot = true; @@ -1444,6 +1446,7 @@ int bolero_runtime_resume(struct device *dev) { struct bolero_priv *priv = dev_get_drvdata(dev->parent); int ret = 0; + static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1); mutex_lock(&priv->vote_lock); if (priv->lpass_core_hw_vote == NULL) { @@ -1472,8 +1475,9 @@ audio_vote: if (priv->core_audio_vote_count == 0) { ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_audio_hw_vote); if (ret < 0) { - dev_err(dev, "%s:lpass audio hw enable failed\n", - __func__); + if (__ratelimit(&rtl)) + dev_err(dev, "%s:lpass audio hw enable failed\n", + __func__); goto done; } } diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index b134819e0c..7dad4b60e5 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "bolero-cdc.h" #include "bolero-clk-rsc.h" @@ -193,13 +194,15 @@ static int bolero_clk_rsc_mux0_clk_request(struct bolero_clk_rsc *priv, bool enable) { int ret = 0; + static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1); if (enable) { /* Enable Requested Core clk */ if (priv->clk_cnt[clk_id] == 0) { ret = clk_prepare_enable(priv->clk[clk_id]); if (ret < 0) { - dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", + if (__ratelimit(&rtl)) + dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", __func__, clk_id); goto done; } @@ -207,7 +210,8 @@ static int bolero_clk_rsc_mux0_clk_request(struct bolero_clk_rsc *priv, ret = clk_prepare_enable( priv->clk[clk_id + NPL_CLK_OFFSET]); if (ret < 0) { - dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", + if (__ratelimit(&rtl)) + dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", __func__, clk_id + NPL_CLK_OFFSET); goto err; @@ -246,6 +250,7 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, int ret = 0; int default_clk_id = priv->default_clk_id[clk_id]; u32 muxsel = 0; + static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1); clk_muxsel = bolero_clk_rsc_get_clk_muxsel(priv, clk_id); if (!clk_muxsel) { @@ -265,15 +270,17 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, ret = clk_prepare_enable(priv->clk[clk_id]); if (ret < 0) { - dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", - __func__, clk_id); + if (__ratelimit(&rtl)) + dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", + __func__, clk_id); goto err_clk; } if (priv->clk[clk_id + NPL_CLK_OFFSET]) { ret = clk_prepare_enable( priv->clk[clk_id + NPL_CLK_OFFSET]); if (ret < 0) { - dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", + if (__ratelimit(&rtl)) + dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", __func__, clk_id + NPL_CLK_OFFSET); goto err_npl_clk; @@ -469,14 +476,15 @@ void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) mutex_lock(&priv->fs_gen_lock); if (enable) { if (priv->reg_seq_en_cnt++ == 0) { - for (i = 0; i < (priv->num_fs_reg * 2); i += 2) { - dev_dbg(priv->dev, "%s: Register: %d, value: %d\n", + for (i = 0; i < (priv->num_fs_reg * 3); i += 3) { + dev_dbg(priv->dev, "%s: Register: %d, mask: %d, value %d\n", __func__, priv->fs_gen_seq[i], - priv->fs_gen_seq[i + 1]); + priv->fs_gen_seq[i + 1], + priv->fs_gen_seq[i + 2]); regmap_update_bits(regmap, priv->fs_gen_seq[i], priv->fs_gen_seq[i + 1], - priv->fs_gen_seq[i + 1]); + priv->fs_gen_seq[i + 2]); } } } else { @@ -488,8 +496,8 @@ void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) return; } if (--priv->reg_seq_en_cnt == 0) { - for (i = ((priv->num_fs_reg - 1) * 2); i >= 0; i -= 2) { - dev_dbg(priv->dev, "%s: Register: %d, value: %d\n", + for (i = ((priv->num_fs_reg - 1) * 3); i >= 0; i -= 3) { + dev_dbg(priv->dev, "%s: Register: %d, mask: %d\n", __func__, priv->fs_gen_seq[i], priv->fs_gen_seq[i + 1]); regmap_update_bits(regmap, priv->fs_gen_seq[i], @@ -614,7 +622,7 @@ static int bolero_clk_rsc_probe(struct platform_device *pdev) ret = -EINVAL; goto err; } - priv->num_fs_reg = fs_gen_size/(2 * sizeof(u32)); + priv->num_fs_reg = fs_gen_size/(3 * sizeof(u32)); priv->fs_gen_seq = devm_kzalloc(&pdev->dev, fs_gen_size, GFP_KERNEL); if (!priv->fs_gen_seq) { ret = -ENOMEM; @@ -625,7 +633,7 @@ static int bolero_clk_rsc_probe(struct platform_device *pdev) ret = of_property_read_u32_array(pdev->dev.of_node, "qcom,fs-gen-sequence", priv->fs_gen_seq, - priv->num_fs_reg * 2); + priv->num_fs_reg * 3); if (ret < 0) { dev_err(&pdev->dev, "%s: unable to parse fs-gen-sequence, ret = %d\n", __func__, ret); diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 48f596e20c..dda2233733 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -351,6 +351,7 @@ struct rx_macro_bcl_pmic_params { u8 ppid; }; +static int rx_macro_core_vote(void *handle, bool enable); static int rx_macro_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai); @@ -1274,6 +1275,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, if (rx_priv->rx_mclk_users == 0) { if (rx_priv->is_native_on) rx_priv->clk_id = RX_CORE_CLK; + rx_macro_core_vote(rx_priv, true); ret = bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, rx_priv->clk_id, @@ -1327,6 +1329,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, 0x01, 0x00); bolero_clk_rsc_fs_gen_request(rx_priv->dev, false); + rx_macro_core_vote(rx_priv, true); bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, rx_priv->clk_id, @@ -1440,18 +1443,21 @@ static int rx_macro_event_handler(struct snd_soc_component *component, } break; case BOLERO_MACRO_EVT_PRE_SSR_UP: + rx_macro_core_vote(rx_priv, true); /* enable&disable RX_CORE_CLK to reset GFMUX reg */ ret = bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, RX_CORE_CLK, true); - if (ret < 0) + if (ret < 0) { dev_err_ratelimited(rx_priv->dev, "%s, failed to enable clk, ret:%d\n", __func__, ret); - else + } else { + rx_macro_core_vote(rx_priv, true); bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, RX_CORE_CLK, false); + } break; case BOLERO_MACRO_EVT_SSR_UP: trace_printk("%s, enter SSR up\n", __func__); diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index cd42b969ef..d882aba6c3 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -180,6 +180,7 @@ struct tx_macro_priv { bool lpi_enable; bool register_event_listener; u16 current_clk_id; + int disable_afe_wakeup_event_listener; }; static bool tx_macro_get_data(struct snd_soc_component *component, @@ -2643,17 +2644,15 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component, if (tx_priv->swr_ctrl_data && (!tx_priv->tx_swr_clk_cnt || !tx_priv->va_swr_clk_cnt)) { if (enable) { - ret = swrm_wcd_notify( - tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_REGISTER_WAKEUP, NULL); - msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, false); + if (!tx_priv->disable_afe_wakeup_event_listener) + ret = swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_REGISTER_WAKEUP, NULL); } else { - msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, true); - ret = swrm_wcd_notify( - tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_DEREGISTER_WAKEUP, NULL); + if (!tx_priv->disable_afe_wakeup_event_listener) + ret = swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_DEREGISTER_WAKEUP, NULL); } } @@ -2685,6 +2684,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, __func__); goto exit; } + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, false); } clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev, @@ -2813,6 +2814,8 @@ tx_clk: TX_CORE_CLK, false); if (tx_priv->swr_clk_users == 0) { + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, true); ret = msm_cdc_pinctrl_select_sleep_state( tx_priv->tx_swr_gpio_p); if (ret < 0) { @@ -3409,6 +3412,9 @@ static int tx_macro_probe(struct platform_device *pdev) const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate"; u32 is_used_tx_swr_gpio = 1; const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio"; + u32 disable_afe_wakeup_event_listener = 0; + const char *disable_afe_wakeup_event_listener_dt = + "qcom,disable-afe-wakeup-event-listener"; if (!bolero_is_va_macro_registered(&pdev->dev)) { dev_err(&pdev->dev, @@ -3475,6 +3481,19 @@ static int tx_macro_probe(struct platform_device *pdev) sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED) return -EINVAL; } + + if (of_find_property(pdev->dev.of_node, + disable_afe_wakeup_event_listener_dt, NULL)) { + ret = of_property_read_u32(pdev->dev.of_node, + disable_afe_wakeup_event_listener_dt, + &disable_afe_wakeup_event_listener); + if (ret) + dev_dbg(&pdev->dev, "%s: error reading %s in dt\n", + __func__, disable_afe_wakeup_event_listener_dt); + } + tx_priv->disable_afe_wakeup_event_listener = + disable_afe_wakeup_event_listener; + if (is_used_tx_swr_gpio) { tx_priv->reset_swr = true; INIT_WORK(&tx_priv->tx_macro_add_child_devices_work, diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 1767d5b4bd..32c180ba62 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -170,10 +170,12 @@ struct va_macro_priv { int va_swr_clk_cnt; int va_clk_status; int tx_clk_status; + int dapm_tx_clk_status; bool lpi_enable; bool register_event_listener; + bool clk_div_switch; int dec_mode[VA_MACRO_NUM_DECIMATORS]; - int disable_afe_wakeup_event_listener; + u16 current_clk_id; }; static bool va_macro_get_data(struct snd_soc_component *component, @@ -205,7 +207,7 @@ static int va_macro_clk_div_get(struct snd_soc_component *component) return -EINVAL; if ((va_priv->version >= BOLERO_VERSION_2_0) - && !va_priv->lpi_enable + && va_priv->clk_div_switch && (va_priv->dmic_clk_div == VA_MACRO_CLK_DIV_16)) return VA_MACRO_CLK_DIV_8; @@ -393,7 +395,14 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - if (va_priv->default_clk_id != VA_CORE_CLK) { + dev_dbg(component->dev, + "%s: va_swr_clk_cnt %d, tx_swr_clk_cnt %d, tx_clk_status %d\n", + __func__, va_priv->va_swr_clk_cnt, + va_priv->tx_swr_clk_cnt, va_priv->tx_clk_status); + if (va_priv->current_clk_id == VA_CORE_CLK) { + return 0; + } else if ( va_priv->va_swr_clk_cnt != 0 && + va_priv->tx_clk_status) { ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, VA_CORE_CLK, @@ -418,14 +427,13 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, false); break; } + va_priv->current_clk_id = VA_CORE_CLK; } - msm_cdc_pinctrl_set_wakeup_capable( - va_priv->va_swr_gpio_p, false); break; case SND_SOC_DAPM_POST_PMD: - msm_cdc_pinctrl_set_wakeup_capable( - va_priv->va_swr_gpio_p, true); - if (va_priv->default_clk_id == TX_CORE_CLK) { + if (va_priv->current_clk_id == VA_CORE_CLK && + va_priv->va_swr_clk_cnt != 0 && + va_priv->tx_clk_status) { ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, TX_CORE_CLK, @@ -450,6 +458,7 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, false); break; } + va_priv->current_clk_id = TX_CORE_CLK; } break; default: @@ -493,8 +502,7 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, dev_dbg(va_dev, "%s: clock switch failed\n", __func__); } - if (va_priv->lpi_enable && - !va_priv->disable_afe_wakeup_event_listener) { + if (va_priv->lpi_enable) { bolero_register_event_listener(component, true); va_priv->register_event_listener = true; } @@ -557,7 +565,7 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, TX_CORE_CLK, true); if (!ret) - va_priv->tx_clk_status++; + va_priv->dapm_tx_clk_status++; if (va_priv->lpi_enable) ret = va_macro_mclk_enable(va_priv, 1, true); @@ -571,12 +579,12 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, bolero_tx_mclk_enable(component, 0); } - if (va_priv->tx_clk_status > 0) { + if (va_priv->dapm_tx_clk_status > 0) { bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, TX_CORE_CLK, false); - va_priv->tx_clk_status--; + va_priv->dapm_tx_clk_status--; } break; default: @@ -599,9 +607,12 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv, (enable ? "enable" : "disable"), va_priv->va_mclk_users); if (enable) { - if (va_priv->swr_clk_users == 0) + if (va_priv->swr_clk_users == 0) { msm_cdc_pinctrl_select_active_state( va_priv->va_swr_gpio_p); + msm_cdc_pinctrl_set_wakeup_capable( + va_priv->va_swr_gpio_p, false); + } clk_tx_ret = bolero_clk_rsc_request_clock(va_priv->dev, TX_CORE_CLK, TX_CORE_CLK, @@ -694,9 +705,12 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv, TX_CORE_CLK, TX_CORE_CLK, false); - if (va_priv->swr_clk_users == 0) + if (va_priv->swr_clk_users == 0) { + msm_cdc_pinctrl_set_wakeup_capable( + va_priv->va_swr_gpio_p, true); msm_cdc_pinctrl_select_sleep_state( va_priv->va_swr_gpio_p); + } } return 0; @@ -1312,12 +1326,12 @@ static int va_macro_enable_tx(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: - if (va_priv->tx_clk_status > 0) { + if (va_priv->dapm_tx_clk_status > 0) { ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, TX_CORE_CLK, false); - va_priv->tx_clk_status--; + va_priv->dapm_tx_clk_status--; } break; case SND_SOC_DAPM_PRE_PMD: @@ -1326,7 +1340,7 @@ static int va_macro_enable_tx(struct snd_soc_dapm_widget *w, TX_CORE_CLK, true); if (!ret) - va_priv->tx_clk_status++; + va_priv->dapm_tx_clk_status++; break; default: dev_err(va_priv->dev, @@ -1508,6 +1522,10 @@ static int va_macro_hw_params(struct snd_pcm_substream *substream, params_channels(params)); sample_rate = params_rate(params); + if (sample_rate > 16000) + va_priv->clk_div_switch = true; + else + va_priv->clk_div_switch = false; switch (sample_rate) { case 8000: tx_fs_rate = 0; @@ -2224,18 +2242,6 @@ static const struct snd_soc_dapm_route va_audio_map_common[] = { {"VA SMIC MUX1", "SWR_MIC11", "VA SWR_INPUT"}, {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - {"VA SWR_INPUT", NULL, "VA_SWR_PWR"}, - }; static const struct snd_soc_dapm_route va_audio_map_v3[] = { @@ -2298,9 +2304,7 @@ static const struct snd_soc_dapm_route va_audio_map_v3[] = { }; static const struct snd_soc_dapm_route va_audio_map_v2[] = { - {"VA_AIF1 CAP", NULL, "VA_SWR_CLK"}, - {"VA_AIF2 CAP", NULL, "VA_SWR_CLK"}, - {"VA_AIF3 CAP", NULL, "VA_SWR_CLK"}, + {"VA SWR_INPUT", NULL, "VA_SWR_CLK"}, }; static const struct snd_soc_dapm_route va_audio_map[] = { @@ -3054,10 +3058,7 @@ static int va_macro_probe(struct platform_device *pdev) u32 default_clk_id = 0; struct clk *lpass_audio_hw_vote = NULL; u32 is_used_va_swr_gpio = 0; - u32 disable_afe_wakeup_event_listener = 0; const char *is_used_va_swr_gpio_dt = "qcom,is-used-swr-gpio"; - const char *disable_afe_wakeup_event_listener_dt = - "qcom,disable-afe-wakeup-event-listener"; va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv), GFP_KERNEL); @@ -3100,18 +3101,6 @@ static int va_macro_probe(struct platform_device *pdev) } } - if (of_find_property(pdev->dev.of_node, - disable_afe_wakeup_event_listener_dt, NULL)) { - ret = of_property_read_u32(pdev->dev.of_node, - disable_afe_wakeup_event_listener_dt, - &disable_afe_wakeup_event_listener); - if (ret) - dev_dbg(&pdev->dev, "%s: error reading %s in dt\n", - __func__, disable_afe_wakeup_event_listener_dt); - } - va_priv->disable_afe_wakeup_event_listener = - disable_afe_wakeup_event_listener; - va_priv->va_swr_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,va-swr-gpios", 0); if (!va_priv->va_swr_gpio_p && is_used_va_swr_gpio) { @@ -3184,6 +3173,7 @@ static int va_macro_probe(struct platform_device *pdev) } va_priv->clk_id = VA_CORE_CLK; va_priv->default_clk_id = default_clk_id; + va_priv->current_clk_id = TX_CORE_CLK; if (is_used_va_swr_gpio) { va_priv->reset_swr = true; diff --git a/asoc/codecs/swr-dmic.c b/asoc/codecs/swr-dmic.c index fb612df818..3ce3d4ad10 100644 --- a/asoc/codecs/swr-dmic.c +++ b/asoc/codecs/swr-dmic.c @@ -220,11 +220,18 @@ static int dmic_swr_ctrl(struct snd_soc_dapm_widget *w, u8 port_type = 0; u8 port_id = w->shift; + if (port_id >= SWR_DMIC_MAX_PORTS) + { + dev_err(component->dev, "%s: invalid port id: %d\n", + __func__, port_id); + return -EINVAL; + } + /* * Port 1 is high quality / 2.4 or 3.072 Mbps * Port 2 is listen low power / 0.6 or 0.768 Mbps */ - if(port_id == SWR_DMIC_HIFI_PORT) + if (port_id == SWR_DMIC_HIFI_PORT) ch_rate = SWR_CLK_RATE_2P4MHZ; else ch_rate = SWR_CLK_RATE_0P6MHZ; diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 3194724ee2..17ce0ef790 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -515,15 +515,6 @@ static void wcd_mbhc_set_and_turnoff_hph_padac(struct wcd_mbhc *mbhc) int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, uint32_t *zr) { - int detection_type = -EINVAL; - - WCD_MBHC_REG_READ(WCD_MBHC_MECH_DETECTION_TYPE, detection_type); - /* Call compute impedance only when accessory is inserted */ - if (!detection_type) { - if (mbhc->mbhc_cb->compute_impedance) - mbhc->mbhc_cb->compute_impedance(mbhc, - &mbhc->zl, &mbhc->zr); - } *zl = mbhc->zl; *zr = mbhc->zr; @@ -1630,8 +1621,6 @@ static int wcd_mbhc_set_keycode(struct wcd_mbhc *mbhc) static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb, unsigned long mode, void *ptr) { - unsigned int l_det_en = 0; - unsigned int detection_type = 0; struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, fsa_nb); if (!mbhc) @@ -1644,23 +1633,6 @@ static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb, mbhc->mbhc_cb->clk_setup(mbhc->component, true); /* insertion detected, enable L_DET_EN */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); - } else { - WCD_MBHC_REG_READ(WCD_MBHC_MECH_DETECTION_TYPE, detection_type); - WCD_MBHC_REG_READ(WCD_MBHC_L_DET_EN, l_det_en); - /* If both l_det_en and detection type are set, it means device was - * unplugged during SSR and detection interrupt was not handled. - * So trigger device disconnect */ - if (detection_type && l_det_en) { - /* Set the detection type appropriately */ - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MECH_DETECTION_TYPE, - !detection_type); - /* Set current plug type to the state before SSR */ - mbhc->current_plug = mbhc->plug_before_ssr; - - wcd_mbhc_swch_irq_handler(mbhc); - mbhc->mbhc_cb->lock_sleep(mbhc, false); - mbhc->plug_before_ssr = MBHC_PLUG_TYPE_NONE; - } } return 0; } diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index cdce7ed058..46886f4a4e 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1883,9 +1883,12 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, default: break; } - if (wcd938x->adc_count == 0) + if (wcd938x->adc_count == 0) { snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); + } break; }; return ret; @@ -2156,8 +2159,6 @@ static int wcd938x_event_notify(struct notifier_block *block, WCD938X_EVT_SSR_DOWN, NULL); wcd938x->mbhc->wcd_mbhc.deinit_in_progress = true; - wcd938x->mbhc->wcd_mbhc.plug_before_ssr = - wcd938x->mbhc->wcd_mbhc.current_plug; mbhc = &wcd938x->mbhc->wcd_mbhc; wcd938x->usbc_hs_status = get_usbc_hs_status(component, mbhc->mbhc_cfg); @@ -2183,8 +2184,6 @@ static int wcd938x_event_notify(struct notifier_block *block, __func__); } else { wcd938x_mbhc_hs_detect(component, mbhc->mbhc_cfg); - if (wcd938x->usbc_hs_status) - mdelay(500); } wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false; wcd938x->dev_up = true; @@ -2192,6 +2191,8 @@ static int wcd938x_event_notify(struct notifier_block *block, blocking_notifier_call_chain(&wcd938x->notifier, WCD938X_EVT_SSR_UP, NULL); + if (wcd938x->usbc_hs_status) + mdelay(500); break; case BOLERO_SLV_EVT_CLK_NOTIFY: snd_soc_component_update_bits(component, @@ -2842,15 +2843,22 @@ static int wcd938x_tx_master_ch_get(struct snd_kcontrol *kcontrol, { struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - int slave_ch_idx; + struct wcd938x_priv *wcd938x = NULL; + int slave_ch_idx = -EINVAL; + + if (component == NULL) + return -EINVAL; + + wcd938x = snd_soc_component_get_drvdata(component); + if (wcd938x == NULL) + return -EINVAL; wcd938x_tx_get_slave_ch_type_idx(kcontrol->id.name, &slave_ch_idx); + if (slave_ch_idx < 0 || slave_ch_idx >= WCD938X_MAX_SLAVE_CH_TYPES) + return -EINVAL; - if (slave_ch_idx != -EINVAL) - ucontrol->value.integer.value[0] = - wcd938x_slave_get_master_ch_val( - wcd938x->tx_master_ch_map[slave_ch_idx]); + ucontrol->value.integer.value[0] = wcd938x_slave_get_master_ch_val( + wcd938x->tx_master_ch_map[slave_ch_idx]); return 0; } @@ -2860,19 +2868,27 @@ static int wcd938x_tx_master_ch_put(struct snd_kcontrol *kcontrol, { struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - int slave_ch_idx; + struct wcd938x_priv *wcd938x = NULL; + int slave_ch_idx = -EINVAL; + + if (component == NULL) + return -EINVAL; + + wcd938x = snd_soc_component_get_drvdata(component); + if (wcd938x == NULL) + return -EINVAL; wcd938x_tx_get_slave_ch_type_idx(kcontrol->id.name, &slave_ch_idx); + if (slave_ch_idx < 0 || slave_ch_idx >= WCD938X_MAX_SLAVE_CH_TYPES) + return -EINVAL; + dev_dbg(component->dev, "%s: slave_ch_idx: %d", __func__, slave_ch_idx); dev_dbg(component->dev, "%s: ucontrol->value.enumerated.item[0] = %ld\n", __func__, ucontrol->value.enumerated.item[0]); - if (slave_ch_idx != -EINVAL) - wcd938x->tx_master_ch_map[slave_ch_idx] = - wcd938x_slave_get_master_ch( - ucontrol->value.enumerated.item[0]); + wcd938x->tx_master_ch_map[slave_ch_idx] = wcd938x_slave_get_master_ch( + ucontrol->value.enumerated.item[0]); return 0; } diff --git a/asoc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c index 690d5d1b67..2a07f99285 100644 --- a/asoc/codecs/wsa881x-analog.c +++ b/asoc/codecs/wsa881x-analog.c @@ -34,6 +34,7 @@ #define SPK_GAIN_12DB 4 #define WIDGET_NAME_MAX_SIZE 80 +#define REGMAP_REGISTER_CHECK_RETRY 30 #define MAX_NAME_LEN 30 #define WSA881X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ @@ -102,7 +103,7 @@ static int32_t wsa881x_resource_acquire(struct snd_soc_component *component, const char *wsa_tz_names[] = {"wsa881x.0e", "wsa881x.0f"}; -struct wsa881x_pdata wsa_pdata[MAX_WSA881X_DEVICE]; +static struct wsa881x_pdata wsa_pdata[MAX_WSA881X_DEVICE]; static bool pinctrl_init; @@ -1142,6 +1143,7 @@ static int wsa881x_probe(struct snd_soc_component *component) { struct i2c_client *client; int ret = 0; + int retry = REGMAP_REGISTER_CHECK_RETRY; int wsa881x_index = 0; struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); @@ -1165,6 +1167,16 @@ static int wsa881x_probe(struct snd_soc_component *component) wsa_pdata[wsa881x_index].tz_pdata.wsa_temp_reg_read = wsa881x_temp_reg_read; snd_soc_component_set_drvdata(component, &wsa_pdata[wsa881x_index]); + while (retry) { + if (wsa_pdata[wsa881x_index].regmap[WSA881X_ANALOG_SLAVE] + != NULL) + break; + msleep(100); + retry--; + } + if (!retry) + dev_err(&client->dev, "%s: max retry expired and regmap of\n" + "analog slave not initilized\n", __func__); wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata); INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work, wsa881x_ocp_ctl_work); @@ -1382,9 +1394,9 @@ static int wsa881x_i2c_probe(struct i2c_client *client, } if (pdata->status == WSA881X_STATUS_I2C) { - dev_dbg(&client->dev, "%s:probe for other slaves\n" - "devices of codec I2C slave Addr = %x\n", - __func__, client->addr); + dev_info(&client->dev, "%s:probe for other slaves\n" + "devices of codec I2C slave Addr = %x wsa_idx = %d\n", + __func__, client->addr, wsa881x_index); dev_dbg(&client->dev, "%s:wsa_idx = %d SLAVE = %d\n", __func__, wsa881x_index, WSA881X_ANALOG_SLAVE); pdata->regmap[WSA881X_ANALOG_SLAVE] = @@ -1402,6 +1414,7 @@ static int wsa881x_i2c_probe(struct i2c_client *client, client->dev.platform_data = pdata; i2c_set_clientdata(client, pdata); pdata->client[WSA881X_ANALOG_SLAVE] = client; + pdata->regmap_flag = true; if (pdata->version == WSA881X_2_0) wsa881x_update_regmap_2_0( pdata->regmap[WSA881X_ANALOG_SLAVE], @@ -1467,7 +1480,6 @@ static int wsa881x_i2c_probe(struct i2c_client *client, goto err; } pdata->client[WSA881X_DIGITAL_SLAVE] = client; - pdata->regmap_flag = true; ret = check_wsa881x_presence(client); if (ret < 0) { dev_err(&client->dev, @@ -1551,6 +1563,8 @@ static int wsa881x_i2c_probe(struct i2c_client *client, component->name_prefix = pdata->wsa881x_name_prefix; pdata->status = WSA881X_STATUS_I2C; + dev_info(&client->dev, "%s:pdata status changed to I2C\n", + __func__); goto err1; } err_mem: diff --git a/asoc/codecs/wsa881x-temp-sensor.h b/asoc/codecs/wsa881x-temp-sensor.h index fbb5941aba..483560db2b 100644 --- a/asoc/codecs/wsa881x-temp-sensor.h +++ b/asoc/codecs/wsa881x-temp-sensor.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2018, 2020 The Linux Foundation. All rights reserved. */ #ifndef WSA881X_TEMP_SENSOR_H #define WSA881X_TEMP_SENSOR_H @@ -29,7 +29,13 @@ struct wsa881x_tz_priv { int curr_temp; }; -int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp); +#ifndef CONFIG_WSA881X_TEMP_SENSOR_DISABLE int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata); void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev); +int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp); +#else +int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata){ return 0; } +void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev){} +int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp){ return 0; } +#endif #endif diff --git a/asoc/holi-port-config.h b/asoc/holi-port-config.h index abc23596a6..d22c4ced93 100644 --- a/asoc/holi-port-config.h +++ b/asoc/holi-port-config.h @@ -33,9 +33,19 @@ static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = { {0x18F, 0, 0, 0x8, 0x8, 0x0F, 0x00, 0, 0, 0x00, 0x01}, /* PCM_OUT */ }; +/* Headset(44.1K) + PCM Haptics */ +static struct port_params rx_frame_params_44p1KHz[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */ + {63, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x00}, /* HPH_CLH */ + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x00}, /* HPH_CMP */ + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0, 0x00, 0x00}, /* LO/AUX */ + {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0x00, 0x00}, /* DSD */ + {0x1FF, 0, 0, 0x8, 0x8, 0x0F, 0, 0, 0, 0x00, 0x01}, /* PCM_OUT */ +}; + /* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */ -static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = { - {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ +static struct port_params tx_frame_params_4p8MHz[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */ {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */ }; @@ -47,15 +57,17 @@ static struct port_params tx_frame_params_wcd937x[SWR_MSTR_PORT_LEN] = { }; static struct swr_mstr_port_map sm_port_map[] = { - {VA_MACRO, SWR_UC0, tx_frame_params_default}, + {VA_MACRO, SWR_UC0, tx_frame_params_4p8MHz}, {RX_MACRO, SWR_UC0, rx_frame_params_default}, {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, + {RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz}, }; static struct swr_mstr_port_map sm_port_map_wcd937x[] = { {VA_MACRO, SWR_UC0, tx_frame_params_wcd937x}, {RX_MACRO, SWR_UC0, rx_frame_params_default}, {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, + {RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz}, }; #endif /* _HOLI_PORT_CONFIG */ diff --git a/asoc/holi.c b/asoc/holi.c index 8c3bdbf24d..04d2c2ddf8 100644 --- a/asoc/holi.c +++ b/asoc/holi.c @@ -4343,7 +4343,8 @@ err: static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) { - (void)substream; + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); qos_client_active_cnt++; if (qos_client_active_cnt == 1) diff --git a/asoc/lahaina-port-config.h b/asoc/lahaina-port-config.h index d02813d676..5f508691c8 100755 --- a/asoc/lahaina-port-config.h +++ b/asoc/lahaina-port-config.h @@ -44,6 +44,16 @@ static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = { {0x18F, 0, 0, 0x8, 0x8, 0x0F, 0x00, 0, 0, 0x00, 0x01}, /* PCM_OUT */ }; +/* Headset(44.1K) + PCM Haptics */ +static struct port_params rx_frame_params_44p1KHz[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */ + {63, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x00}, /* HPH_CLH */ + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x00}, /* HPH_CMP */ + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0, 0x00, 0x00}, /* LO/AUX */ + {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0x00, 0x00}, /* DSD */ + {0x1FF, 0, 0, 0x8, 0x8, 0x0F, 0, 0, 0, 0x00, 0x01}, /* PCM_OUT */ +}; + /* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */ static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = { {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ @@ -92,6 +102,7 @@ static struct swr_mstr_port_map sm_port_map[] = { {TX_MACRO, SWR_UC2, tx_frame_params_0p6MHz}, {RX_MACRO, SWR_UC0, rx_frame_params_default}, {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, + {RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz}, {WSA_MACRO, SWR_UC0, wsa_frame_params_default}, }; @@ -101,6 +112,7 @@ static struct swr_mstr_port_map sm_port_map_shima[] = { {TX_MACRO, SWR_UC2, tx_frame_params_shima_0p6MHz}, {RX_MACRO, SWR_UC0, rx_frame_params_default}, {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, + {RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz}, {WSA_MACRO, SWR_UC0, wsa_frame_params_default}, }; diff --git a/asoc/lahaina.c b/asoc/lahaina.c index 151db1dd1c..b6f47be14c 100644 --- a/asoc/lahaina.c +++ b/asoc/lahaina.c @@ -73,6 +73,7 @@ struct msm_asoc_mach_data { struct clk *lpass_audio_hw_vote; int core_audio_vote_count; u32 wsa_max_devs; + int wcd_disabled; }; static bool is_initial_boot; @@ -84,8 +85,8 @@ static int dmic_4_5_gpio_cnt; static void *def_wcd_mbhc_cal(void); -static int msm_aux_codec_init(struct snd_soc_pcm_runtime*); -static int msm_int_audrx_init(struct snd_soc_pcm_runtime*); +static int msm_rx_tx_codec_init(struct snd_soc_pcm_runtime*); +static int msm_int_wsa_init(struct snd_soc_pcm_runtime*); /* * Need to report LINEIN @@ -489,7 +490,7 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { .ignore_suspend = 1, .ops = &msm_common_be_ops, SND_SOC_DAILINK_REG(wsa_dma_rx0), - .init = &msm_int_audrx_init, + .init = &msm_int_wsa_init, }, { .name = LPASS_BE_WSA_CDC_DMA_RX_1, @@ -526,7 +527,7 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { .ignore_suspend = 1, .ops = &msm_common_be_ops, SND_SOC_DAILINK_REG(rx_dma_rx0), - .init = &msm_aux_codec_init, + .init = &msm_rx_tx_codec_init, }, { .name = LPASS_BE_RX_CDC_DMA_RX_1, @@ -538,7 +539,6 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { .ignore_suspend = 1, .ops = &msm_common_be_ops, SND_SOC_DAILINK_REG(rx_dma_rx1), - .init = &msm_int_audrx_init, }, { .name = LPASS_BE_RX_CDC_DMA_RX_2, @@ -758,7 +758,7 @@ static int msm_populate_dai_link_component_of_node( np = dai_link[i].codecs[j].of_node; if (!of_device_is_available(np)) { - dev_err(cdev, "%s: codec is disabled: %s\n", + dev_dbg(cdev, "%s: codec is disabled: %s\n", __func__, np->full_name); dai_link[i].codecs[j].of_node = NULL; @@ -856,9 +856,17 @@ static int msm_snd_card_late_probe(struct snd_soc_card *card) struct snd_soc_component *component = NULL; const char *be_dl_name = LPASS_BE_RX_CDC_DMA_RX_0; struct snd_soc_pcm_runtime *rtd; + struct msm_asoc_mach_data *pdata; int ret = 0; void *mbhc_calibration; + pdata = snd_soc_card_get_drvdata(card); + if (!pdata) + return -EINVAL; + + if (pdata->wcd_disabled) + return 0; + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); if (!rtd) { dev_err(card->dev, @@ -992,7 +1000,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) return card; } -static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) +static int msm_int_wsa_init(struct snd_soc_pcm_runtime *rtd) { u8 spkleft_ports[WSA883X_MAX_SWR_PORTS] = {0, 1, 2, 3}; u8 spkright_ports[WSA883X_MAX_SWR_PORTS] = {0, 1, 2, 3}; @@ -1005,43 +1013,34 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) unsigned int ch_mask[WSA883X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; struct snd_soc_component *component = NULL; struct snd_soc_dapm_context *dapm = NULL; - struct snd_card *card = NULL; - struct snd_info_entry *entry = NULL; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); - int ret = 0; - - if (codec_reg_done) { - return 0; - } + int wsa_active_devs = 0; if (pdata->wsa_max_devs > 0) { - component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.1"); - if (!component) { - pr_err("%s: wsa-codec.1 component is NULL\n", __func__); - return -EINVAL; - } + component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.1"); + if (component) { + dapm = snd_soc_component_get_dapm(component); - dapm = snd_soc_component_get_dapm(component); + wsa883x_set_channel_map(component, &spkleft_ports[0], + WSA883X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], &spkleft_port_types[0]); - wsa883x_set_channel_map(component, &spkleft_ports[0], - WSA883X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0], &spkleft_port_types[0]); - - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "spkrLeft IN"); - snd_soc_dapm_ignore_suspend(dapm, "spkrLeft SPKR"); - } - - wsa883x_codec_info_create_codec_entry(pdata->codec_root, - component); - } + wsa883x_codec_info_create_codec_entry(pdata->codec_root, + component); + wsa_active_devs++; + } else { + pr_info("%s: wsa-codec.1 component is NULL\n", __func__); + } + } /* If current platform has more than one WSA */ - if (pdata->wsa_max_devs > 1) { + if (pdata->wsa_max_devs > wsa_active_devs) { component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.2"); if (!component) { pr_err("%s: wsa-codec.2 component is NULL\n", __func__); + pr_err("%s: %d WSA is found. Expect %d WSA.", + __func__, wsa_active_devs, pdata->wsa_max_devs); return -EINVAL; } @@ -1051,15 +1050,27 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) WSA883X_MAX_SWR_PORTS, &ch_mask[0], &ch_rate[0], &spkright_port_types[0]); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "spkrRight IN"); - snd_soc_dapm_ignore_suspend(dapm, "spkrRight SPKR"); - } - wsa883x_codec_info_create_codec_entry(pdata->codec_root, component); } + msm_common_dai_link_init(rtd); + return 0; +} + +static int msm_rx_tx_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *component = NULL; + struct snd_soc_dapm_context *dapm = NULL; + int ret = 0; + struct snd_info_entry *entry; + struct snd_card *card = NULL; + struct msm_asoc_mach_data *pdata; + + pdata = snd_soc_card_get_drvdata(rtd->card); + if(!pdata) + return -EINVAL; + component = snd_soc_rtdcom_lookup(rtd, "bolero_codec"); if (!component) { pr_err("%s: could not find component for bolero_codec\n", @@ -1103,28 +1114,17 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) if (!entry) { pr_debug("%s: Cannot create codecs module entry\n", __func__); - ret = 0; - goto err; + return 0; } pdata->codec_root = entry; } bolero_info_create_codec_entry(pdata->codec_root, component); bolero_register_wake_irq(component, false); - codec_reg_done = true; - msm_common_dai_link_init(rtd); - -err: - return ret; -} - -static int msm_aux_codec_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_component *component = NULL; - struct snd_soc_dapm_context *dapm = NULL; - struct snd_info_entry *entry; - struct snd_card *card = NULL; - struct msm_asoc_mach_data *pdata; + if (pdata->wcd_disabled) { + codec_reg_done = true; + return 0; + } component = snd_soc_rtdcom_lookup(rtd, WCD938X_DRV_NAME); if (!component) { pr_err("%s component is NULL\n", __func__); @@ -1143,17 +1143,6 @@ static int msm_aux_codec_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); snd_soc_dapm_sync(dapm); - pdata = snd_soc_card_get_drvdata(component->card); - if (!pdata->codec_root) { - entry = msm_snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - dev_dbg(component->dev, "%s: Cannot create codecs module entry\n", - __func__); - return 0; - } - pdata->codec_root = entry; - } wcd938x_info_create_codec_entry(pdata->codec_root, component); #if 0 @@ -1175,6 +1164,7 @@ static int msm_aux_codec_init(struct snd_soc_pcm_runtime *rtd) } #endif + codec_reg_done = true; msm_common_dai_link_init(rtd); return 0; } @@ -1306,6 +1296,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,lito-is-v2-enabled", &pdata->lito_v2_enabled); + of_property_read_u32(pdev->dev.of_node, + "qcom,wcd-disabled", + &pdata->wcd_disabled); + card = populate_snd_card_dailinks(&pdev->dev); if (!card) { dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); diff --git a/asoc/msm_dailink.h b/asoc/msm_dailink.h index a6bde216cc..0ec53d8c52 100644 --- a/asoc/msm_dailink.h +++ b/asoc/msm_dailink.h @@ -5,7 +5,6 @@ #include - SND_SOC_DAILINK_DEFS(usb_audio_rx, DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")), DAILINK_COMP_ARRAY(COMP_DUMMY()), @@ -182,3 +181,4 @@ SND_SOC_DAILINK_DEFS(tavil_i2s_tx1, DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")), DAILINK_COMP_ARRAY(COMP_CODEC("tavil_codec", "tavil_i2s_tx1")), DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy"))); + diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 8e439467be..80ac564ec3 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -178,6 +179,7 @@ struct dev_config { u32 sample_rate; u32 bit_format; u32 channels; + u32 data_format; }; struct msm_wsa881x_dev_info { @@ -206,6 +208,7 @@ struct msm_asoc_mach_data { u32 tdm_micb_voltage; u32 tdm_micb_current; bool codec_is_csra; + void __iomem *mi2s_dsd_mode[MI2S_MAX]; }; struct msm_asoc_wcd93xx_codec { @@ -478,6 +481,19 @@ static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", static const char *const vi_feed_ch_text[] = {"One", "Two"}; static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", "S32_LE"}; +static const char *const data_format_text[] = { + "LPCM", + "Compr", + "LPCM-60958", + "Compr-60958", + "NA4", + "NA5", + "NA6", + "NA7", + "NA8", + "DSD_DOP_W_MARKER", + "NATIVE_DSD_DATA" +}; static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", "KHZ_44P1", "KHZ_48", "KHZ_88P2", "KHZ_96", "KHZ_176P4", @@ -616,6 +632,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_data_format, data_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_data_format, data_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_meta_mi2s_rx_sample_rate, mi2s_rate_text); @@ -3251,7 +3269,8 @@ static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, return idx; /* check for PRIM_MI2S and CSRAx config to allow 24bit BE config only */ - if ((PRIM_MI2S == idx) && (true==pdata->codec_is_csra)) + if ((idx == PRIM_MI2S) && (pdata->codec_is_csra == true) + && mi2s_rx_cfg[idx].data_format != AFE_DSD_DATA) { mi2s_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; pr_debug("%s: Keeping default format idx[%d]_rx_format = %d, item = %d\n", @@ -3305,6 +3324,74 @@ static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_mi2s_tx_data_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].data_format = ucontrol->value.enumerated.item[0]; + + pr_debug("%s: idx[%d]_data_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].data_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_data_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].data_format = ucontrol->value.enumerated.item[0]; + + pr_debug("%s: idx[%d]_data_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].data_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_data_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].data_format; + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].data_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_data_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].data_format; + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].data_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + static int msm_meta_mi2s_get_port_idx(struct snd_kcontrol *kcontrol) { int idx = 0; @@ -4335,6 +4422,18 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("SEN_MI2S_TX Channels", sen_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX DataFormat", mi2s_tx_data_format, + msm_mi2s_tx_data_format_get, + msm_mi2s_tx_data_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX DataFormat", mi2s_tx_data_format, + msm_mi2s_tx_data_format_get, + msm_mi2s_tx_data_format_put), + SOC_ENUM_EXT("PRIM_MI2S_RX DataFormat", mi2s_rx_data_format, + msm_mi2s_rx_data_format_get, + msm_mi2s_rx_data_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX DataFormat", mi2s_rx_data_format, + msm_mi2s_rx_data_format_get, + msm_mi2s_rx_data_format_put), SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, @@ -6349,7 +6448,7 @@ static struct snd_soc_ops msm_fe_qos_ops = { static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) { - int ret = 0; + int ret = 0, val = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai_link *dai_link = rtd->dai_link; @@ -6357,6 +6456,12 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int data_format; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + data_format = mi2s_rx_cfg[index].data_format; + else + data_format = mi2s_tx_cfg[index].data_format; dev_dbg(rtd->card->dev, "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", @@ -6382,6 +6487,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; fmt = SND_SOC_DAIFMT_CBM_CFM; } + + if (data_format == AFE_DSD_DATA) + fmt = SND_SOC_DAIFMT_CBM_CFS; ret = msm_mi2s_set_sclk(substream, true); if (ret < 0) { dev_err(rtd->card->dev, @@ -6396,9 +6504,34 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, index, ret); goto clk_off; } - if (pdata->mi2s_gpio_p[index]) - msm_cdc_pinctrl_select_active_state( + + if (pdata->mi2s_gpio_p[index]) { + if ((data_format == AFE_DSD_DATA) && + ((index == QUAT_MI2S) || + (index == PRIM_MI2S))) { + msm_cdc_pinctrl_select_alt_active_state( + pdata->mi2s_gpio_p[index]); + } else { + msm_cdc_pinctrl_select_active_state( pdata->mi2s_gpio_p[index]); + } + } + + if (index == QUAT_MI2S || index == PRIM_MI2S) { + switch (data_format) { + case AFE_DSD_DATA: + if (pdata->mi2s_dsd_mode[index]) { + val = ioread32( + pdata->mi2s_dsd_mode[index]); + val = val | 0x1; + iowrite32(val, + pdata->mi2s_dsd_mode[index]); + } + break; + default: + break; + } + } } ret = qcs405_send_island_vad_config(dai_link->id); @@ -6452,11 +6585,18 @@ static int msm_mi2s_snd_hw_free(struct snd_pcm_substream *substream) static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) { int ret; + int val; + int data_format; struct snd_soc_pcm_runtime *rtd = substream->private_data; int index = rtd->cpu_dai->id; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + data_format = mi2s_rx_cfg[index].data_format; + else + data_format = mi2s_tx_cfg[index].data_format; + pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); if (index < PRIM_MI2S || index >= MI2S_MAX) { @@ -6470,6 +6610,22 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) msm_cdc_pinctrl_select_sleep_state( pdata->mi2s_gpio_p[index]); + if (index == QUAT_MI2S || index == PRIM_MI2S) { + switch (data_format) { + case AFE_DSD_DATA: + if (pdata->mi2s_dsd_mode[index]) { + val = ioread32( + pdata->mi2s_dsd_mode[index]); + val = val & ~1; + iowrite32(val, + pdata->mi2s_dsd_mode[index]); + } + break; + default: + break; + } + } + ret = msm_mi2s_set_sclk(substream, false); if (ret < 0) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", @@ -9750,6 +9906,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) const char *micb_supply_str1 = "tdm-vdd-micb"; const char *micb_voltage_str = "qcom,tdm-vdd-micb-voltage"; const char *micb_current_str = "qcom,tdm-vdd-micb-current"; + u32 v_base_addr; if (!pdev->dev.of_node) { dev_err(&pdev->dev, "No platform supplied from device tree\n"); @@ -9761,6 +9918,31 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (!pdata) return -ENOMEM; + ret = of_property_read_u32( + pdev->dev.of_node, "tcsr_i2s_dsd_prim", &v_base_addr); + if (ret) { + dev_err(&pdev->dev, "MUX addr invalid for MI2S dsd prim\n"); + } else { + pdata->mi2s_dsd_mode[PRIM_MI2S] = + devm_ioremap(&pdev->dev, v_base_addr, 4); + if (pdata->mi2s_dsd_mode[PRIM_MI2S] == NULL) { + pr_err("%s ioremap failure for muxsel virt addr dsd prim\n", + __func__); + } + } + ret = of_property_read_u32( + pdev->dev.of_node, "tcsr_i2s_dsd_quat", &v_base_addr); + if (ret) { + dev_err(&pdev->dev, "MUX addr invalid for MI2S dsd quat\n"); + } else { + pdata->mi2s_dsd_mode[QUAT_MI2S] = + devm_ioremap(&pdev->dev, v_base_addr, 4); + if (pdata->mi2s_dsd_mode[QUAT_MI2S] == NULL) { + pr_err("%s ioremap failure for muxsel virt addr dsd quat\n", + __func__); + } + } + /* test for ep92 HDMI bridge and update dai links accordingly */ ret = msm_detect_ep92_dev(pdev, card); if (ret) diff --git a/config/holiauto.conf b/config/holiauto.conf index e46212b20f..d0d6dd0456 100644 --- a/config/holiauto.conf +++ b/config/holiauto.conf @@ -29,6 +29,7 @@ export CONFIG_SND_SOC_WCD938X_SLAVE=m export CONFIG_SND_SOC_WCD937X=m export CONFIG_SND_SOC_WCD937X_SLAVE=m export CONFIG_SND_SOC_WSA881X_ANALOG=m +export CONFIG_WSA881X_TEMP_SENSOR_DISABLE=m export CONFIG_SND_SOC_HOLI=m export CONFIG_SND_EVENT=m export CONFIG_TDM_DISABLE=m diff --git a/config/holiautoconf.h b/config/holiautoconf.h index b1758be036..2eb9a6d5a4 100644 --- a/config/holiautoconf.h +++ b/config/holiautoconf.h @@ -33,6 +33,7 @@ #define CONFIG_SND_SOC_WCD937X 1 #define CONFIG_SND_SOC_WCD937X_SLAVE 1 #define CONFIG_SND_SOC_WSA881X_ANALOG 1 +#define CONFIG_WSA881X_TEMP_SENSOR_DISABLE 1 #define CONFIG_SND_SOC_HOLI 1 #define CONFIG_SND_EVENT 1 #define CONFIG_TDM_DISABLE 1 diff --git a/config/lahainaauto.conf b/config/lahainaauto.conf index 00465fb3fd..90bbd80fbb 100644 --- a/config/lahainaauto.conf +++ b/config/lahainaauto.conf @@ -38,3 +38,4 @@ export CONFIG_AUDIO_PKT_ION=m export CONFIG_MSM_QDSP6_GPR_RPMSG=m export CONFIG_AUDIO_PKT=m export CONFIG_DIGITAL_CDC_RSC_MGR=m +export CONFIG_AUXPCM_DISABLE=m diff --git a/config/lahainaautoconf.h b/config/lahainaautoconf.h index 303624e3e9..e830620a9a 100644 --- a/config/lahainaautoconf.h +++ b/config/lahainaautoconf.h @@ -42,3 +42,4 @@ #define CONFIG_MSM_QDSP6_GPR_RPMSG 1 #define CONFIG_AUDIO_PKT 1 #define CONFIG_DIGITAL_CDC_RSC_MGR 1 +#define CONFIG_AUXPCM_DISABLE 1 diff --git a/config/sa8155auto.conf b/config/sa8155auto.conf index bf5b9cdae1..e6506760a4 100644 --- a/config/sa8155auto.conf +++ b/config/sa8155auto.conf @@ -13,3 +13,4 @@ CONFIG_SND_SOC_MSM_STUB=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m CONFIG_MSM_QDSP6V2_CODECS=m CONFIG_SND_EVENT=m +CONFIG_SND_SOC_SA8155=m diff --git a/config/sa8155autoconf.h b/config/sa8155autoconf.h index 167451639a..7470fc6b5c 100644 --- a/config/sa8155autoconf.h +++ b/config/sa8155autoconf.h @@ -17,3 +17,4 @@ #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 #define CONFIG_MSM_QDSP6V2_CODECS 1 #define CONFIG_SND_EVENT 1 +#define CONFIG_SND_SOC_SA8155 1 diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 8682585316..495648fb26 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -132,7 +132,7 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, bool cma_mem) { - struct msm_audio_alloc_data *alloc_data; + struct msm_audio_alloc_data *alloc_data = NULL; struct device *cb_dev; unsigned long ionflag = 0; int rc = 0; @@ -214,6 +214,7 @@ detach_dma_buf: alloc_data->attach); free_alloc_data: kfree(alloc_data); + alloc_data = NULL; return rc; } @@ -255,6 +256,7 @@ static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf, bool cma_mem) list_del(&(alloc_data->list)); kfree(alloc_data); + alloc_data = NULL; break; } } @@ -361,6 +363,11 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, int rc = 0; bool is_iova = true; + if (!dma_buf || !paddr || !vaddr || !plen) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + rc = msm_audio_ion_get_phys(dma_buf, paddr, plen, is_iova); if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", diff --git a/dsp/msm_audio_ion_vm.c b/dsp/msm_audio_ion_vm.c index 2cf2861d9f..34bf0a2284 100644 --- a/dsp/msm_audio_ion_vm.c +++ b/dsp/msm_audio_ion_vm.c @@ -562,12 +562,18 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, pr_err("%s: Invalid params\n", __func__); return -EINVAL; } - + pr_debug("%s: audio heap is used\n", __func__); if (msm_audio_ion_data.smmu_enabled == true) { - pr_debug("%s: system heap is used\n", __func__); - *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0); + *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0); + if (IS_ERR_OR_NULL((void *)(*dma_buf))) { + if (IS_ERR((void *)(*dma_buf))) + err_ion_ptr = PTR_ERR((int *)(*dma_buf)); + pr_debug("%s: ION alloc failed for audio heap err ptr=%ld, smmu_enabled=%d," + "trying system heap..\n", + __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled); + *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0); + } } else { - pr_debug("%s: audio heap is used\n", __func__); *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0); } if (IS_ERR_OR_NULL((void *)(*dma_buf))) { diff --git a/include/asoc/wcd-mbhc-v2.h b/include/asoc/wcd-mbhc-v2.h index e9dd2ae165..1c351f8012 100644 --- a/include/asoc/wcd-mbhc-v2.h +++ b/include/asoc/wcd-mbhc-v2.h @@ -551,7 +551,6 @@ struct wcd_mbhc { wait_queue_head_t wait_btn_press; bool is_btn_press; u8 current_plug; - u8 plug_before_ssr; bool in_swch_irq_handler; bool hphl_swh; /*track HPHL switch NC / NO */ bool gnd_swh; /*track GND switch NC / NO */ diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 1d6d3debcc..87173c79da 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -4103,6 +4103,9 @@ struct afe_id_aptx_adaptive_enc_init /* Macro for defining the packetizer ID: COP. */ #define AFE_MODULE_ID_PACKETIZER_COP 0x0001322A +/* Macro for defining the packetizer ID: COP V2 */ +#define AFE_MODULE_ID_PACKETIZER_COP_V2 0x000132F9 + /* * Packetizer type parameter for the #AVS_MODULE_ID_ENCODER module. * This parameter cannot be set runtime. @@ -4168,6 +4171,7 @@ struct afe_id_aptx_adaptive_enc_init */ #define AFE_MODULE_ID_DEPACKETIZER_COP 0x00013233 #define AFE_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9 +#define AFE_MODULE_ID_DEPACKETIZER_COP_V2 0x000132FC /* Macros for dynamic loading of modules by AVCS */ @@ -4175,10 +4179,22 @@ struct afe_id_aptx_adaptive_enc_init #define AVS_MODULE_ID_PACKETIZER_COP_V1 0x000132E8 +#define AVS_MODULE_ID_PACKETIZER_COP_V2 0x000132F9 + #define AVS_MODULE_ID_DEPACKETIZER_COP 0x00013233 #define AVS_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9 +#define AVS_MODULE_ID_DEPACKETIZER_COP_V2 0x000132FC + +/* + * Depacketizer and packetizer type parameter for the + * #AVS_MODULE_ID_DEPACKETIZER_COP_V2 module and + * #AVS_MODULE_ID_PACKETIZER_COP_V2 module. + */ + +#define AVS_COP_V2_PARAM_ID_STREAM_INFO 0x000132FD + /* * Depacketizer type parameter for the #AVS_MODULE_ID_DECODER module. * This parameter cannot be set runtime. @@ -4192,6 +4208,12 @@ struct afe_id_aptx_adaptive_enc_init struct aptx_channel_mode_param_t { u32 channel_mode; } __packed; + +#define CAPI_V2_PARAM_SET_LC3_ENC_DOWNMIX_2_MONO 0x00013384 +struct lc3_channel_mode_param_t { + u32 channel_mode; +} __packed; + /* * Decoder buffer ID parameter for the #AVS_MODULE_ID_DECODER module. * This parameter cannot be set runtime. @@ -4410,6 +4432,10 @@ struct asm_aac_enc_cfg_t { /* FMT ID for apt-X Adaptive speech */ #define ASM_MEDIA_FMT_APTX_AD_SPEECH 0x00013208 +/* FMT ID for lc3 codec */ +#define ASM_MEDIA_FMT_LC3 0x0001337E +#define ENC_CODEC_TYPE_LC3 0x2B000000 + #define PCM_CHANNEL_L 1 #define PCM_CHANNEL_R 2 #define PCM_CHANNEL_C 3 @@ -4470,6 +4496,70 @@ struct asm_aptx_ad_speech_enc_cfg_t struct asm_aptx_ad_speech_mode_cfg_t speech_mode; } __attribute__ ((packed)); + +#define CAPI_V2_PARAM_LC3_ENC_INIT 0x00013381 +#define CAPI_V2_PARAM_LC3_DEC_MODULE_INIT 0x00013391 +struct afe_lc3_stream_map_t { + uint32_t stream_id; + uint32_t direction; + uint32_t channel_mask_lsw; + uint32_t channel_mask_msw; +} __packed; + +struct afe_stream_map_t { + uint32_t audio_location; + uint8_t stream_id; + uint8_t direction; +} __packed; + +struct afe_lc3_cfg_t { + uint32_t api_version; + uint32_t sampling_freq; + uint32_t max_octets_per_frame; + uint32_t frame_duration; + uint32_t bit_depth; + uint32_t num_blocks; + uint8_t default_q_level; + uint8_t vendor_specific[16]; + uint32_t mode; +} __packed; + +struct afe_lc3_enc_cfg_t { + struct afe_lc3_cfg_t toAirConfig; + uint32_t stream_map_size; + struct afe_stream_map_t streamMapOut[16]; +} __packed; + +struct afe_lc3_dec_cfg_t { + struct afe_lc3_cfg_t FromAir; + uint32_t decoder_output_channel; + uint32_t stream_map_size; + struct afe_stream_map_t streamMapIn[16]; +} __packed; + +struct avs_cop_v2_param_id_stream_info_t { + uint32_t stream_map_size; + struct afe_lc3_stream_map_t streamMap[16]; +} __packed; + +struct afe_lc3_dec_config_t { + struct avs_cop_v2_param_id_stream_info_t streamMapToAir; +} __packed; + +struct afe_lc3_enc_config_t { + struct afe_lc3_enc_cfg_t to_Air_cfg; + struct avs_cop_v2_param_id_stream_info_t streamMapToAir; +} __packed; + +struct asm_enc_lc3_cfg_t { + struct afe_imc_dec_enc_info imc_info; + struct afe_lc3_enc_config_t enc_codec; +} __packed; + +struct asm_lc3_dec_cfg_t { + struct afe_lc3_dec_config_t dec_codec; +} __packed; + struct afe_matched_port_t { uint32_t minor_version; @@ -4765,12 +4855,14 @@ union afe_enc_config_data { struct asm_ldac_enc_cfg_t ldac_config; struct asm_aptx_ad_enc_cfg_t aptx_ad_config; struct asm_aptx_ad_speech_enc_cfg_t aptx_ad_speech_config; + struct asm_enc_lc3_cfg_t lc3_enc_config; }; struct afe_enc_config { u32 format; u32 scrambler_mode; u32 mono_mode; + u32 lc3_mono_mode; union afe_enc_config_data data; }; @@ -4830,6 +4922,7 @@ union afe_dec_config_data { struct asm_mp3_dec_cfg_t mp3_config; struct asm_aptx_ad_dec_cfg_t aptx_ad_config; struct asm_aptx_ad_speech_dec_cfg_t aptx_ad_speech_config; + struct asm_lc3_dec_cfg_t lc3_dec_config; }; struct afe_dec_config { diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h index 0ef02ef7e8..2003e76fe1 100644 --- a/include/dsp/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -95,5 +95,7 @@ int32_t cal_utils_get_cal_type_version(void *cal_type_data); void cal_utils_mark_cal_used(struct cal_block_data *cal_block); -bool cal_utils_is_cal_stale(struct cal_block_data *cal_block); +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type); + +int cal_utils_init(void); #endif diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index 2d9b64aaaa..a8c5ec83e9 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -17,7 +17,7 @@ #define SWR_CLK_RATE_2P4MHZ 2400000 #define SWR_CLK_RATE_4P8MHZ 4800000 #define SWR_CLK_RATE_9P6MHZ 9600000 -#define SWR_CLK_RATE_11P2896MHZ 1128960 +#define SWR_CLK_RATE_11P2896MHZ 11289600 extern struct bus_type soundwire_type; struct swr_device; diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 700826e504..c4c76acf1a 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -148,16 +149,19 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) { int ret = 0; struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev); + static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1); if (!lpi_dev_up) { - pr_err_ratelimited("%s: ADSP is down due to SSR, return\n", + if (__ratelimit(&rtl)) + pr_err("%s: ADSP is down due to SSR, return\n", __func__); return 0; } pm_runtime_get_sync(lpi_dev); mutex_lock(&state->core_hw_vote_lock); if (!state->core_hw_vote_status) { - pr_err_ratelimited("%s: core hw vote clk is not enabled\n", + if (__ratelimit(&rtl)) + pr_err("%s: core hw vote clk is not enabled\n", __func__); ret = -EINVAL; goto err; @@ -179,6 +183,7 @@ static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr, { struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev); int ret = 0; + static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1); if (!lpi_dev_up) { return 0; @@ -186,7 +191,8 @@ static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr, pm_runtime_get_sync(lpi_dev); mutex_lock(&state->core_hw_vote_lock); if (!state->core_hw_vote_status) { - pr_err_ratelimited("%s: core hw vote clk is not enabled\n", + if (__ratelimit(&rtl)) + pr_err("%s: core hw vote clk is not enabled\n", __func__); ret = -EINVAL; goto err; diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 477474d2ed..098070febe 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -752,6 +752,9 @@ static int swrm_get_port_config(struct swr_mstr_ctrl *swrm) if (swrm->mport_cfg[SWRM_DSD_PARAMS_PORT].port_en && (swrm->master_id == MASTER_ID_RX)) usecase = 1; + else if ((swrm->master_id == MASTER_ID_RX) && + (swrm->bus_clk == SWR_CLK_RATE_11P2896MHZ)) + usecase = 2; if (swrm->bus_clk == SWR_CLK_RATE_4P8MHZ) usecase = 1; @@ -2748,6 +2751,11 @@ static int swrm_probe(struct platform_device *pdev) } devm_kfree(&pdev->dev, temp); + ret = of_property_read_u32(pdev->dev.of_node, "qcom,is-always-on", + &swrm->is_always_on); + if (ret) + dev_dbg(&pdev->dev, "%s: failed to get is_always_on flag\n", __func__); + swrm->reg_irq = pdata->reg_irq; swrm->master.read = swrm_read; swrm->master.write = swrm_write; @@ -2870,7 +2878,7 @@ static int swrm_probe(struct platform_device *pdev) * controller will be up now */ swr_master_add_boarddevices(&swrm->master); - if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) + if (!swrm->is_always_on && swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) dev_dbg(&pdev->dev, "%s: Audio HW Vote is failed\n", __func__); mutex_lock(&swrm->mlock); swrm_clk_request(swrm, true); @@ -3018,7 +3026,7 @@ static int swrm_runtime_resume(struct device *dev) struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; bool swrm_clk_req_err = false; - bool hw_core_err = false; + bool hw_core_err = false, aud_core_err = false; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; u32 temp = 0; @@ -3034,9 +3042,11 @@ static int swrm_runtime_resume(struct device *dev) __func__); hw_core_err = true; } - if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) + if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { dev_err(dev, "%s:lpass audio hw enable failed\n", __func__); + aud_core_err = true; + } if ((swrm->state == SWR_MSTR_DOWN) || (swrm->state == SWR_MSTR_SSR && swrm->dev_up)) { @@ -3128,6 +3138,9 @@ static int swrm_runtime_resume(struct device *dev) swrm->state = SWR_MSTR_UP; } exit: + if (swrm->is_always_on && !aud_core_err) + swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); + if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); if (swrm_clk_req_err) @@ -3150,7 +3163,7 @@ static int swrm_runtime_suspend(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; - bool hw_core_err = false; + bool hw_core_err = false, aud_core_err = false; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; int current_state = 0; @@ -3170,6 +3183,8 @@ static int swrm_runtime_suspend(struct device *dev) hw_core_err = true; } + if (swrm->is_always_on && swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) + aud_core_err = true; if ((current_state == SWR_MSTR_UP) || (current_state == SWR_MSTR_SSR)) { @@ -3236,7 +3251,9 @@ static int swrm_runtime_suspend(struct device *dev) } if (swrm->clk_stop_mode0_supp) { - if (swrm->wake_irq > 0) { + if ((swrm->wake_irq > 0) && + (irqd_irq_disabled( + irq_get_irq_data(swrm->wake_irq)))) { enable_irq(swrm->wake_irq); } else if (swrm->ipc_wakeup) { //msm_aud_evt_blocking_notifier_call_chain( @@ -3252,11 +3269,13 @@ static int swrm_runtime_suspend(struct device *dev) swrm->state = SWR_MSTR_DOWN; exit: - if (swrm->state != SWR_MSTR_UP) { + if (!swrm->is_always_on && swrm->state != SWR_MSTR_UP) { if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false)) dev_dbg(dev, "%s:lpass audio hw enable failed\n", __func__); - } + } else if (swrm->is_always_on && !aud_core_err) + swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); + if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 8aa0d013bb..40223c4a3b 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -194,6 +194,7 @@ struct swr_mstr_ctrl { u32 wr_fifo_depth; bool enable_slave_irq; u64 logical_dev[SWRM_NUM_AUTO_ENUM_SLAVES]; + u32 is_always_on; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_swrm_dent; struct dentry *debugfs_peek;