Merge commit 'd9fa9d435ba1b92cf0f0361a0749107b7abc45a5' into audio-kernel-5-4.lnx.1.0

Change-Id: Iaf98532030ee4ef5fe6a70df083a685733dd5670
This commit is contained in:
Phani Kumar Uppalapati
2020-11-05 18:35:53 -08:00
34 changed files with 618 additions and 227 deletions

View File

@@ -31,7 +31,6 @@ export
endif endif
endif endif
# Use USERINCLUDE when you must reference the UAPI directories only. # Use USERINCLUDE when you must reference the UAPI directories only.
USERINCLUDE += \ USERINCLUDE += \
-I$(srctree)/techpack/audio/include/uapi/audio -I$(srctree)/techpack/audio/include/uapi/audio

View File

@@ -169,8 +169,10 @@ ifdef CONFIG_SND_SOC_WSA881X_ANALOG
WSA881X_ANALOG_OBJS += wsa881x-analog.o WSA881X_ANALOG_OBJS += wsa881x-analog.o
WSA881X_ANALOG_OBJS += wsa881x-tables-analog.o WSA881X_ANALOG_OBJS += wsa881x-tables-analog.o
WSA881X_ANALOG_OBJS += wsa881x-regmap-analog.o WSA881X_ANALOG_OBJS += wsa881x-regmap-analog.o
ifndef CONFIG_WSA881X_TEMP_SENSOR_DISABLE
WSA881X_ANALOG_OBJS += wsa881x-temp-sensor.o WSA881X_ANALOG_OBJS += wsa881x-temp-sensor.o
endif endif
endif
ifdef CONFIG_SND_SOC_MSM_STUB ifdef CONFIG_SND_SOC_MSM_STUB
STUB_OBJS += msm_stub.o STUB_OBJS += msm_stub.o
endif endif

View File

@@ -15,6 +15,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <dsp/apr_audio-v2.h> #include <dsp/apr_audio-v2.h>
#include <dt-bindings/clock/qcom,audio-ext-clk.h> #include <dt-bindings/clock/qcom,audio-ext-clk.h>
#include <linux/ratelimit.h>
#ifdef CONFIG_AUDIO_PRM #ifdef CONFIG_AUDIO_PRM
#include <dsp/audio_prm.h> #include <dsp/audio_prm.h>
#else #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 audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info; struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info;
int ret; int ret;
static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) && if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) &&
(clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX) && !clk_priv->clk_cfg.enable) { (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); ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
#endif #endif
if (ret < 0) { 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__); __func__);
return ret; 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 audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info; struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info;
int ret; int ret;
static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
if (pnctrl_info->pinctrl) { if (pnctrl_info->pinctrl) {
ret = pinctrl_select_state(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 #else
ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
#endif #endif
if (ret < 0) if (ret < 0) {
pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n", if (__ratelimit(&rtl))
pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n",
__func__, ret); __func__, ret);
}
} }
if (pnctrl_info->base) 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) 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) { if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) {
#ifdef CONFIG_AUDIO_PRM #ifdef CONFIG_AUDIO_PRM
pr_debug("%s: clk_id %d ",__func__, clk_priv->prm_clk_cfg.clk_id); 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); &clk_priv->lpass_audio_hwvote_client_handle);
#endif #endif
if (ret < 0) { 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); __func__, ret);
return ret; return ret;
} }

View File

@@ -15,6 +15,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <soc/swr-common.h> #include <soc/swr-common.h>
#include <dsp/digital-cdc-rsc-mgr.h> #include <dsp/digital-cdc-rsc-mgr.h>
#include <linux/ratelimit.h>
#include "bolero-cdc.h" #include "bolero-cdc.h"
#include "internal.h" #include "internal.h"
#include "bolero-clk-rsc.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; bolero_reg_access[VA_MACRO] = bolero_va_reg_access_v3;
} }
BLOCKING_INIT_NOTIFIER_HEAD(&priv->notifier);
priv->dev = &pdev->dev; priv->dev = &pdev->dev;
priv->dev_up = true; priv->dev_up = true;
priv->initial_boot = 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); struct bolero_priv *priv = dev_get_drvdata(dev->parent);
int ret = 0; int ret = 0;
static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
mutex_lock(&priv->vote_lock); mutex_lock(&priv->vote_lock);
if (priv->lpass_core_hw_vote == NULL) { if (priv->lpass_core_hw_vote == NULL) {
@@ -1472,8 +1475,9 @@ audio_vote:
if (priv->core_audio_vote_count == 0) { if (priv->core_audio_vote_count == 0) {
ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_audio_hw_vote); ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_audio_hw_vote);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "%s:lpass audio hw enable failed\n", if (__ratelimit(&rtl))
__func__); dev_err(dev, "%s:lpass audio hw enable failed\n",
__func__);
goto done; goto done;
} }
} }

View File

