asoc: codecs: update max sampling rate of wsa881x analog driver

Updated the wsa dailink to support 384Khz HS playback.

Picked latest codec fixes to kernel6.0.

Change-Id: Ia570dc3f3ed55415ac374e1ba3bb6f2277dade96
Signed-off-by: Sairam Peri<quic_peri@quicinc.com>
This commit is contained in:
Sairam Peri
2023-08-28 00:05:48 +05:30
parent 513787652f
commit 6e38fad118
10 changed files with 463 additions and 59 deletions

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/of_platform.h> #include <linux/of_platform.h>
@@ -21,6 +21,7 @@
#include "internal.h" #include "internal.h"
#include "bolero-clk-rsc.h" #include "bolero-clk-rsc.h"
#include "asoc/bolero-slave-internal.h" #include "asoc/bolero-slave-internal.h"
#include <linux/qti-regmap-debugfs.h>
#define DRV_NAME "bolero_codec" #define DRV_NAME "bolero_codec"
@@ -236,8 +237,9 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data)
BOLERO_MACRO_EVT_BCS_CLK_OFF, data); BOLERO_MACRO_EVT_BCS_CLK_OFF, data);
break; break;
case SLV_BOLERO_EVT_RX_PA_GAIN_UPDATE: case SLV_BOLERO_EVT_RX_PA_GAIN_UPDATE:
/* Update PA Gain only for bolero version 2.1 */ /* Update PA Gain for bolero version 2.1 and 2.2*/
if (priv->version == BOLERO_VERSION_2_1) if ((priv->version == BOLERO_VERSION_2_1) ||
(priv->version == BOLERO_VERSION_2_2))
if (priv->macro_params[RX_MACRO].event_handler) if (priv->macro_params[RX_MACRO].event_handler)
priv->macro_params[RX_MACRO].event_handler( priv->macro_params[RX_MACRO].event_handler(
priv->component, priv->component,
@@ -698,7 +700,8 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
if (macro_id == TX_MACRO || macro_id == VA_MACRO) if (macro_id == TX_MACRO || macro_id == VA_MACRO)
priv->macro_params[macro_id].clk_div_get = ops->clk_div_get; priv->macro_params[macro_id].clk_div_get = ops->clk_div_get;
if (priv->version == BOLERO_VERSION_2_1) { if ((priv->version == BOLERO_VERSION_2_1) ||
(priv->version == BOLERO_VERSION_2_2)) {
if (macro_id == VA_MACRO) if (macro_id == VA_MACRO)
priv->macro_params[macro_id].reg_wake_irq = priv->macro_params[macro_id].reg_wake_irq =
ops->reg_wake_irq; ops->reg_wake_irq;
@@ -781,6 +784,34 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id)
} }
EXPORT_SYMBOL(bolero_unregister_macro); EXPORT_SYMBOL(bolero_unregister_macro);
/**
* bolero_rx_pa_on - Send PA on event from RX macro to slave.
*
* @dev: macro device ptr.
*/
void bolero_rx_pa_on(struct device *dev)
{
struct bolero_priv *priv;
if (!dev) {
pr_err("%s: dev is null\n", __func__);
return;
}
if (!bolero_is_valid_child_dev(dev)) {
dev_err(dev, "%s: not a valid child dev\n",
__func__);
return;
}
priv = dev_get_drvdata(dev->parent);
if (!priv) {
dev_err(dev, "%s: priv is null\n", __func__);
return;
}
bolero_cdc_notifier_call(priv, BOLERO_SLV_EVT_RX_MACRO_PA_ON);
}
EXPORT_SYMBOL_GPL(bolero_rx_pa_on);
void bolero_wsa_pa_on(struct device *dev, bool adie_lb) void bolero_wsa_pa_on(struct device *dev, bool adie_lb)
{ {
struct bolero_priv *priv; struct bolero_priv *priv;
@@ -1055,7 +1086,8 @@ int bolero_register_wake_irq(struct snd_soc_component *component,
return -EINVAL; return -EINVAL;
} }
if (priv->version == BOLERO_VERSION_2_1) { if ((priv->version == BOLERO_VERSION_2_1) ||
(priv->version == BOLERO_VERSION_2_2)) {
if (priv->macro_params[VA_MACRO].reg_wake_irq) if (priv->macro_params[VA_MACRO].reg_wake_irq)
priv->macro_params[VA_MACRO].reg_wake_irq( priv->macro_params[VA_MACRO].reg_wake_irq(
component, ipc_wakeup); component, ipc_wakeup);
@@ -1176,7 +1208,7 @@ static int bolero_soc_codec_probe(struct snd_soc_component *component)
{ {
struct bolero_priv *priv = dev_get_drvdata(component->dev); struct bolero_priv *priv = dev_get_drvdata(component->dev);
int macro_idx, ret = 0; int macro_idx, ret = 0;
u8 core_id_0 = 0, core_id_1 = 0; u8 core_id_0 = 0, core_id_1 = 0, core_id_2 = 0;
snd_soc_component_init_regmap(component, priv->regmap); snd_soc_component_init_regmap(component, priv->regmap);
@@ -1201,10 +1233,16 @@ static int bolero_soc_codec_probe(struct snd_soc_component *component)
BOLERO_CDC_VA_TOP_CSR_CORE_ID_0); BOLERO_CDC_VA_TOP_CSR_CORE_ID_0);
core_id_1 = snd_soc_component_read(component, core_id_1 = snd_soc_component_read(component,
BOLERO_CDC_VA_TOP_CSR_CORE_ID_1); BOLERO_CDC_VA_TOP_CSR_CORE_ID_1);
core_id_2 = snd_soc_component_read(component,
BOLERO_CDC_VA_TOP_CSR_CORE_ID_2);
if ((core_id_0 == 0x01) && (core_id_1 == 0x0F)) if ((core_id_0 == 0x01) && (core_id_1 == 0x0F))
priv->version = BOLERO_VERSION_2_0; priv->version = BOLERO_VERSION_2_0;
if ((core_id_0 == 0x02) && (core_id_1 == 0x0E)) if ((core_id_0 == 0x02) && (core_id_1 == 0x0E)) {
priv->version = BOLERO_VERSION_2_1; if (core_id_2 == 0x20)
priv->version = BOLERO_VERSION_2_2;
else
priv->version = BOLERO_VERSION_2_1;
}
/* call init for supported macros */ /* call init for supported macros */
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
@@ -1368,7 +1406,8 @@ static int bolero_probe(struct platform_device *pdev)
__func__); __func__);
ret = 0; ret = 0;
} }
if (priv->version == BOLERO_VERSION_2_1) { if ((priv->version == BOLERO_VERSION_2_1) ||
(priv->version == BOLERO_VERSION_2_2)) {
bolero_reg_access[TX_MACRO] = bolero_tx_reg_access_v2; bolero_reg_access[TX_MACRO] = bolero_tx_reg_access_v2;
bolero_reg_access[VA_MACRO] = bolero_va_reg_access_v2; bolero_reg_access[VA_MACRO] = bolero_va_reg_access_v2;
} else if (priv->version == BOLERO_VERSION_2_0) { } else if (priv->version == BOLERO_VERSION_2_0) {
@@ -1385,6 +1424,9 @@ static int bolero_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "%s:regmap init failed\n", __func__); dev_err(&pdev->dev, "%s:regmap init failed\n", __func__);
return -EINVAL; return -EINVAL;
} }
devm_regmap_qti_debugfs_register(priv->dev, priv->regmap);
priv->read_dev = __bolero_reg_read; priv->read_dev = __bolero_reg_read;
priv->write_dev = __bolero_reg_write; priv->write_dev = __bolero_reg_write;

View File

@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef BOLERO_CDC_H #ifndef BOLERO_CDC_H
@@ -13,6 +14,7 @@
#define BOLERO_VERSION_1_2 0x0003 #define BOLERO_VERSION_1_2 0x0003
#define BOLERO_VERSION_2_0 0x0004 #define BOLERO_VERSION_2_0 0x0004
#define BOLERO_VERSION_2_1 0x0005 #define BOLERO_VERSION_2_1 0x0005
#define BOLERO_VERSION_2_2 0x0006
enum { enum {
START_MACRO, START_MACRO,
@@ -115,6 +117,7 @@ int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable);
int bolero_get_version(struct device *dev); int bolero_get_version(struct device *dev);
int bolero_dmic_clk_enable(struct snd_soc_component *component, int bolero_dmic_clk_enable(struct snd_soc_component *component,
u32 dmic, u32 tx_mode, bool enable); u32 dmic, u32 tx_mode, bool enable);
void bolero_rx_pa_on(struct device *dev);
#else #else
static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb)
{ {
@@ -215,5 +218,11 @@ static int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable)
{ {
return 0; return 0;
} }
static inline void bolero_rx_pa_on(struct device *dev)
{
return 0;
}
#endif /* CONFIG_SND_SOC_BOLERO */ #endif /* CONFIG_SND_SOC_BOLERO */
#endif /* BOLERO_CDC_H */ #endif /* BOLERO_CDC_H */

View File

@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -462,6 +463,7 @@ struct rx_macro_priv {
u16 default_clk_id; u16 default_clk_id;
int8_t rx0_gain_val; int8_t rx0_gain_val;
int8_t rx1_gain_val; int8_t rx1_gain_val;
u32 rx_macro_wsa_slv;
}; };
static struct snd_soc_dai_driver rx_macro_dai[]; static struct snd_soc_dai_driver rx_macro_dai[];
@@ -1249,7 +1251,11 @@ static int rx_macro_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
} }
} }
} }
break;
if (rx_priv->rx_macro_wsa_slv)
bolero_rx_pa_on(rx_dev);
break;
default: default:
break; break;
} }
@@ -4112,7 +4118,7 @@ static int rx_macro_probe(struct platform_device *pdev)
struct rx_macro_priv *rx_priv = NULL; struct rx_macro_priv *rx_priv = NULL;
u32 rx_base_addr = 0, muxsel = 0; u32 rx_base_addr = 0, muxsel = 0;
char __iomem *rx_io_base = NULL, *muxsel_io = NULL; char __iomem *rx_io_base = NULL, *muxsel_io = NULL;
int ret = 0; int ret = 0, val = 0;
u8 bcl_pmic_params[3]; u8 bcl_pmic_params[3];
u32 default_clk_id = 0; u32 default_clk_id = 0;
u32 is_used_rx_swr_gpio = 1; u32 is_used_rx_swr_gpio = 1;
@@ -4144,6 +4150,14 @@ static int rx_macro_probe(struct platform_device *pdev)
__func__, "reg"); __func__, "reg");
return ret; return ret;
} }
ret = of_property_read_u32(pdev->dev.of_node, "qcom,rx-wsa-enable", &val);
if (ret == 0) {
rx_priv->rx_macro_wsa_slv = (val == 1) ? 1 : 0;
dev_info(&pdev->dev, "RX macro wsa slave is %s\n",
(val == 1) ? "connected" : "not connected");
}
ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id", ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
&default_clk_id); &default_clk_id);
if (ret) { if (ret) {

View File

@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -690,6 +691,92 @@ static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
} }
static int tx_macro_put_dec_enum_v2(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dapm_widget *widget =
snd_soc_dapm_kcontrol_widget(kcontrol);
struct snd_soc_component *component =
snd_soc_dapm_to_component(widget->dapm);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val = 0;
u16 mic_sel_reg = 0;
struct device *tx_dev = NULL;
struct tx_macro_priv *tx_priv = NULL;
if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
return -EINVAL;
val = ucontrol->value.enumerated.item[0];
if (val > e->items - 1)
return -EINVAL;
dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
widget->name, val);
switch (e->reg) {
case BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0:
mic_sel_reg = BOLERO_CDC_TX0_TX_PATH_CFG0;
break;
case BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0:
mic_sel_reg = BOLERO_CDC_TX1_TX_PATH_CFG0;
break;
case BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0:
mic_sel_reg = BOLERO_CDC_TX2_TX_PATH_CFG0;
break;
case BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0:
mic_sel_reg = BOLERO_CDC_TX3_TX_PATH_CFG0;
break;
default:
dev_err(component->dev, "%s: e->reg: 0x%x not expected\n",
__func__, e->reg);
return -EINVAL;
}
if (strnstr(widget->name, "SMIC", strlen(widget->name))) {
if (val != 0) {
snd_soc_component_update_bits(component,
mic_sel_reg,
1 << 7, 0x0 << 7);
}
} else {
/* DMIC selected */
if (val != 0)
snd_soc_component_update_bits(component, mic_sel_reg,
1 << 7, 1 << 7);
}
return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
}
static int tx_macro_put_pcm_in_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dapm_widget *widget =
snd_soc_dapm_kcontrol_widget(kcontrol);
struct snd_soc_component *component =
snd_soc_dapm_to_component(widget->dapm);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val = 0;
struct device *tx_dev = NULL;
struct tx_macro_priv *tx_priv = NULL;
if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
return -EINVAL;
val = ucontrol->value.enumerated.item[0];
if (val > e->items - 1)
return -EINVAL;
dev_dbg(component->dev, "%s: wname: %s\n", __func__, widget->name);
snd_soc_component_update_bits(component,
BOLERO_CDC_TX_TOP_CSR_I2S_CLK,
0x1, val);
return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
}
static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
@@ -947,7 +1034,8 @@ static int tx_macro_get_bcs_ch_sel(struct snd_kcontrol *kcontrol,
if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
return -EINVAL; return -EINVAL;
if (tx_priv->version == BOLERO_VERSION_2_1) if ((tx_priv->version == BOLERO_VERSION_2_1) ||
(tx_priv->version == BOLERO_VERSION_2_2))
value = (snd_soc_component_read(component, value = (snd_soc_component_read(component,
BOLERO_CDC_VA_TOP_CSR_SWR_CTRL)) & 0x0F; BOLERO_CDC_VA_TOP_CSR_SWR_CTRL)) & 0x0F;
else if (tx_priv->version == BOLERO_VERSION_2_0) else if (tx_priv->version == BOLERO_VERSION_2_0)
@@ -975,7 +1063,8 @@ static int tx_macro_put_bcs_ch_sel(struct snd_kcontrol *kcontrol,
return -EINVAL; return -EINVAL;
value = ucontrol->value.integer.value[0]; value = ucontrol->value.integer.value[0];
if (tx_priv->version == BOLERO_VERSION_2_1) if ((tx_priv->version == BOLERO_VERSION_2_1) ||
(tx_priv->version == BOLERO_VERSION_2_2))
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F, value); BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F, value);
else if (tx_priv->version == BOLERO_VERSION_2_0) else if (tx_priv->version == BOLERO_VERSION_2_0)
@@ -1128,7 +1217,8 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
snd_soc_component_read(component, snd_soc_component_read(component,
tx_gain_ctl_reg)); tx_gain_ctl_reg));
if (tx_priv->bcs_enable) { if (tx_priv->bcs_enable) {
if (tx_priv->version == BOLERO_VERSION_2_1) if ((tx_priv->version == BOLERO_VERSION_2_1) ||
(tx_priv->version == BOLERO_VERSION_2_2))
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F, BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F,
tx_priv->bcs_ch); tx_priv->bcs_ch);
@@ -1219,6 +1309,10 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
0x20, 0x00); 0x20, 0x00);
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
dec_cfg_reg, 0x06, 0x00); dec_cfg_reg, 0x06, 0x00);
snd_soc_component_update_bits(component, tx_vol_ctl_reg,
0x40, 0x40);
snd_soc_component_update_bits(component, tx_vol_ctl_reg,
0x40, 0x00);
snd_soc_component_update_bits(component, tx_vol_ctl_reg, snd_soc_component_update_bits(component, tx_vol_ctl_reg,
0x10, 0x00); 0x10, 0x00);
if (tx_priv->bcs_enable) { if (tx_priv->bcs_enable) {
@@ -1227,7 +1321,8 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00); BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00);
tx_priv->bcs_clk_en = false; tx_priv->bcs_clk_en = false;
if (tx_priv->version == BOLERO_VERSION_2_1) if ((tx_priv->version == BOLERO_VERSION_2_1) ||
(tx_priv->version == BOLERO_VERSION_2_2))
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F, BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F,
0x00); 0x00);
@@ -1559,6 +1654,38 @@ TX_MACRO_DAPM_ENUM_EXT(tx_smic7_v3, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
tx_macro_put_dec_enum); tx_macro_put_dec_enum);
TX_MACRO_DAPM_ENUM_EXT(tx_smic0_v4, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
tx_macro_put_dec_enum_v2);
TX_MACRO_DAPM_ENUM_EXT(tx_smic1_v4, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
tx_macro_put_dec_enum_v2);
TX_MACRO_DAPM_ENUM_EXT(tx_smic2_v4, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
tx_macro_put_dec_enum_v2);
TX_MACRO_DAPM_ENUM_EXT(tx_smic3_v4, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
tx_macro_put_dec_enum_v2);
static const char * const pcm_in0_mux_text[] = {
"SWR_MIC", "RX_SWR_TX_PCM_IN0",
};
static const char * const pcm_in1_mux_text[] = {
"SWR_MIC", "RX_SWR_TX_PCM_IN1",
};
TX_MACRO_DAPM_ENUM_EXT(rx_swr_tx_pcm_in0, SND_SOC_NOPM,
0, pcm_in0_mux_text, snd_soc_dapm_get_enum_double,
tx_macro_put_pcm_in_enum);
TX_MACRO_DAPM_ENUM_EXT(rx_swr_tx_pcm_in1, SND_SOC_NOPM,
0, pcm_in1_mux_text, snd_soc_dapm_get_enum_double,
tx_macro_put_pcm_in_enum);
static const char * const dec_mode_mux_text[] = { static const char * const dec_mode_mux_text[] = {
"ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF", "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF",
}; };
@@ -1681,11 +1808,6 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_common[] = {
TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2), TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2),
TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3), TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3),
TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v2),
TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v2),
TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v2),
TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v2),
SND_SOC_DAPM_SUPPLY("TX MIC BIAS1", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_SUPPLY("TX MIC BIAS1", SND_SOC_NOPM, 0, 0,
tx_macro_enable_micbias, tx_macro_enable_micbias,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
@@ -1768,6 +1890,12 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v2[] = {
SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM,
TX_MACRO_AIF3_CAP, 0, TX_MACRO_AIF3_CAP, 0,
tx_aif3_cap_mixer_v2, ARRAY_SIZE(tx_aif3_cap_mixer_v2)), tx_aif3_cap_mixer_v2, ARRAY_SIZE(tx_aif3_cap_mixer_v2)),
TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v2),
TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v2),
TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v2),
TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v2),
}; };
static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = { static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = {
@@ -1788,6 +1916,10 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = {
TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6), TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6),
TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7), TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7),
TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v2),
TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v2),
TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v2),
TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v2),
TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4_v3), TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4_v3),
TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5_v3), TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5_v3),
TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6_v3), TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6_v3),
@@ -1826,6 +1958,31 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = {
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
}; };
static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v4[] = {
SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM,
TX_MACRO_AIF1_CAP, 0,
tx_aif1_cap_mixer_v2, ARRAY_SIZE(tx_aif1_cap_mixer_v2)),
SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM,
TX_MACRO_AIF2_CAP, 0,
tx_aif2_cap_mixer_v2, ARRAY_SIZE(tx_aif2_cap_mixer_v2)),
SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM,
TX_MACRO_AIF3_CAP, 0,
tx_aif3_cap_mixer_v2, ARRAY_SIZE(tx_aif3_cap_mixer_v2)),
TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v4),
TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v4),
TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v4),
TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v4),
TX_MACRO_DAPM_MUX("RX SWR TX MUX0", 0, rx_swr_tx_pcm_in0),
TX_MACRO_DAPM_MUX("RX SWR TX MUX1", 0, rx_swr_tx_pcm_in1),
SND_SOC_DAPM_INPUT("RX_SWR_TX_PCM_IN0"),
SND_SOC_DAPM_INPUT("RX_SWR_TX_PCM_IN1"),
};
static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = {
SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0, SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0,
SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0), SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0),
@@ -2022,8 +2179,6 @@ static const struct snd_soc_dapm_route tx_audio_map_common[] = {
{"TX SMIC MUX0", "SWR_MIC7", "TX SWR_INPUT"}, {"TX SMIC MUX0", "SWR_MIC7", "TX SWR_INPUT"},
{"TX SMIC MUX0", "SWR_MIC8", "TX SWR_INPUT"}, {"TX SMIC MUX0", "SWR_MIC8", "TX SWR_INPUT"},
{"TX SMIC MUX0", "SWR_MIC9", "TX SWR_INPUT"}, {"TX SMIC MUX0", "SWR_MIC9", "TX SWR_INPUT"},
{"TX SMIC MUX0", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX0", "SWR_MIC11", "TX SWR_INPUT"},
{"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"}, {"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"},
{"TX DMIC MUX1", "DMIC0", "TX DMIC0"}, {"TX DMIC MUX1", "DMIC0", "TX DMIC0"},
@@ -2046,8 +2201,6 @@ static const struct snd_soc_dapm_route tx_audio_map_common[] = {
{"TX SMIC MUX1", "SWR_MIC7", "TX SWR_INPUT"}, {"TX SMIC MUX1", "SWR_MIC7", "TX SWR_INPUT"},
{"TX SMIC MUX1", "SWR_MIC8", "TX SWR_INPUT"}, {"TX SMIC MUX1", "SWR_MIC8", "TX SWR_INPUT"},
{"TX SMIC MUX1", "SWR_MIC9", "TX SWR_INPUT"}, {"TX SMIC MUX1", "SWR_MIC9", "TX SWR_INPUT"},
{"TX SMIC MUX1", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX1", "SWR_MIC11", "TX SWR_INPUT"},
{"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"}, {"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"},
{"TX DMIC MUX2", "DMIC0", "TX DMIC0"}, {"TX DMIC MUX2", "DMIC0", "TX DMIC0"},
@@ -2070,8 +2223,6 @@ static const struct snd_soc_dapm_route tx_audio_map_common[] = {
{"TX SMIC MUX2", "SWR_MIC7", "TX SWR_INPUT"}, {"TX SMIC MUX2", "SWR_MIC7", "TX SWR_INPUT"},
{"TX SMIC MUX2", "SWR_MIC8", "TX SWR_INPUT"}, {"TX SMIC MUX2", "SWR_MIC8", "TX SWR_INPUT"},
{"TX SMIC MUX2", "SWR_MIC9", "TX SWR_INPUT"}, {"TX SMIC MUX2", "SWR_MIC9", "TX SWR_INPUT"},
{"TX SMIC MUX2", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX2", "SWR_MIC11", "TX SWR_INPUT"},
{"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"}, {"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"},
{"TX DMIC MUX3", "DMIC0", "TX DMIC0"}, {"TX DMIC MUX3", "DMIC0", "TX DMIC0"},
@@ -2094,11 +2245,35 @@ static const struct snd_soc_dapm_route tx_audio_map_common[] = {
{"TX SMIC MUX3", "SWR_MIC7", "TX SWR_INPUT"}, {"TX SMIC MUX3", "SWR_MIC7", "TX SWR_INPUT"},
{"TX SMIC MUX3", "SWR_MIC8", "TX SWR_INPUT"}, {"TX SMIC MUX3", "SWR_MIC8", "TX SWR_INPUT"},
{"TX SMIC MUX3", "SWR_MIC9", "TX SWR_INPUT"}, {"TX SMIC MUX3", "SWR_MIC9", "TX SWR_INPUT"},
};
static const struct snd_soc_dapm_route tx_audio_map_v2[] = {
{"TX SMIC MUX0", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX0", "SWR_MIC11", "TX SWR_INPUT"},
{"TX SMIC MUX1", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX1", "SWR_MIC11", "TX SWR_INPUT"},
{"TX SMIC MUX2", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX2", "SWR_MIC11", "TX SWR_INPUT"},
{"TX SMIC MUX3", "SWR_MIC10", "TX SWR_INPUT"}, {"TX SMIC MUX3", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX3", "SWR_MIC11", "TX SWR_INPUT"}, {"TX SMIC MUX3", "SWR_MIC11", "TX SWR_INPUT"},
}; };
static const struct snd_soc_dapm_route tx_audio_map_v3[] = { static const struct snd_soc_dapm_route tx_audio_map_v3[] = {
{"TX SMIC MUX0", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX0", "SWR_MIC11", "TX SWR_INPUT"},
{"TX SMIC MUX1", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX1", "SWR_MIC11", "TX SWR_INPUT"},
{"TX SMIC MUX2", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX2", "SWR_MIC11", "TX SWR_INPUT"},
{"TX SMIC MUX3", "SWR_MIC10", "TX SWR_INPUT"},
{"TX SMIC MUX3", "SWR_MIC11", "TX SWR_INPUT"},
{"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"}, {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"},
{"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"}, {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"},
{"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"}, {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"},
@@ -2238,6 +2413,39 @@ static const struct snd_soc_dapm_route tx_audio_map_v3[] = {
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"}, {"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
}; };
static const struct snd_soc_dapm_route tx_audio_map_v4[] = {
{"TX SMIC MUX0", "SWR_MIC10", "RX SWR TX MUX0"},
{"RX SWR TX MUX0", "SWR_MIC", "TX SWR_INPUT"},
{"RX SWR TX MUX0", "RX_SWR_TX_PCM_IN0", "RX_SWR_TX_PCM_IN0"},
{"TX SMIC MUX0", "SWR_MIC11", "RX SWR TX MUX1"},
{"RX SWR TX MUX1", "SWR_MIC", "TX SWR_INPUT"},
{"RX SWR TX MUX1", "RX_SWR_TX_PCM_IN1", "RX_SWR_TX_PCM_IN1"},
{"TX SMIC MUX1", "SWR_MIC10", "RX SWR TX MUX0"},
{"RX SWR TX MUX0", "SWR_MIC", "TX SWR_INPUT"},
{"RX SWR TX MUX0", "RX_SWR_TX_PCM_IN0", "RX_SWR_TX_PCM_IN0"},
{"TX SMIC MUX1", "SWR_MIC11", "RX SWR TX MUX1"},
{"RX SWR TX MUX1", "SWR_MIC", "TX SWR_INPUT"},
{"RX SWR TX MUX1", "RX_SWR_TX_PCM_IN1", "RX_SWR_TX_PCM_IN1"},
{"TX SMIC MUX2", "SWR_MIC10", "RX SWR TX MUX0"},
{"RX SWR TX MUX0", "SWR_MIC", "TX SWR_INPUT"},
{"RX SWR TX MUX0", "RX_SWR_TX_PCM_IN0", "RX_SWR_TX_PCM_IN0"},
{"TX SMIC MUX2", "SWR_MIC11", "RX SWR TX MUX1"},
{"RX SWR TX MUX1", "SWR_MIC", "TX SWR_INPUT"},
{"RX SWR TX MUX1", "RX_SWR_TX_PCM_IN1", "RX_SWR_TX_PCM_IN1"},
{"TX SMIC MUX3", "SWR_MIC10", "RX SWR TX MUX0"},
{"RX SWR TX MUX0", "SWR_MIC", "TX SWR_INPUT"},
{"RX SWR TX MUX0", "RX_SWR_TX_PCM_IN0", "RX_SWR_TX_PCM_IN0"},
{"TX SMIC MUX3", "SWR_MIC11", "RX SWR TX MUX1"},
{"RX SWR TX MUX1", "SWR_MIC", "TX SWR_INPUT"},
{"RX SWR TX MUX1", "RX_SWR_TX_PCM_IN1", "RX_SWR_TX_PCM_IN1"},
{"RX SWR TX MUX0", NULL, "TX_MCLK"},
{"RX SWR TX MUX1", NULL, "TX_MCLK"},
};
static const struct snd_soc_dapm_route tx_audio_map[] = { static const struct snd_soc_dapm_route tx_audio_map[] = {
{"TX_AIF1 CAP", NULL, "TX_MCLK"}, {"TX_AIF1 CAP", NULL, "TX_MCLK"},
{"TX_AIF2 CAP", NULL, "TX_MCLK"}, {"TX_AIF2 CAP", NULL, "TX_MCLK"},
@@ -3125,6 +3333,10 @@ static int tx_macro_init(struct snd_soc_component *component)
ret = snd_soc_dapm_new_controls(dapm, ret = snd_soc_dapm_new_controls(dapm,
tx_macro_dapm_widgets_v3, tx_macro_dapm_widgets_v3,
ARRAY_SIZE(tx_macro_dapm_widgets_v3)); ARRAY_SIZE(tx_macro_dapm_widgets_v3));
else if (tx_priv->version == BOLERO_VERSION_2_2)
ret = snd_soc_dapm_new_controls(dapm,
tx_macro_dapm_widgets_v4,
ARRAY_SIZE(tx_macro_dapm_widgets_v4));
if (ret < 0) { if (ret < 0) {
dev_err(tx_dev, "%s: Failed to add controls\n", dev_err(tx_dev, "%s: Failed to add controls\n",
__func__); __func__);
@@ -3149,10 +3361,18 @@ static int tx_macro_init(struct snd_soc_component *component)
__func__); __func__);
return ret; return ret;
} }
if (tx_priv->version == BOLERO_VERSION_2_1)
ret = snd_soc_dapm_add_routes(dapm,
tx_audio_map_v2,
ARRAY_SIZE(tx_audio_map_v2));
if (tx_priv->version == BOLERO_VERSION_2_0) if (tx_priv->version == BOLERO_VERSION_2_0)
ret = snd_soc_dapm_add_routes(dapm, ret = snd_soc_dapm_add_routes(dapm,
tx_audio_map_v3, tx_audio_map_v3,
ARRAY_SIZE(tx_audio_map_v3)); ARRAY_SIZE(tx_audio_map_v3));
if (tx_priv->version == BOLERO_VERSION_2_2)
ret = snd_soc_dapm_add_routes(dapm,
tx_audio_map_v4,
ARRAY_SIZE(tx_audio_map_v4));
if (ret < 0) { if (ret < 0) {
dev_err(tx_dev, "%s: Failed to add routes\n", dev_err(tx_dev, "%s: Failed to add routes\n",
__func__); __func__);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -180,6 +180,7 @@ struct va_macro_priv {
int dec_mode[VA_MACRO_NUM_DECIMATORS]; int dec_mode[VA_MACRO_NUM_DECIMATORS];
u16 current_clk_id; u16 current_clk_id;
int pcm_rate[VA_MACRO_NUM_DECIMATORS]; int pcm_rate[VA_MACRO_NUM_DECIMATORS];
bool dev_up;
}; };
static bool va_macro_get_data(struct snd_soc_component *component, static bool va_macro_get_data(struct snd_soc_component *component,
@@ -325,6 +326,7 @@ static int va_macro_event_handler(struct snd_soc_component *component,
trace_printk("%s, enter SSR up\n", __func__); trace_printk("%s, enter SSR up\n", __func__);
/* reset swr after ssr/pdr */ /* reset swr after ssr/pdr */
va_priv->reset_swr = true; va_priv->reset_swr = true;
va_priv->dev_up = true;
if (va_priv->swr_ctrl_data) if (va_priv->swr_ctrl_data)
swrm_wcd_notify( swrm_wcd_notify(
va_priv->swr_ctrl_data[0].va_swr_pdev, va_priv->swr_ctrl_data[0].va_swr_pdev,
@@ -334,6 +336,7 @@ static int va_macro_event_handler(struct snd_soc_component *component,
bolero_rsc_clk_reset(va_dev, VA_CORE_CLK); bolero_rsc_clk_reset(va_dev, VA_CORE_CLK);
break; break;
case BOLERO_MACRO_EVT_SSR_DOWN: case BOLERO_MACRO_EVT_SSR_DOWN:
va_priv->dev_up = false;
if (va_priv->swr_ctrl_data) { if (va_priv->swr_ctrl_data) {
swrm_wcd_notify( swrm_wcd_notify(
va_priv->swr_ctrl_data[0].va_swr_pdev, va_priv->swr_ctrl_data[0].va_swr_pdev,
@@ -437,31 +440,31 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
} }
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
if (va_priv->current_clk_id == VA_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, 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,
true); true);
if (ret) { if (ret) {
dev_dbg(component->dev, dev_err(component->dev,
"%s: request clock TX_CLK disable failed\n", "%s: request clock TX_CLK enable failed\n",
__func__); __func__);
break; if (va_priv->dev_up)
break;
} }
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,
false); false);
if (ret) { if (ret) {
dev_dbg(component->dev, dev_err(component->dev,
"%s: request clock VA_CLK disable failed\n", "%s: request clock VA_CLK disable failed\n",
__func__); __func__);
bolero_clk_rsc_request_clock(va_priv->dev, if (va_priv->dev_up)
TX_CORE_CLK, bolero_clk_rsc_request_clock(va_priv->dev,
TX_CORE_CLK, TX_CORE_CLK,
false); TX_CORE_CLK,
false);
break; break;
} }
va_priv->current_clk_id = TX_CORE_CLK; va_priv->current_clk_id = TX_CORE_CLK;
@@ -1338,6 +1341,10 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w,
/* Disable TX CLK */ /* Disable TX CLK */
snd_soc_component_update_bits(component, tx_vol_ctl_reg, snd_soc_component_update_bits(component, tx_vol_ctl_reg,
0x20, 0x00); 0x20, 0x00);
snd_soc_component_update_bits(component, tx_vol_ctl_reg,
0x40, 0x40);
snd_soc_component_update_bits(component, tx_vol_ctl_reg,
0x40, 0x00);
snd_soc_component_update_bits(component, tx_vol_ctl_reg, snd_soc_component_update_bits(component, tx_vol_ctl_reg,
0x10, 0x00); 0x10, 0x00);
break; break;
@@ -2750,7 +2757,8 @@ static int va_macro_init(struct snd_soc_component *component)
__func__); __func__);
return ret; return ret;
} }
if (va_priv->version == BOLERO_VERSION_2_1) if ((va_priv->version == BOLERO_VERSION_2_1) ||
(va_priv->version == BOLERO_VERSION_2_2))
ret = snd_soc_dapm_new_controls(dapm, ret = snd_soc_dapm_new_controls(dapm,
va_macro_dapm_widgets_v2, va_macro_dapm_widgets_v2,
ARRAY_SIZE(va_macro_dapm_widgets_v2)); ARRAY_SIZE(va_macro_dapm_widgets_v2));
@@ -2792,7 +2800,8 @@ static int va_macro_init(struct snd_soc_component *component)
return ret; return ret;
} }
} }
if (va_priv->version == BOLERO_VERSION_2_1) { if ((va_priv->version == BOLERO_VERSION_2_1) ||
(va_priv->version == BOLERO_VERSION_2_2)) {
ret = snd_soc_dapm_add_routes(dapm, ret = snd_soc_dapm_add_routes(dapm,
va_audio_map_v2, va_audio_map_v2,
ARRAY_SIZE(va_audio_map_v2)); ARRAY_SIZE(va_audio_map_v2));
@@ -2867,6 +2876,8 @@ static int va_macro_init(struct snd_soc_component *component)
} }
snd_soc_dapm_sync(dapm); snd_soc_dapm_sync(dapm);
va_priv->dev_up = true;
for (i = 0; i < VA_MACRO_NUM_DECIMATORS; i++) { for (i = 0; i < VA_MACRO_NUM_DECIMATORS; i++) {
va_priv->va_hpf_work[i].va_priv = va_priv; va_priv->va_hpf_work[i].va_priv = va_priv;
va_priv->va_hpf_work[i].decimator = i; va_priv->va_hpf_work[i].decimator = i;
@@ -2882,7 +2893,8 @@ static int va_macro_init(struct snd_soc_component *component)
} }
va_priv->component = component; va_priv->component = component;
if (va_priv->version == BOLERO_VERSION_2_1) { if ((va_priv->version == BOLERO_VERSION_2_1) ||
(va_priv->version == BOLERO_VERSION_2_2)) {
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0, 0xEE, 0xCC); BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0, 0xEE, 0xCC);
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,

View File

@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef _WCD937X_INTERNAL_H #ifndef _WCD937X_INTERNAL_H
@@ -60,6 +61,7 @@ struct wcd937x_priv {
u32 hph_mode; u32 hph_mode;
bool comp1_enable; bool comp1_enable;
bool comp2_enable; bool comp2_enable;
bool bcs_dis;
struct irq_domain *virq; struct irq_domain *virq;
struct wcd_irq_info irq_info; struct wcd_irq_info irq_info;
@@ -93,6 +95,7 @@ struct wcd937x_priv {
struct snd_info_entry *variant_entry; struct snd_info_entry *variant_entry;
int ear_rx_path; int ear_rx_path;
int ana_clk_count; int ana_clk_count;
int adc_count;
struct mutex ana_tx_clk_lock; struct mutex ana_tx_clk_lock;
u8 tx_master_ch_map[WCD937X_MAX_SLAVE_CH_TYPES]; u8 tx_master_ch_map[WCD937X_MAX_SLAVE_CH_TYPES];
bool usbc_hs_status; bool usbc_hs_status;

View File

@@ -142,11 +142,6 @@ static int wcd937x_handle_post_irq(void *data)
struct wcd937x_priv *wcd937x = data; struct wcd937x_priv *wcd937x = data;
u32 status1 = 0, status2 = 0, status3 = 0; u32 status1 = 0, status2 = 0, status3 = 0;
/* Clear the ACK registers. Temporary workaround.*/
regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_0, 0x0);
regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_1, 0x0);
regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_2, 0x0);
regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &status1); regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &status1);
regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &status2); regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &status2);
regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_2, &status3); regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_2, &status3);
@@ -159,8 +154,20 @@ static int wcd937x_handle_post_irq(void *data)
static int wcd937x_init_reg(struct snd_soc_component *component) static int wcd937x_init_reg(struct snd_soc_component *component)
{ {
snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL, u32 val = 0;
val = snd_soc_component_read(component, WCD937X_DIGITAL_EFUSE_REG_29)
& 0x0F;
if (snd_soc_component_read(component, WCD937X_DIGITAL_EFUSE_REG_16)
== 0x02 || snd_soc_component_read(component,
WCD937X_DIGITAL_EFUSE_REG_17) > 0x09) {
snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL,
0x0E, val);
} else {
snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL,
0x0E, 0x0E); 0x0E, 0x0E);
}
snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL, snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL,
0x80, 0x80); 0x80, 0x80);
usleep_range(1000, 1010); usleep_range(1000, 1010);
@@ -187,6 +194,28 @@ static int wcd937x_init_reg(struct snd_soc_component *component)
0xFF, 0xFA); 0xFF, 0xFA);
snd_soc_component_update_bits(component, WCD937X_MICB3_TEST_CTL_1, snd_soc_component_update_bits(component, WCD937X_MICB3_TEST_CTL_1,
0xFF, 0xFA); 0xFF, 0xFA);
snd_soc_component_update_bits(component, WCD937X_MICB1_TEST_CTL_2,
0x38, 0x00);
snd_soc_component_update_bits(component, WCD937X_MICB2_TEST_CTL_2,
0x38, 0x00);
snd_soc_component_update_bits(component, WCD937X_MICB3_TEST_CTL_2,
0x38, 0x00);
/* Set Bandgap Fine Adjustment to +5mV for Tanggu SMIC part */
if (snd_soc_component_read(component, WCD937X_DIGITAL_EFUSE_REG_16)
== 0x01) {
snd_soc_component_update_bits(component,
WCD937X_BIAS_VBG_FINE_ADJ, 0xF0, 0xB0);
} else if (snd_soc_component_read(component,
WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) {
snd_soc_component_update_bits(component,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x1F, 0x04);
snd_soc_component_update_bits(component,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x1F, 0x04);
snd_soc_component_update_bits(component,
WCD937X_BIAS_VBG_FINE_ADJ, 0xF0, 0xB0);
snd_soc_component_update_bits(component,
WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xF0, 0x50);
}
return 0; return 0;
} }
@@ -551,6 +580,12 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); set_bit(HPH_COMP_DELAY, &wcd937x->status_mask);
break; break;
case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_POST_PMU:
if ((snd_soc_component_read(component,
WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) &&
((snd_soc_component_read(component,
WCD937X_ANA_HPH) & 0x0C) == 0x0C))
snd_soc_component_update_bits(component,
WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x90);
if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI)
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
@@ -592,6 +627,12 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00);
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
if ((snd_soc_component_read(component,
WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) &&
((snd_soc_component_read(component,
WCD937X_ANA_HPH) & 0x0C) == 0x0C))
snd_soc_component_update_bits(component,
WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x80);
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
0x0F, 0x01); 0x0F, 0x01);
@@ -625,6 +666,12 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); set_bit(HPH_COMP_DELAY, &wcd937x->status_mask);
break; break;
case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_POST_PMU:
if ((snd_soc_component_read(component,
WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) &&
((snd_soc_component_read(component,
WCD937X_ANA_HPH) & 0x0C) == 0x0C))
snd_soc_component_update_bits(component,
WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x90);
if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI)
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R,
@@ -666,6 +713,12 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00);
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
if ((snd_soc_component_read(component,
WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) &&
((snd_soc_component_read(component,
WCD937X_ANA_HPH) & 0x0C) == 0x0C))
snd_soc_component_update_bits(component,
WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x80);
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R,
0x0F, 0x01); 0x0F, 0x01);
@@ -1413,8 +1466,12 @@ static int wcd937x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
/* Enable BCS for Headset mic */ /* Enable BCS for Headset mic */
if (w->shift == 1 && !(snd_soc_component_read(component, if (w->shift == 1 && !(snd_soc_component_read(component,
WCD937X_TX_NEW_TX_CH2_SEL) & 0x80)) { WCD937X_TX_NEW_TX_CH2_SEL) & 0x80)) {
wcd937x_tx_connect_port(component, MBHC, true); if (!wcd937x->bcs_dis) {
set_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask); wcd937x_tx_connect_port(
component, MBHC, true);
set_bit(AMIC2_BCS_ENABLE,
&wcd937x->status_mask);
}
} }
wcd937x_tx_connect_port(component, ADC1 + (w->shift), true); wcd937x_tx_connect_port(component, ADC1 + (w->shift), true);
} else { } else {
@@ -1449,6 +1506,7 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w,
mutex_lock(&wcd937x->ana_tx_clk_lock); mutex_lock(&wcd937x->ana_tx_clk_lock);
wcd937x->ana_clk_count++; wcd937x->ana_clk_count++;
mutex_unlock(&wcd937x->ana_tx_clk_lock); mutex_unlock(&wcd937x->ana_tx_clk_lock);
wcd937x->adc_count++;
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80);
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
@@ -1466,8 +1524,13 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w,
wcd937x_tx_connect_port(component, MBHC, false); wcd937x_tx_connect_port(component, MBHC, false);
clear_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask); clear_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask);
} }
snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); wcd937x->adc_count--;
if (wcd937x->adc_count <= 0) {
snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00);
wcd937x->adc_count = 0;
}
break; break;
}; };
@@ -1507,14 +1570,19 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w,
WCD937X_ANA_TX_CH3, 0x80, 0x80); WCD937X_ANA_TX_CH3, 0x80, 0x80);
break; break;
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
snd_soc_component_update_bits(component, if (wcd937x->adc_count == 0) {
snd_soc_component_update_bits(component,
WCD937X_ANA_TX_CH1, 0x80, 0x00); WCD937X_ANA_TX_CH1, 0x80, 0x00);
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
WCD937X_ANA_TX_CH2, 0x80, 0x00); WCD937X_ANA_TX_CH2, 0x80, 0x00);
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
WCD937X_ANA_TX_CH3, 0x80, 0x00); WCD937X_ANA_TX_CH3, 0x80, 0x00);
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00); WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00);
snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00);
}
mutex_lock(&wcd937x->ana_tx_clk_lock); mutex_lock(&wcd937x->ana_tx_clk_lock);
wcd937x->ana_clk_count--; wcd937x->ana_clk_count--;
if (wcd937x->ana_clk_count <= 0) { if (wcd937x->ana_clk_count <= 0) {
@@ -1524,8 +1592,6 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w,
} }
mutex_unlock(&wcd937x->ana_tx_clk_lock); mutex_unlock(&wcd937x->ana_tx_clk_lock);
snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00);
break; break;
}; };
return 0; return 0;
@@ -2185,6 +2251,29 @@ static int wcd937x_tx_master_ch_put(struct snd_kcontrol *kcontrol,
return 0; return 0;
} }
static int wcd937x_bcs_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
ucontrol->value.integer.value[0] = wcd937x->bcs_dis;
return 0;
}
static int wcd937x_bcs_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
wcd937x->bcs_dis = ucontrol->value.integer.value[0];
dev_dbg(component->dev, "%s: BCS Disable %d\n", __func__, wcd937x->bcs_dis);
return 0;
}
static const char * const wcd937x_tx_ch_pwr_level_text[] = { static const char * const wcd937x_tx_ch_pwr_level_text[] = {
"L0", "L1", "L2", "L3", "L0", "L1", "L2", "L3",
}; };
@@ -2216,6 +2305,8 @@ static const struct snd_kcontrol_new wcd937x_snd_controls[] = {
wcd937x_get_compander, wcd937x_set_compander), wcd937x_get_compander, wcd937x_set_compander),
SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0,
wcd937x_get_compander, wcd937x_set_compander), wcd937x_get_compander, wcd937x_set_compander),
SOC_SINGLE_EXT("ADC2_BCS Disable", SND_SOC_NOPM, 0, 1, 0,
wcd937x_bcs_get, wcd937x_bcs_put),
SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 20, 1, line_gain),
SOC_SINGLE_TLV("HPHR Volume", WCD937X_HPH_R_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD937X_HPH_R_EN, 0, 20, 1, line_gain),
@@ -2846,6 +2937,8 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component)
component, WCD937X_DIGITAL_EFUSE_REG_0) & 0x1E) >> 1; component, WCD937X_DIGITAL_EFUSE_REG_0) & 0x1E) >> 1;
wcd937x->variant = variant; wcd937x->variant = variant;
wcd937x->adc_count = 0;
wcd937x->fw_data = devm_kzalloc(component->dev, wcd937x->fw_data = devm_kzalloc(component->dev,
sizeof(*(wcd937x->fw_data)), sizeof(*(wcd937x->fw_data)),
GFP_KERNEL); GFP_KERNEL);