@@ -11,6 +11,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/ratelimit.h>
#include "bolero-cdc.h" #include "bolero-cdc.h"
#include "bolero-clk-rsc.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) bool enable)
{ {
int ret = 0; int ret = 0;
static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
if (enable) { if (enable) {
/* Enable Requested Core clk */ /* Enable Requested Core clk */
if (priv->clk_cnt[clk_id] == 0) { if (priv->clk_cnt[clk_id] == 0) {
ret = clk_prepare_enable(priv->clk[clk_id]); ret = clk_prepare_enable(priv->clk[clk_id]);
if (ret < 0) { 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); __func__, clk_id);
goto done; goto done;
} }
@@ -207,7 +210,8 @@ static int bolero_clk_rsc_mux0_clk_request(struct bolero_clk_rsc *priv,
ret = clk_prepare_enable( ret = clk_prepare_enable(
priv->clk[clk_id + NPL_CLK_OFFSET]); priv->clk[clk_id + NPL_CLK_OFFSET]);
if (ret < 0) { 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__, __func__,
clk_id + NPL_CLK_OFFSET); clk_id + NPL_CLK_OFFSET);
goto err; goto err;
@@ -246,6 +250,7 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv,
int ret = 0; int ret = 0;
int default_clk_id = priv->default_clk_id[clk_id]; int default_clk_id = priv->default_clk_id[clk_id];
u32 muxsel = 0; u32 muxsel = 0;
static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
clk_muxsel = bolero_clk_rsc_get_clk_muxsel(priv, clk_id); clk_muxsel = bolero_clk_rsc_get_clk_muxsel(priv, clk_id);
if (!clk_muxsel) { 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]); ret = clk_prepare_enable(priv->clk[clk_id]);
if (ret < 0) { if (ret < 0) {
dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", if (__ratelimit(&rtl))
__func__, clk_id); dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
__func__, clk_id);
goto err_clk; goto err_clk;
} }
if (priv->clk[clk_id + NPL_CLK_OFFSET]) { if (priv->clk[clk_id + NPL_CLK_OFFSET]) {
ret = clk_prepare_enable( ret = clk_prepare_enable(
priv->clk[clk_id + NPL_CLK_OFFSET]); priv->clk[clk_id + NPL_CLK_OFFSET]);
if (ret < 0) { 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__, __func__,
clk_id + NPL_CLK_OFFSET); clk_id + NPL_CLK_OFFSET);
goto err_npl_clk; 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); mutex_lock(&priv->fs_gen_lock);
if (enable) { if (enable) {
if (priv->reg_seq_en_cnt++ == 0) { if (priv->reg_seq_en_cnt++ == 0) {
for (i = 0; i < (priv->num_fs_reg * 2); i += 2) { for (i = 0; i < (priv->num_fs_reg * 3); i += 3) {
dev_dbg(priv->dev, "%s: Register: %d, value: %d\n", dev_dbg(priv->dev, "%s: Register: %d, mask: %d, value %d\n",
__func__, priv->fs_gen_seq[i], __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, regmap_update_bits(regmap,
priv->fs_gen_seq[i], priv->fs_gen_seq[i],
priv->fs_gen_seq[i + 1], priv->fs_gen_seq[i + 1],
priv->fs_gen_seq[i + 1]); priv->fs_gen_seq[i + 2]);
} }
} }
} else { } else {
@@ -488,8 +496,8 @@ void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable)
return; return;
} }
if (--priv->reg_seq_en_cnt == 0) { if (--priv->reg_seq_en_cnt == 0) {
for (i = ((priv->num_fs_reg - 1) * 2); i >= 0; i -= 2) { for (i = ((priv->num_fs_reg - 1) * 3); i >= 0; i -= 3) {
dev_dbg(priv->dev, "%s: Register: %d, value: %d\n", dev_dbg(priv->dev, "%s: Register: %d, mask: %d\n",
__func__, priv->fs_gen_seq[i], __func__, priv->fs_gen_seq[i],
priv->fs_gen_seq[i + 1]); priv->fs_gen_seq[i + 1]);
regmap_update_bits(regmap, priv->fs_gen_seq[i], 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; ret = -EINVAL;
goto err; 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); priv->fs_gen_seq = devm_kzalloc(&pdev->dev, fs_gen_size, GFP_KERNEL);
if (!priv->fs_gen_seq) { if (!priv->fs_gen_seq) {
ret = -ENOMEM; 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, ret = of_property_read_u32_array(pdev->dev.of_node,
"qcom,fs-gen-sequence", "qcom,fs-gen-sequence",
priv->fs_gen_seq, priv->fs_gen_seq,
priv->num_fs_reg * 2); priv->num_fs_reg * 3);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "%s: unable to parse fs-gen-sequence, ret = %d\n", dev_err(&pdev->dev, "%s: unable to parse fs-gen-sequence, ret = %d\n",
__func__, ret); __func__, ret);

View File

@@ -351,6 +351,7 @@ struct rx_macro_bcl_pmic_params {
u8 ppid; u8 ppid;
}; };
static int rx_macro_core_vote(void *handle, bool enable);
static int rx_macro_hw_params(struct snd_pcm_substream *substream, static int rx_macro_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai); 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->rx_mclk_users == 0) {
if (rx_priv->is_native_on) if (rx_priv->is_native_on)
rx_priv->clk_id = RX_CORE_CLK; rx_priv->clk_id = RX_CORE_CLK;
rx_macro_core_vote(rx_priv, true);
ret = bolero_clk_rsc_request_clock(rx_priv->dev, ret = bolero_clk_rsc_request_clock(rx_priv->dev,
rx_priv->default_clk_id, rx_priv->default_clk_id,
rx_priv->clk_id, rx_priv->clk_id,
@@ -1327,6 +1329,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv,
0x01, 0x00); 0x01, 0x00);
bolero_clk_rsc_fs_gen_request(rx_priv->dev, bolero_clk_rsc_fs_gen_request(rx_priv->dev,
false); false);
rx_macro_core_vote(rx_priv, true);
bolero_clk_rsc_request_clock(rx_priv->dev, bolero_clk_rsc_request_clock(rx_priv->dev,
rx_priv->default_clk_id, rx_priv->default_clk_id,
rx_priv->clk_id, rx_priv->clk_id,
@@ -1440,18 +1443,21 @@ static int rx_macro_event_handler(struct snd_soc_component *component,
} }
break; break;
case BOLERO_MACRO_EVT_PRE_SSR_UP: case BOLERO_MACRO_EVT_PRE_SSR_UP:
rx_macro_core_vote(rx_priv, true);
/* enable&disable RX_CORE_CLK to reset GFMUX reg */ /* enable&disable RX_CORE_CLK to reset GFMUX reg */
ret = bolero_clk_rsc_request_clock(rx_priv->dev, ret = bolero_clk_rsc_request_clock(rx_priv->dev,
rx_priv->default_clk_id, rx_priv->default_clk_id,
RX_CORE_CLK, true); RX_CORE_CLK, true);
if (ret < 0) if (ret < 0) {
dev_err_ratelimited(rx_priv->dev, dev_err_ratelimited(rx_priv->dev,
"%s, failed to enable clk, ret:%d\n", "%s, failed to enable clk, ret:%d\n",
__func__, ret); __func__, ret);
else } else {
rx_macro_core_vote(rx_priv, true);
bolero_clk_rsc_request_clock(rx_priv->dev, bolero_clk_rsc_request_clock(rx_priv->dev,
rx_priv->default_clk_id, rx_priv->default_clk_id,
RX_CORE_CLK, false); RX_CORE_CLK, false);
}
break; break;
case BOLERO_MACRO_EVT_SSR_UP: case BOLERO_MACRO_EVT_SSR_UP:
trace_printk("%s, enter SSR up\n", __func__); trace_printk("%s, enter SSR up\n", __func__);

View File

@@ -180,6 +180,7 @@ struct tx_macro_priv {
bool lpi_enable; bool lpi_enable;
bool register_event_listener; bool register_event_listener;
u16 current_clk_id; u16 current_clk_id;
int disable_afe_wakeup_event_listener;
}; };
static bool tx_macro_get_data(struct snd_soc_component *component, 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 && if (tx_priv->swr_ctrl_data &&
(!tx_priv->tx_swr_clk_cnt || !tx_priv->va_swr_clk_cnt)) { (!tx_priv->tx_swr_clk_cnt || !tx_priv->va_swr_clk_cnt)) {
if (enable) { if (enable) {
ret = swrm_wcd_notify( if (!tx_priv->disable_afe_wakeup_event_listener)
tx_priv->swr_ctrl_data[0].tx_swr_pdev, ret = swrm_wcd_notify(
SWR_REGISTER_WAKEUP, NULL); tx_priv->swr_ctrl_data[0].tx_swr_pdev,
msm_cdc_pinctrl_set_wakeup_capable( SWR_REGISTER_WAKEUP, NULL);
tx_priv->tx_swr_gpio_p, false);
} else { } else {
msm_cdc_pinctrl_set_wakeup_capable( if (!tx_priv->disable_afe_wakeup_event_listener)
tx_priv->tx_swr_gpio_p, true); ret = swrm_wcd_notify(
ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev,
tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_DEREGISTER_WAKEUP, NULL);
SWR_DEREGISTER_WAKEUP, NULL);
} }
} }
@@ -2685,6 +2684,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
__func__); __func__);
goto exit; 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, clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
@@ -2813,6 +2814,8 @@ tx_clk:
TX_CORE_CLK, TX_CORE_CLK,
false); false);
if (tx_priv->swr_clk_users == 0) { 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( ret = msm_cdc_pinctrl_select_sleep_state(
tx_priv->tx_swr_gpio_p); tx_priv->tx_swr_gpio_p);
if (ret < 0) { 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"; const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate";
u32 is_used_tx_swr_gpio = 1; u32 is_used_tx_swr_gpio = 1;
const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio"; 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)) { if (!bolero_is_va_macro_registered(&pdev->dev)) {
dev_err(&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) sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
return -EINVAL; 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) { if (is_used_tx_swr_gpio) {
tx_priv->reset_swr = true; tx_priv->reset_swr = true;
INIT_WORK(&tx_priv->tx_macro_add_child_devices_work, INIT_WORK(&tx_priv->tx_macro_add_child_devices_work,

View File

@@ -170,10 +170,12 @@ struct va_macro_priv {
int va_swr_clk_cnt; int va_swr_clk_cnt;
int va_clk_status; int va_clk_status;
int tx_clk_status; int tx_clk_status;
int dapm_tx_clk_status;
bool lpi_enable; bool lpi_enable;
bool register_event_listener; bool register_event_listener;
bool clk_div_switch;
int dec_mode[VA_MACRO_NUM_DECIMATORS]; 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, 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; return -EINVAL;
if ((va_priv->version >= BOLERO_VERSION_2_0) 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)) && (va_priv->dmic_clk_div == VA_MACRO_CLK_DIV_16))
return VA_MACRO_CLK_DIV_8; 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) { switch (event) {
case SND_SOC_DAPM_PRE_PMU: 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, ret = bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id, va_priv->default_clk_id,
VA_CORE_CLK, VA_CORE_CLK,
@@ -418,14 +427,13 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
false); false);
break; break;
} }
va_priv->current_clk_id = VA_CORE_CLK;
} }
msm_cdc_pinctrl_set_wakeup_capable(
va_priv->va_swr_gpio_p, false);
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
msm_cdc_pinctrl_set_wakeup_capable( if (va_priv->current_clk_id == VA_CORE_CLK &&
va_priv->va_swr_gpio_p, true); va_priv->va_swr_clk_cnt != 0 &&
if (va_priv->default_clk_id == TX_CORE_CLK) { va_priv->tx_clk_status) {
ret = bolero_clk_rsc_request_clock(va_priv->dev, ret = bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id, va_priv->default_clk_id,
TX_CORE_CLK, TX_CORE_CLK,
@@ -450,6 +458,7 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
false); false);
break; break;
} }
va_priv->current_clk_id = TX_CORE_CLK;
} }
break; break;
default: 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", dev_dbg(va_dev, "%s: clock switch failed\n",
__func__); __func__);
} }
if (va_priv->lpi_enable && if (va_priv->lpi_enable) {
!va_priv->disable_afe_wakeup_event_listener) {
bolero_register_event_listener(component, true); bolero_register_event_listener(component, true);
va_priv->register_event_listener = 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, TX_CORE_CLK,
true); true);
if (!ret) if (!ret)
va_priv->tx_clk_status++; va_priv->dapm_tx_clk_status++;
if (va_priv->lpi_enable) if (va_priv->lpi_enable)
ret = va_macro_mclk_enable(va_priv, 1, true); 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); 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, bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id, va_priv->default_clk_id,
TX_CORE_CLK, TX_CORE_CLK,
false); false);
va_priv->tx_clk_status--; va_priv->dapm_tx_clk_status--;
} }
break; break;
default: 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); (enable ? "enable" : "disable"), va_priv->va_mclk_users);
if (enable) { if (enable) {
if (va_priv->swr_clk_users == 0) if (va_priv->swr_clk_users == 0) {
msm_cdc_pinctrl_select_active_state( msm_cdc_pinctrl_select_active_state(
va_priv->va_swr_gpio_p); 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, clk_tx_ret = bolero_clk_rsc_request_clock(va_priv->dev,
TX_CORE_CLK, TX_CORE_CLK,
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,
TX_CORE_CLK, TX_CORE_CLK,
false); 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( msm_cdc_pinctrl_select_sleep_state(
va_priv->va_swr_gpio_p); va_priv->va_swr_gpio_p);
}
} }
return 0; return 0;
@@ -1312,12 +1326,12 @@ static int va_macro_enable_tx(struct snd_soc_dapm_widget *w,
switch (event) { switch (event) {
case SND_SOC_DAPM_POST_PMU: 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, ret = bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id, va_priv->default_clk_id,
TX_CORE_CLK, TX_CORE_CLK,
false); false);
va_priv->tx_clk_status--; va_priv->dapm_tx_clk_status--;
} }
break; break;
case SND_SOC_DAPM_PRE_PMD: 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, TX_CORE_CLK,
true); true);
if (!ret) if (!ret)
va_priv->tx_clk_status++; va_priv->dapm_tx_clk_status++;
break; break;
default: default:
dev_err(va_priv->dev, dev_err(va_priv->dev,
@@ -1508,6 +1522,10 @@ static int va_macro_hw_params(struct snd_pcm_substream *substream,
params_channels(params)); params_channels(params));
sample_rate = params_rate(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) { switch (sample_rate) {
case 8000: case 8000:
tx_fs_rate = 0; 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 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"},
{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
}; };
static const struct snd_soc_dapm_route va_audio_map_v3[] = { 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[] = { static const struct snd_soc_dapm_route va_audio_map_v2[] = {
{"VA_AIF1 CAP", NULL, "VA_SWR_CLK"}, {"VA SWR_INPUT", NULL, "VA_SWR_CLK"},
{"VA_AIF2 CAP", NULL, "VA_SWR_CLK"},
{"VA_AIF3 CAP", NULL, "VA_SWR_CLK"},
}; };
static const struct snd_soc_dapm_route va_audio_map[] = { 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; u32 default_clk_id = 0;
struct clk *lpass_audio_hw_vote = NULL; struct clk *lpass_audio_hw_vote = NULL;
u32 is_used_va_swr_gpio = 0; 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 *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), va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv),
GFP_KERNEL); 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, va_priv->va_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
"qcom,va-swr-gpios", 0); "qcom,va-swr-gpios", 0);
if (!va_priv->va_swr_gpio_p && is_used_va_swr_gpio) { 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->clk_id = VA_CORE_CLK;
va_priv->default_clk_id = default_clk_id; va_priv->default_clk_id = default_clk_id;
va_priv->current_clk_id = TX_CORE_CLK;
if (is_used_va_swr_gpio) { if (is_used_va_swr_gpio) {
va_priv->reset_swr = true; va_priv->reset_swr = true;

View File

@@ -220,11 +220,18 @@ static int dmic_swr_ctrl(struct snd_soc_dapm_widget *w,
u8 port_type = 0; u8 port_type = 0;
u8 port_id = w->shift; 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 1 is high quality / 2.4 or 3.072 Mbps
* Port 2 is listen low power / 0.6 or 0.768 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; ch_rate = SWR_CLK_RATE_2P4MHZ;
else else
ch_rate = SWR_CLK_RATE_0P6MHZ; ch_rate = SWR_CLK_RATE_0P6MHZ;

View File

@@ -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, int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
uint32_t *zr) 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; *zl = mbhc->zl;
*zr = mbhc->zr; *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, static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb,
unsigned long mode, void *ptr) 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); struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, fsa_nb);
if (!mbhc) 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); mbhc->mbhc_cb->clk_setup(mbhc->component, true);
/* insertion detected, enable L_DET_EN */ /* insertion detected, enable L_DET_EN */
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); 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; return 0;
} }

View File

@@ -1883,9 +1883,12 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w,
default: default:
break; break;
} }
if (wcd938x->adc_count == 0) if (wcd938x->adc_count == 0) {
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00);
}
break; break;
}; };
return ret; return ret;
@@ -2156,8 +2159,6 @@ static int wcd938x_event_notify(struct notifier_block *block,
WCD938X_EVT_SSR_DOWN, WCD938X_EVT_SSR_DOWN,
NULL); NULL);
wcd938x->mbhc->wcd_mbhc.deinit_in_progress = true; 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; mbhc = &wcd938x->mbhc->wcd_mbhc;
wcd938x->usbc_hs_status = get_usbc_hs_status(component, wcd938x->usbc_hs_status = get_usbc_hs_status(component,
mbhc->mbhc_cfg); mbhc->mbhc_cfg);
@@ -2183,8 +2184,6 @@ static int wcd938x_event_notify(struct notifier_block *block,
__func__); __func__);
} else { } else {
wcd938x_mbhc_hs_detect(component, mbhc->mbhc_cfg); wcd938x_mbhc_hs_detect(component, mbhc->mbhc_cfg);
if (wcd938x->usbc_hs_status)
mdelay(500);
} }
wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false; wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false;
wcd938x->dev_up = true; wcd938x->dev_up = true;
@@ -2192,6 +2191,8 @@ static int wcd938x_event_notify(struct notifier_block *block,
blocking_notifier_call_chain(&wcd938x->notifier, blocking_notifier_call_chain(&wcd938x->notifier,
WCD938X_EVT_SSR_UP, WCD938X_EVT_SSR_UP,
NULL); NULL);
if (wcd938x->usbc_hs_status)
mdelay(500);
break; break;
case BOLERO_SLV_EVT_CLK_NOTIFY: case BOLERO_SLV_EVT_CLK_NOTIFY:
snd_soc_component_update_bits(component, 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 = struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol); snd_soc_kcontrol_component(kcontrol);
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); struct wcd938x_priv *wcd938x = NULL;
int slave_ch_idx; 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); 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(
ucontrol->value.integer.value[0] = wcd938x->tx_master_ch_map[slave_ch_idx]);
wcd938x_slave_get_master_ch_val(
wcd938x->tx_master_ch_map[slave_ch_idx]);
return 0; return 0;
} }
@@ -2860,19 +2868,27 @@ static int wcd938x_tx_master_ch_put(struct snd_kcontrol *kcontrol,
{ {
struct snd_soc_component *component = struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol); snd_soc_kcontrol_component(kcontrol);
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); struct wcd938x_priv *wcd938x = NULL;
int slave_ch_idx; 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); 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: slave_ch_idx: %d", __func__, slave_ch_idx);
dev_dbg(component->dev, "%s: ucontrol->value.enumerated.item[0] = %ld\n", dev_dbg(component->dev, "%s: ucontrol->value.enumerated.item[0] = %ld\n",
__func__, ucontrol->value.enumerated.item[0]); __func__, ucontrol->value.enumerated.item[0]);
if (slave_ch_idx != -EINVAL) wcd938x->tx_master_ch_map[slave_ch_idx] = wcd938x_slave_get_master_ch(
wcd938x->tx_master_ch_map[slave_ch_idx] = ucontrol->value.enumerated.item[0]);
wcd938x_slave_get_master_ch(
ucontrol->value.enumerated.item[0]);
return 0; return 0;
} }