View File

@@ -1233,12 +1233,12 @@ static const struct snd_soc_component_driver soc_codec_dev_wsa881x = {
static struct snd_soc_dai_driver wsa_dai[] = { static struct snd_soc_dai_driver wsa_dai[] = {
{ {
.name = "", .name = "wsa_rx0",
.playback = { .playback = {
.stream_name = "", .stream_name = "",
.rates = WSA881X_RATES | WSA881X_FRAC_RATES, .rates = WSA881X_RATES | WSA881X_FRAC_RATES,
.formats = WSA881X_FORMATS, .formats = WSA881X_FORMATS,
.rate_max = 192000, .rate_max = 384000,
.rate_min = 8000, .rate_min = 8000,
.channels_min = 1, .channels_min = 1,
.channels_max = 2, .channels_max = 2,

View File

@@ -1774,7 +1774,16 @@ err:
static int msm_asoc_machine_remove(struct platform_device *pdev) static int msm_asoc_machine_remove(struct platform_device *pdev)
{ {
struct snd_soc_card *card = platform_get_drvdata(pdev); struct snd_soc_card *card = platform_get_drvdata(pdev);
struct msm_asoc_mach_data *pdata = NULL;
struct msm_common_pdata *common_pdata = NULL;
if (card)
pdata = snd_soc_card_get_drvdata(card);
if (pdata)
common_pdata = pdata->common_pdata;
msm_common_snd_deinit(common_pdata);
snd_event_master_deregister(&pdev->dev); snd_event_master_deregister(&pdev->dev);
snd_soc_unregister_card(card); snd_soc_unregister_card(card);

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2020, The Linux Foundation. All rights reserved. * Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
/* from Slave to bolero events */ /* from Slave to bolero events */
@@ -24,4 +25,5 @@ enum {
BOLERO_SLV_EVT_PA_ON_POST_FSCLK, BOLERO_SLV_EVT_PA_ON_POST_FSCLK,
BOLERO_SLV_EVT_PA_ON_POST_FSCLK_ADIE_LB, BOLERO_SLV_EVT_PA_ON_POST_FSCLK_ADIE_LB,
BOLERO_SLV_EVT_CLK_NOTIFY, BOLERO_SLV_EVT_CLK_NOTIFY,
BOLERO_SLV_EVT_RX_MACRO_PA_ON,
}; };