View File

@@ -34,6 +34,7 @@
#define SPK_GAIN_12DB 4 #define SPK_GAIN_12DB 4
#define WIDGET_NAME_MAX_SIZE 80 #define WIDGET_NAME_MAX_SIZE 80
#define REGMAP_REGISTER_CHECK_RETRY 30
#define MAX_NAME_LEN 30 #define MAX_NAME_LEN 30
#define WSA881X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ #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"}; 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; static bool pinctrl_init;
@@ -1142,6 +1143,7 @@ static int wsa881x_probe(struct snd_soc_component *component)
{ {
struct i2c_client *client; struct i2c_client *client;
int ret = 0; int ret = 0;
int retry = REGMAP_REGISTER_CHECK_RETRY;
int wsa881x_index = 0; int wsa881x_index = 0;
struct snd_soc_dapm_context *dapm = struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(component); 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 = wsa_pdata[wsa881x_index].tz_pdata.wsa_temp_reg_read =
wsa881x_temp_reg_read; wsa881x_temp_reg_read;
snd_soc_component_set_drvdata(component, &wsa_pdata[wsa881x_index]); 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); wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata);
INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work, INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work,
wsa881x_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) { if (pdata->status == WSA881X_STATUS_I2C) {
dev_dbg(&client->dev, "%s:probe for other slaves\n" dev_info(&client->dev, "%s:probe for other slaves\n"
"devices of codec I2C slave Addr = %x\n", "devices of codec I2C slave Addr = %x wsa_idx = %d\n",
__func__, client->addr); __func__, client->addr, wsa881x_index);
dev_dbg(&client->dev, "%s:wsa_idx = %d SLAVE = %d\n", dev_dbg(&client->dev, "%s:wsa_idx = %d SLAVE = %d\n",
__func__, wsa881x_index, WSA881X_ANALOG_SLAVE); __func__, wsa881x_index, WSA881X_ANALOG_SLAVE);
pdata->regmap[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; client->dev.platform_data = pdata;
i2c_set_clientdata(client, pdata); i2c_set_clientdata(client, pdata);
pdata->client[WSA881X_ANALOG_SLAVE] = client; pdata->client[WSA881X_ANALOG_SLAVE] = client;
pdata->regmap_flag = true;
if (pdata->version == WSA881X_2_0) if (pdata->version == WSA881X_2_0)
wsa881x_update_regmap_2_0( wsa881x_update_regmap_2_0(
pdata->regmap[WSA881X_ANALOG_SLAVE], pdata->regmap[WSA881X_ANALOG_SLAVE],
@@ -1467,7 +1480,6 @@ static int wsa881x_i2c_probe(struct i2c_client *client,
goto err; goto err;
} }
pdata->client[WSA881X_DIGITAL_SLAVE] = client; pdata->client[WSA881X_DIGITAL_SLAVE] = client;
pdata->regmap_flag = true;
ret = check_wsa881x_presence(client); ret = check_wsa881x_presence(client);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, dev_err(&client->dev,
@@ -1551,6 +1563,8 @@ static int wsa881x_i2c_probe(struct i2c_client *client,
component->name_prefix = pdata->wsa881x_name_prefix; component->name_prefix = pdata->wsa881x_name_prefix;
pdata->status = WSA881X_STATUS_I2C; pdata->status = WSA881X_STATUS_I2C;
dev_info(&client->dev, "%s:pdata status changed to I2C\n",
__func__);
goto err1; goto err1;
} }
err_mem: err_mem:

View File

@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* 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 #ifndef WSA881X_TEMP_SENSOR_H
#define WSA881X_TEMP_SENSOR_H #define WSA881X_TEMP_SENSOR_H
@@ -29,7 +29,13 @@ struct wsa881x_tz_priv {
int curr_temp; 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); int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata);
void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev); 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 #endif

View File

@@ -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 */ {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) */ /* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = { static struct port_params tx_frame_params_4p8MHz[SWR_MSTR_PORT_LEN] = {
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */ {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */ {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[] = { 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_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd}, {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[] = { static struct swr_mstr_port_map sm_port_map_wcd937x[] = {
{VA_MACRO, SWR_UC0, tx_frame_params_wcd937x}, {VA_MACRO, SWR_UC0, tx_frame_params_wcd937x},
{RX_MACRO, SWR_UC0, rx_frame_params_default}, {RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd}, {RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz},
}; };
#endif /* _HOLI_PORT_CONFIG */ #endif /* _HOLI_PORT_CONFIG */

View File

@@ -4343,7 +4343,8 @@ err:
static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) 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++; qos_client_active_cnt++;
if (qos_client_active_cnt == 1) if (qos_client_active_cnt == 1)

View File

@@ -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 */ {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) */ /* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = { static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */ {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}, {TX_MACRO, SWR_UC2, tx_frame_params_0p6MHz},
{RX_MACRO, SWR_UC0, rx_frame_params_default}, {RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd}, {RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz},
{WSA_MACRO, SWR_UC0, wsa_frame_params_default}, {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}, {TX_MACRO, SWR_UC2, tx_frame_params_shima_0p6MHz},
{RX_MACRO, SWR_UC0, rx_frame_params_default}, {RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd}, {RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz},
{WSA_MACRO, SWR_UC0, wsa_frame_params_default}, {WSA_MACRO, SWR_UC0, wsa_frame_params_default},
}; };

View File

@@ -73,6 +73,7 @@ struct msm_asoc_mach_data {
struct clk *lpass_audio_hw_vote; struct clk *lpass_audio_hw_vote;
int core_audio_vote_count; int core_audio_vote_count;
u32 wsa_max_devs; u32 wsa_max_devs;
int wcd_disabled;
}; };
static bool is_initial_boot; static bool is_initial_boot;
@@ -84,8 +85,8 @@ static int dmic_4_5_gpio_cnt;
static void *def_wcd_mbhc_cal(void); static void *def_wcd_mbhc_cal(void);
static int msm_aux_codec_init(struct snd_soc_pcm_runtime*); static int msm_rx_tx_codec_init(struct snd_soc_pcm_runtime*);
static int msm_int_audrx_init(struct snd_soc_pcm_runtime*); static int msm_int_wsa_init(struct snd_soc_pcm_runtime*);
/* /*
* Need to report LINEIN * Need to report LINEIN
@@ -489,7 +490,7 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = {
.ignore_suspend = 1, .ignore_suspend = 1,
.ops = &msm_common_be_ops, .ops = &msm_common_be_ops,
SND_SOC_DAILINK_REG(wsa_dma_rx0), 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, .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, .ignore_suspend = 1,
.ops = &msm_common_be_ops, .ops = &msm_common_be_ops,
SND_SOC_DAILINK_REG(rx_dma_rx0), 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, .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, .ignore_suspend = 1,
.ops = &msm_common_be_ops, .ops = &msm_common_be_ops,
SND_SOC_DAILINK_REG(rx_dma_rx1), SND_SOC_DAILINK_REG(rx_dma_rx1),
.init = &msm_int_audrx_init,
}, },
{ {
.name = LPASS_BE_RX_CDC_DMA_RX_2, .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; np = dai_link[i].codecs[j].of_node;
if (!of_device_is_available(np)) { 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__, __func__,
np->full_name); np->full_name);
dai_link[i].codecs[j].of_node = NULL; 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; struct snd_soc_component *component = NULL;
const char *be_dl_name = LPASS_BE_RX_CDC_DMA_RX_0; const char *be_dl_name = LPASS_BE_RX_CDC_DMA_RX_0;
struct snd_soc_pcm_runtime *rtd; struct snd_soc_pcm_runtime *rtd;
struct msm_asoc_mach_data *pdata;
int ret = 0; int ret = 0;
void *mbhc_calibration; 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); rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
if (!rtd) { if (!rtd) {
dev_err(card->dev, dev_err(card->dev,
@@ -992,7 +1000,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
return card; 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 spkleft_ports[WSA883X_MAX_SWR_PORTS] = {0, 1, 2, 3};
u8 spkright_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}; unsigned int ch_mask[WSA883X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3};
struct snd_soc_component *component = NULL; struct snd_soc_component *component = NULL;
struct snd_soc_dapm_context *dapm = 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 = struct msm_asoc_mach_data *pdata =
snd_soc_card_get_drvdata(rtd->card); snd_soc_card_get_drvdata(rtd->card);
int ret = 0; int wsa_active_devs = 0;
if (codec_reg_done) {
return 0;
}
if (pdata->wsa_max_devs > 0) { if (pdata->wsa_max_devs > 0) {
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.1"); component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.1");
if (!component) { if (component) {
pr_err("%s: wsa-codec.1 component is NULL\n", __func__); dapm = snd_soc_component_get_dapm(component);
return -EINVAL;
}
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_codec_info_create_codec_entry(pdata->codec_root,
WSA883X_MAX_SWR_PORTS, &ch_mask[0], component);
&ch_rate[0], &spkleft_port_types[0]); wsa_active_devs++;
} else {
if (dapm->component) { pr_info("%s: wsa-codec.1 component is NULL\n", __func__);
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);
}
/* If current platform has more than one WSA */ /* 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"); component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.2");
if (!component) { if (!component) {
pr_err("%s: wsa-codec.2 component is NULL\n", __func__); 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; 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], WSA883X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0], &spkright_port_types[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, wsa883x_codec_info_create_codec_entry(pdata->codec_root,
component); 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"); component = snd_soc_rtdcom_lookup(rtd, "bolero_codec");
if (!component) { if (!component) {
pr_err("%s: could not find component for bolero_codec\n", 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) { if (!entry) {
pr_debug("%s: Cannot create codecs module entry\n", pr_debug("%s: Cannot create codecs module entry\n",
__func__); __func__);
ret = 0; return 0;
goto err;
} }
pdata->codec_root = entry; pdata->codec_root = entry;
} }
bolero_info_create_codec_entry(pdata->codec_root, component); bolero_info_create_codec_entry(pdata->codec_root, component);
bolero_register_wake_irq(component, false); 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); component = snd_soc_rtdcom_lookup(rtd, WCD938X_DRV_NAME);
if (!component) { if (!component) {
pr_err("%s component is NULL\n", __func__); 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_ignore_suspend(dapm, "AMIC4");
snd_soc_dapm_sync(dapm); 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); wcd938x_info_create_codec_entry(pdata->codec_root, component);
#if 0 #if 0
@@ -1175,6 +1164,7 @@ static int msm_aux_codec_init(struct snd_soc_pcm_runtime *rtd)
} }
#endif #endif
codec_reg_done = true;
msm_common_dai_link_init(rtd); msm_common_dai_link_init(rtd);
return 0; return 0;
} }
@@ -1306,6 +1296,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
"qcom,lito-is-v2-enabled", "qcom,lito-is-v2-enabled",
&pdata->lito_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); card = populate_snd_card_dailinks(&pdev->dev);
if (!card) { if (!card) {
dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);

View File

@@ -5,7 +5,6 @@
#include <sound/soc.h> #include <sound/soc.h>
SND_SOC_DAILINK_DEFS(usb_audio_rx, SND_SOC_DAILINK_DEFS(usb_audio_rx,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")), DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_DUMMY()), 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_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("tavil_codec", "tavil_i2s_tx1")), DAILINK_COMP_ARRAY(COMP_CODEC("tavil_codec", "tavil_i2s_tx1")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy"))); DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));

View File

@@ -21,6 +21,7 @@
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/info.h> #include <sound/info.h>
#include <dsp/audio_notifier.h> #include <dsp/audio_notifier.h>
#include <dsp/apr_audio-v2.h>
#include <dsp/q6afe-v2.h> #include <dsp/q6afe-v2.h>
#include <dsp/q6core.h> #include <dsp/q6core.h>
#include <dsp/msm_mdf.h> #include <dsp/msm_mdf.h>
@@ -178,6 +179,7 @@ struct dev_config {
u32 sample_rate; u32 sample_rate;
u32 bit_format; u32 bit_format;
u32 channels; u32 channels;
u32 data_format;
}; };
struct msm_wsa881x_dev_info { struct msm_wsa881x_dev_info {
@@ -206,6 +208,7 @@ struct msm_asoc_mach_data {
u32 tdm_micb_voltage; u32 tdm_micb_voltage;
u32 tdm_micb_current; u32 tdm_micb_current;
bool codec_is_csra; bool codec_is_csra;
void __iomem *mi2s_dsd_mode[MI2S_MAX];
}; };
struct msm_asoc_wcd93xx_codec { 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 const char *const vi_feed_ch_text[] = {"One", "Two"};
static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
"S32_LE"}; "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", static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16",
"KHZ_32", "KHZ_44P1", "KHZ_48", "KHZ_32", "KHZ_44P1", "KHZ_48",
"KHZ_88P2", "KHZ_96", "KHZ_176P4", "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(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_rx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_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_rx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_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); 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; return idx;
/* check for PRIM_MI2S and CSRAx config to allow 24bit BE config only */ /* 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; 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", 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; 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) static int msm_meta_mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
{ {
int idx = 0; 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), msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
SOC_ENUM_EXT("SEN_MI2S_TX Channels", sen_mi2s_tx_chs, SOC_ENUM_EXT("SEN_MI2S_TX Channels", sen_mi2s_tx_chs,
msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), 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, SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format,
msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, 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) 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_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai_link *dai_link = rtd->dai_link; 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; unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
struct snd_soc_card *card = rtd->card; struct snd_soc_card *card = rtd->card;
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(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, dev_dbg(rtd->card->dev,
"%s: substream = %s stream = %d, dai name %s, dai ID %d\n", "%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]; mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
fmt = SND_SOC_DAIFMT_CBM_CFM; 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); ret = msm_mi2s_set_sclk(substream, true);
if (ret < 0) { if (ret < 0) {
dev_err(rtd->card->dev, dev_err(rtd->card->dev,
@@ -6396,9 +6504,34 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
__func__, index, ret); __func__, index, ret);
goto clk_off; 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]); 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); 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) static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
{ {
int ret; int ret;
int val;
int data_format;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
int index = rtd->cpu_dai->id; int index = rtd->cpu_dai->id;
struct snd_soc_card *card = rtd->card; struct snd_soc_card *card = rtd->card;
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(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__, pr_debug("%s(): substream = %s stream = %d\n", __func__,
substream->name, substream->stream); substream->name, substream->stream);
if (index < PRIM_MI2S || index >= MI2S_MAX) { 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( msm_cdc_pinctrl_select_sleep_state(
pdata->mi2s_gpio_p[index]); 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); ret = msm_mi2s_set_sclk(substream, false);
if (ret < 0) if (ret < 0)
pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", 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_supply_str1 = "tdm-vdd-micb";
const char *micb_voltage_str = "qcom,tdm-vdd-micb-voltage"; const char *micb_voltage_str = "qcom,tdm-vdd-micb-voltage";
const char *micb_current_str = "qcom,tdm-vdd-micb-current"; const char *micb_current_str = "qcom,tdm-vdd-micb-current";
u32 v_base_addr;
if (!pdev->dev.of_node) { if (!pdev->dev.of_node) {
dev_err(&pdev->dev, "No platform supplied from device tree\n"); 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) if (!pdata)
return -ENOMEM; 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 */ /* test for ep92 HDMI bridge and update dai links accordingly */
ret = msm_detect_ep92_dev(pdev, card); ret = msm_detect_ep92_dev(pdev, card);
if (ret) if (ret)

View File

@@ -29,6 +29,7 @@ export CONFIG_SND_SOC_WCD938X_SLAVE=m
export CONFIG_SND_SOC_WCD937X=m export CONFIG_SND_SOC_WCD937X=m
export CONFIG_SND_SOC_WCD937X_SLAVE=m export CONFIG_SND_SOC_WCD937X_SLAVE=m
export CONFIG_SND_SOC_WSA881X_ANALOG=m export CONFIG_SND_SOC_WSA881X_ANALOG=m
export CONFIG_WSA881X_TEMP_SENSOR_DISABLE=m
export CONFIG_SND_SOC_HOLI=m export CONFIG_SND_SOC_HOLI=m
export CONFIG_SND_EVENT=m export CONFIG_SND_EVENT=m
export CONFIG_TDM_DISABLE=m export CONFIG_TDM_DISABLE=m

View File

@@ -33,6 +33,7 @@
#define CONFIG_SND_SOC_WCD937X 1 #define CONFIG_SND_SOC_WCD937X 1
#define CONFIG_SND_SOC_WCD937X_SLAVE 1 #define CONFIG_SND_SOC_WCD937X_SLAVE 1
#define CONFIG_SND_SOC_WSA881X_ANALOG 1 #define CONFIG_SND_SOC_WSA881X_ANALOG 1
#define CONFIG_WSA881X_TEMP_SENSOR_DISABLE 1
#define CONFIG_SND_SOC_HOLI 1 #define CONFIG_SND_SOC_HOLI 1
#define CONFIG_SND_EVENT 1 #define CONFIG_SND_EVENT 1
#define CONFIG_TDM_DISABLE 1 #define CONFIG_TDM_DISABLE 1

View File

@@ -38,3 +38,4 @@ export CONFIG_AUDIO_PKT_ION=m
export CONFIG_MSM_QDSP6_GPR_RPMSG=m export CONFIG_MSM_QDSP6_GPR_RPMSG=m
export CONFIG_AUDIO_PKT=m export CONFIG_AUDIO_PKT=m
export CONFIG_DIGITAL_CDC_RSC_MGR=m export CONFIG_DIGITAL_CDC_RSC_MGR=m
export CONFIG_AUXPCM_DISABLE=m

View File

@@ -42,3 +42,4 @@
#define CONFIG_MSM_QDSP6_GPR_RPMSG 1 #define CONFIG_MSM_QDSP6_GPR_RPMSG 1
#define CONFIG_AUDIO_PKT 1 #define CONFIG_AUDIO_PKT 1
#define CONFIG_DIGITAL_CDC_RSC_MGR 1 #define CONFIG_DIGITAL_CDC_RSC_MGR 1
#define CONFIG_AUXPCM_DISABLE 1

View File

@@ -13,3 +13,4 @@ CONFIG_SND_SOC_MSM_STUB=m
CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
CONFIG_MSM_QDSP6V2_CODECS=m CONFIG_MSM_QDSP6V2_CODECS=m
CONFIG_SND_EVENT=m CONFIG_SND_EVENT=m
CONFIG_SND_SOC_SA8155=m

View File

@@ -17,3 +17,4 @@
#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1
#define CONFIG_MSM_QDSP6V2_CODECS 1 #define CONFIG_MSM_QDSP6V2_CODECS 1
#define CONFIG_SND_EVENT 1 #define CONFIG_SND_EVENT 1
#define CONFIG_SND_SOC_SA8155 1

View File

@@ -132,7 +132,7 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
bool cma_mem) bool cma_mem)
{ {
struct msm_audio_alloc_data *alloc_data; struct msm_audio_alloc_data *alloc_data = NULL;
struct device *cb_dev; struct device *cb_dev;
unsigned long ionflag = 0; unsigned long ionflag = 0;
int rc = 0; int rc = 0;
@@ -214,6 +214,7 @@ detach_dma_buf:
alloc_data->attach); alloc_data->attach);
free_alloc_data: free_alloc_data:
kfree(alloc_data); kfree(alloc_data);
alloc_data = NULL;
return rc; 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)); list_del(&(alloc_data->list));
kfree(alloc_data); kfree(alloc_data);
alloc_data = NULL;
break; break;
} }
} }
@@ -361,6 +363,11 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
int rc = 0; int rc = 0;
bool is_iova = true; 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); rc = msm_audio_ion_get_phys(dma_buf, paddr, plen, is_iova);
if (rc) { if (rc) {
pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",

View File

@@ -562,12 +562,18 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz,
pr_err("%s: Invalid params\n", __func__); pr_err("%s: Invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
pr_debug("%s: audio heap is used\n", __func__);
if (msm_audio_ion_data.smmu_enabled == true) { 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_AUDIO_HEAP_ID), 0);
*dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_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 { } else {
pr_debug("%s: audio heap is used\n", __func__);
*dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_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_OR_NULL((void *)(*dma_buf))) {

View File

@@ -551,7 +551,6 @@ struct wcd_mbhc {
wait_queue_head_t wait_btn_press; wait_queue_head_t wait_btn_press;
bool is_btn_press; bool is_btn_press;
u8 current_plug; u8 current_plug;
u8 plug_before_ssr;
bool in_swch_irq_handler; bool in_swch_irq_handler;
bool hphl_swh; /*track HPHL switch NC / NO */ bool hphl_swh; /*track HPHL switch NC / NO */
bool gnd_swh; /*track GND switch NC / NO */ bool gnd_swh; /*track GND switch NC / NO */

View File

@@ -4103,6 +4103,9 @@ struct afe_id_aptx_adaptive_enc_init
/* Macro for defining the packetizer ID: COP. */ /* Macro for defining the packetizer ID: COP. */
#define AFE_MODULE_ID_PACKETIZER_COP 0x0001322A #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. * Packetizer type parameter for the #AVS_MODULE_ID_ENCODER module.
* This parameter cannot be set runtime. * 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 0x00013233
#define AFE_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9 #define AFE_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9
#define AFE_MODULE_ID_DEPACKETIZER_COP_V2 0x000132FC
/* Macros for dynamic loading of modules by AVCS */ /* 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_V1 0x000132E8
#define AVS_MODULE_ID_PACKETIZER_COP_V2 0x000132F9
#define AVS_MODULE_ID_DEPACKETIZER_COP 0x00013233 #define AVS_MODULE_ID_DEPACKETIZER_COP 0x00013233
#define AVS_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9 #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. * Depacketizer type parameter for the #AVS_MODULE_ID_DECODER module.
* This parameter cannot be set runtime. * This parameter cannot be set runtime.
@@ -4192,6 +4208,12 @@ struct afe_id_aptx_adaptive_enc_init
struct aptx_channel_mode_param_t { struct aptx_channel_mode_param_t {
u32 channel_mode; u32 channel_mode;
} __packed; } __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. * Decoder buffer ID parameter for the #AVS_MODULE_ID_DECODER module.
* This parameter cannot be set runtime. * This parameter cannot be set runtime.
@@ -4410,6 +4432,10 @@ struct asm_aac_enc_cfg_t {
/* FMT ID for apt-X Adaptive speech */ /* FMT ID for apt-X Adaptive speech */
#define ASM_MEDIA_FMT_APTX_AD_SPEECH 0x00013208 #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_L 1
#define PCM_CHANNEL_R 2 #define PCM_CHANNEL_R 2
#define PCM_CHANNEL_C 3 #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; struct asm_aptx_ad_speech_mode_cfg_t speech_mode;
} __attribute__ ((packed)); } __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 struct afe_matched_port_t
{ {
uint32_t minor_version; uint32_t minor_version;
@@ -4765,12 +4855,14 @@ union afe_enc_config_data {
struct asm_ldac_enc_cfg_t ldac_config; struct asm_ldac_enc_cfg_t ldac_config;
struct asm_aptx_ad_enc_cfg_t aptx_ad_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_aptx_ad_speech_enc_cfg_t aptx_ad_speech_config;
struct asm_enc_lc3_cfg_t lc3_enc_config;
}; };
struct afe_enc_config { struct afe_enc_config {
u32 format; u32 format;
u32 scrambler_mode; u32 scrambler_mode;
u32 mono_mode; u32 mono_mode;
u32 lc3_mono_mode;
union afe_enc_config_data data; 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_mp3_dec_cfg_t mp3_config;
struct asm_aptx_ad_dec_cfg_t aptx_ad_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_aptx_ad_speech_dec_cfg_t aptx_ad_speech_config;
struct asm_lc3_dec_cfg_t lc3_dec_config;
}; };
struct afe_dec_config { struct afe_dec_config {

View File

@@ -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); 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 #endif

View File

@@ -17,7 +17,7 @@
#define SWR_CLK_RATE_2P4MHZ 2400000 #define SWR_CLK_RATE_2P4MHZ 2400000
#define SWR_CLK_RATE_4P8MHZ 4800000 #define SWR_CLK_RATE_4P8MHZ 4800000
#define SWR_CLK_RATE_9P6MHZ 9600000 #define SWR_CLK_RATE_9P6MHZ 9600000
#define SWR_CLK_RATE_11P2896MHZ 1128960 #define SWR_CLK_RATE_11P2896MHZ 11289600
extern struct bus_type soundwire_type; extern struct bus_type soundwire_type;
struct swr_device; struct swr_device;

View File

@@ -13,6 +13,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/ratelimit.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/delay.h> #include <linux/delay.h>
@@ -148,16 +149,19 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr)
{ {
int ret = 0; int ret = 0;
struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev); struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev);
static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
if (!lpi_dev_up) { 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__); __func__);
return 0; return 0;
} }
pm_runtime_get_sync(lpi_dev); pm_runtime_get_sync(lpi_dev);
mutex_lock(&state->core_hw_vote_lock); mutex_lock(&state->core_hw_vote_lock);
if (!state->core_hw_vote_status) { 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__); __func__);
ret = -EINVAL; ret = -EINVAL;
goto err; 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); struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev);
int ret = 0; int ret = 0;
static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
if (!lpi_dev_up) { if (!lpi_dev_up) {
return 0; 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); pm_runtime_get_sync(lpi_dev);
mutex_lock(&state->core_hw_vote_lock); mutex_lock(&state->core_hw_vote_lock);
if (!state->core_hw_vote_status) { 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__); __func__);
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;

View File

@@ -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 && if (swrm->mport_cfg[SWRM_DSD_PARAMS_PORT].port_en &&
(swrm->master_id == MASTER_ID_RX)) (swrm->master_id == MASTER_ID_RX))
usecase = 1; 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) if (swrm->bus_clk == SWR_CLK_RATE_4P8MHZ)
usecase = 1; usecase = 1;
@@ -2748,6 +2751,11 @@ static int swrm_probe(struct platform_device *pdev)
} }
devm_kfree(&pdev->dev, temp); 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->reg_irq = pdata->reg_irq;
swrm->master.read = swrm_read; swrm->master.read = swrm_read;
swrm->master.write = swrm_write; swrm->master.write = swrm_write;
@@ -2870,7 +2878,7 @@ static int swrm_probe(struct platform_device *pdev)
* controller will be up now * controller will be up now
*/ */
swr_master_add_boarddevices(&swrm->master); 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__); dev_dbg(&pdev->dev, "%s: Audio HW Vote is failed\n", __func__);
mutex_lock(&swrm->mlock); mutex_lock(&swrm->mlock);
swrm_clk_request(swrm, true); 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); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
int ret = 0; int ret = 0;
bool swrm_clk_req_err = false; 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_master *mstr = &swrm->master;
struct swr_device *swr_dev; struct swr_device *swr_dev;
u32 temp = 0; u32 temp = 0;
@@ -3034,9 +3042,11 @@ static int swrm_runtime_resume(struct device *dev)
__func__); __func__);
hw_core_err = true; 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", dev_err(dev, "%s:lpass audio hw enable failed\n",
__func__); __func__);
aud_core_err = true;
}
if ((swrm->state == SWR_MSTR_DOWN) || if ((swrm->state == SWR_MSTR_DOWN) ||
(swrm->state == SWR_MSTR_SSR && swrm->dev_up)) { (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; swrm->state = SWR_MSTR_UP;
} }
exit: exit:
if (swrm->is_always_on && !aud_core_err)
swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false);
if (!hw_core_err) if (!hw_core_err)
swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
if (swrm_clk_req_err) 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 platform_device *pdev = to_platform_device(dev);
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
int ret = 0; 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_master *mstr = &swrm->master;
struct swr_device *swr_dev; struct swr_device *swr_dev;
int current_state = 0; int current_state = 0;
@@ -3170,6 +3183,8 @@ static int swrm_runtime_suspend(struct device *dev)
hw_core_err = true; 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) || if ((current_state == SWR_MSTR_UP) ||
(current_state == SWR_MSTR_SSR)) { (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->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); enable_irq(swrm->wake_irq);
} else if (swrm->ipc_wakeup) { } else if (swrm->ipc_wakeup) {
//msm_aud_evt_blocking_notifier_call_chain( //msm_aud_evt_blocking_notifier_call_chain(
@@ -3252,11 +3269,13 @@ static int swrm_runtime_suspend(struct device *dev)
swrm->state = SWR_MSTR_DOWN; swrm->state = SWR_MSTR_DOWN;
exit: 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)) if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false))
dev_dbg(dev, "%s:lpass audio hw enable failed\n", dev_dbg(dev, "%s:lpass audio hw enable failed\n",
__func__); __func__);
} } else if (swrm->is_always_on && !aud_core_err)
swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false);
if (!hw_core_err) if (!hw_core_err)
swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
mutex_unlock(&swrm->reslock); mutex_unlock(&swrm->reslock);

View File

@@ -194,6 +194,7 @@ struct swr_mstr_ctrl {
u32 wr_fifo_depth; u32 wr_fifo_depth;
bool enable_slave_irq; bool enable_slave_irq;
u64 logical_dev[SWRM_NUM_AUTO_ENUM_SLAVES]; u64 logical_dev[SWRM_NUM_AUTO_ENUM_SLAVES];
u32 is_always_on;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_swrm_dent; struct dentry *debugfs_swrm_dent;
struct dentry *debugfs_peek; struct dentry *debugfs_peek;