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

Change-Id: I58fbdf6b91c33ab5d147efbe5f5706616052c7fe
Signed-off-by: Vidyakumar Athota <vathota@codeaurora.org>
This commit is contained in:
Vidyakumar Athota
2020-09-06 18:16:18 -07:00
53 changed files with 9168 additions and 309 deletions

View File

@@ -18,6 +18,9 @@ endif
ifeq ($(CONFIG_ARCH_LAHAINA), y)
include $(srctree)/techpack/audio/config/lahainaauto.conf
endif
ifeq ($(CONFIG_ARCH_HOLI), y)
include $(srctree)/techpack/audio/config/holiauto.conf
endif
endif
# Use USERINCLUDE when you must reference the UAPI directories only.
@@ -51,6 +54,10 @@ ifeq ($(CONFIG_ARCH_LAHAINA), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/audio/config/lahainaautoconf.h
endif
ifeq ($(CONFIG_ARCH_HOLI), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/audio/config/holiautoconf.h
endif
obj-y += soc/
obj-y += dsp/

View File

@@ -18,6 +18,8 @@ ifeq ($(TARGET_SUPPORT), sdmsteppe)
KBUILD_OPTIONS += CONFIG_ARCH_SM6150=y
endif
subdir-ccflags-y += -I$(AUDIO_ROOT)/include/uapi/
obj-m := ipc/
obj-m += dsp/
obj-m += soc/
@@ -50,6 +52,10 @@ KBUILD_OPTIONS += CONFIG_SND_SOC_SA6155=m
endif
endif
define PROCESS_HEADERS
$(foreach name,$(1),$(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(2)$(name) $(3)$(name)))
endef
all:
$(shell rm -fr $(shell pwd)/soc/core.h)
$(shell ln -s $(KERNEL_SRC)/drivers/pinctrl/core.h $(shell pwd)/soc/core.h)
@@ -61,15 +67,17 @@ all:
$(shell mkdir $(shell pwd)/sound)
$(shell mkdir $(shell pwd)/linux/mfd)
$(shell mkdir $(shell pwd)/linux/mfd/wcd9xxx)
$(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/audio/linux/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH1)))
$(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(UAPI_OUT)/linux/mfd/wcd9xxx/ $(AUDIO_ROOT)/include/uapi/audio/linux/mfd/wcd9xxx/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH2)))
$(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/audio/sound/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH3)))
$(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/sound)
$(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/linux/mfd)
$(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/linux/mfd/wcd9xxx)
$(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(KERNEL_BINARY_DIR)/usr/include/linux/ $(AUDIO_ROOT)/include/uapi/audio/linux/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH1)))
$(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(KERNEL_BINARY_DIR)/usr/include/linux/mfd/wcd9xxx/ $(AUDIO_ROOT)/include/uapi/audio/linux/mfd/wcd9xxx/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH2)))
$(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(KERNEL_BINARY_DIR)/usr/include/sound/ $(AUDIO_ROOT)/include/uapi/audio/sound/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH3)))
$(call PROCESS_HEADERS, $(notdir $(shell ls $(AUDIO_ROOT)/include/uapi/audio/linux/*.h)), $(AUDIO_ROOT)/include/uapi/audio/linux/, $(UAPI_OUT)/linux/)
$(call PROCESS_HEADERS, $(notdir $(shell ls $(AUDIO_ROOT)/include/uapi/audio/linux/mfd/wcd9xxx/*.h)), $(AUDIO_ROOT)/include/uapi/audio/linux/mfd/wcd9xxx/, $(UAPI_OUT)/linux/mfd/wcd9xxx/)
$(call PROCESS_HEADERS, $(notdir $(shell ls $(AUDIO_ROOT)/include/uapi/audio/sound/*.h)), $(AUDIO_ROOT)/include/uapi/audio/sound/, $(UAPI_OUT)/sound/)
$(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/audio)
$(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/audio/sound)
$(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/audio/linux)
$(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/audio/linux/mfd)
$(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/audio/linux/mfd/wcd9xxx)
$(call PROCESS_HEADERS, $(notdir $(shell ls $(AUDIO_ROOT)/include/uapi/audio/linux/*.h)), $(AUDIO_ROOT)/include/uapi/audio/linux/, $(KERNEL_BINARY_DIR)/usr/include/audio/linux/)
$(call PROCESS_HEADERS, $(notdir $(shell ls $(AUDIO_ROOT)/include/uapi/audio/linux/mfd/wcd9xxx/*.h)), $(AUDIO_ROOT)/include/uapi/audio/linux/mfd/wcd9xxx/, $(KERNEL_BINARY_DIR)/usr/include/audio/linux/mfd/wcd9xxx/)
$(call PROCESS_HEADERS, $(notdir $(shell ls $(AUDIO_ROOT)/include/uapi/audio/sound/*.h)), $(AUDIO_ROOT)/include/uapi/audio/sound/, $(KERNEL_BINARY_DIR)/usr/include/audio/sound/)
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
modules_install:

View File

@@ -138,6 +138,11 @@ ifdef CONFIG_SND_SOC_LAHAINA
MACHINE_OBJS += lahaina.o
endif
# for HOLI sound card driver
ifdef CONFIG_SND_SOC_HOLI
MACHINE_OBJS += holi.o
endif
ifdef CONFIG_SND_SOC_LITO
MACHINE_OBJS += kona.o
endif
@@ -219,6 +224,9 @@ machine_dlkm-y := $(MACHINE_OBJS)
obj-$(CONFIG_SND_SOC_LAHAINA) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
obj-$(CONFIG_SND_SOC_HOLI) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
obj-$(CONFIG_SND_SOC_LITO) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)

View File

@@ -805,6 +805,8 @@ static bool bolero_is_volatile_register(struct device *dev,
case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL:
case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL:
case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL:
case BOLERO_CDC_TX_TOP_CSR_SWR_MIC0_CTL:
case BOLERO_CDC_TX_TOP_CSR_SWR_MIC1_CTL:
case BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL:
case BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST:
case BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0:

View File

@@ -232,6 +232,27 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data)
priv->component,
BOLERO_MACRO_EVT_BCS_CLK_OFF, data);
break;
case WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE:
/* Update PA Gain only for bolero version 2.1 */
if (priv->version == BOLERO_VERSION_2_1)
if (priv->macro_params[RX_MACRO].event_handler)
priv->macro_params[RX_MACRO].event_handler(
priv->component,
BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE,
data);
break;
case WCD_BOLERO_EVT_HPHL_HD2_ENABLE:
if (priv->macro_params[RX_MACRO].event_handler)
priv->macro_params[RX_MACRO].event_handler(
priv->component,
BOLERO_MACRO_EVT_HPHL_HD2_ENABLE, data);
break;
case WCD_BOLERO_EVT_HPHR_HD2_ENABLE:
if (priv->macro_params[RX_MACRO].event_handler)
priv->macro_params[RX_MACRO].event_handler(
priv->component,
BOLERO_MACRO_EVT_HPHR_HD2_ENABLE, data);
break;
default:
dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n",
__func__, event);
@@ -755,7 +776,7 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id)
}
EXPORT_SYMBOL(bolero_unregister_macro);
void bolero_wsa_pa_on(struct device *dev)
void bolero_wsa_pa_on(struct device *dev, bool adie_lb)
{
struct bolero_priv *priv;
@@ -773,8 +794,12 @@ void bolero_wsa_pa_on(struct device *dev)
dev_err(dev, "%s: priv is null\n", __func__);
return;
}
bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_ON_POST_FSCLK);
if (adie_lb)
bolero_cdc_notifier_call(priv,
BOLERO_WCD_EVT_PA_ON_POST_FSCLK_ADIE_LB);
else
bolero_cdc_notifier_call(priv,
BOLERO_WCD_EVT_PA_ON_POST_FSCLK);
}
EXPORT_SYMBOL(bolero_wsa_pa_on);

View File

@@ -50,6 +50,9 @@ enum {
BOLERO_MACRO_EVT_BCS_CLK_OFF,
BOLERO_MACRO_EVT_SSR_GFMUX_UP,
BOLERO_MACRO_EVT_PRE_SSR_UP,
BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE,
BOLERO_MACRO_EVT_HPHL_HD2_ENABLE, /* Enable HD2 cfg for HPHL */
BOLERO_MACRO_EVT_HPHR_HD2_ENABLE, /* Enable HD2 cfg for HPHR */
};
enum {
@@ -99,7 +102,7 @@ int bolero_runtime_suspend(struct device *dev);
int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data);
int bolero_register_event_listener(struct snd_soc_component *component,
bool enable);
void bolero_wsa_pa_on(struct device *dev);
void bolero_wsa_pa_on(struct device *dev, bool adie_lb);
bool bolero_check_core_votes(struct device *dev);
int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable);
int bolero_get_version(struct device *dev);
@@ -176,7 +179,7 @@ static inline int bolero_register_event_listener(
return 0;
}
static void bolero_wsa_pa_on(struct device *dev)
static void bolero_wsa_pa_on(struct device *dev, bool adie_lb)
{
}

View File

@@ -16,6 +16,7 @@ enum {
BOLERO_WCD_EVT_SSR_DOWN,
BOLERO_WCD_EVT_SSR_UP,
BOLERO_WCD_EVT_PA_ON_POST_FSCLK,
BOLERO_WCD_EVT_PA_ON_POST_FSCLK_ADIE_LB,
};
enum {
@@ -32,6 +33,9 @@ enum {
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE,
WCD_BOLERO_EVT_HPHL_HD2_ENABLE, /* to enable hd2 config for hphl */
WCD_BOLERO_EVT_HPHR_HD2_ENABLE, /* to enable hd2 config for hphr */
};
struct wcd_ctrl_platform_data {

View File

@@ -78,6 +78,11 @@ static const struct snd_kcontrol_new name##_mux = \
#define RX_MACRO_EC_MIX_TX1_MASK 0x0f
#define RX_MACRO_EC_MIX_TX2_MASK 0x0f
#define RX_MACRO_GAIN_MAX_VAL 0x28
#define RX_MACRO_GAIN_VAL_UNITY 0x0
/* Define macros to increase PA Gain by half */
#define RX_MACRO_MOD_GAIN (RX_MACRO_GAIN_VAL_UNITY + 6)
#define COMP_MAX_COEFF 25
struct wcd_imped_val {
@@ -454,6 +459,8 @@ struct rx_macro_priv {
struct rx_macro_bcl_pmic_params bcl_pmic_params;
u16 clk_id;
u16 default_clk_id;
int8_t rx0_gain_val;
int8_t rx1_gain_val;
};
static struct snd_soc_dai_driver rx_macro_dai[];
@@ -1460,6 +1467,56 @@ static int rx_macro_event_handler(struct snd_soc_component *component,
case BOLERO_MACRO_EVT_CLK_RESET:
bolero_rsc_clk_reset(rx_dev, RX_CORE_CLK);
break;
case BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE:
rx_priv->rx0_gain_val = snd_soc_component_read32(component,
BOLERO_CDC_RX_RX0_RX_VOL_CTL);
rx_priv->rx1_gain_val = snd_soc_component_read32(component,
BOLERO_CDC_RX_RX1_RX_VOL_CTL);
if (data) {
/* Reduce gain by half only if its greater than -6DB */
if ((rx_priv->rx0_gain_val >= RX_MACRO_GAIN_VAL_UNITY)
&& (rx_priv->rx0_gain_val <= RX_MACRO_GAIN_MAX_VAL))
snd_soc_component_update_bits(component,
BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xFF,
(rx_priv->rx0_gain_val -
RX_MACRO_MOD_GAIN));
if ((rx_priv->rx1_gain_val >= RX_MACRO_GAIN_VAL_UNITY)
&& (rx_priv->rx1_gain_val <= RX_MACRO_GAIN_MAX_VAL))
snd_soc_component_update_bits(component,
BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xFF,
(rx_priv->rx1_gain_val -
RX_MACRO_MOD_GAIN));
}
else {
/* Reset gain value to default */
if ((rx_priv->rx0_gain_val >=
(RX_MACRO_GAIN_VAL_UNITY - RX_MACRO_MOD_GAIN)) &&
(rx_priv->rx0_gain_val <= (RX_MACRO_GAIN_MAX_VAL -
RX_MACRO_MOD_GAIN)))
snd_soc_component_update_bits(component,
BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xFF,
(rx_priv->rx0_gain_val +
RX_MACRO_MOD_GAIN));
if ((rx_priv->rx1_gain_val >=
(RX_MACRO_GAIN_VAL_UNITY - RX_MACRO_MOD_GAIN)) &&
(rx_priv->rx1_gain_val <= (RX_MACRO_GAIN_MAX_VAL -
RX_MACRO_MOD_GAIN)))
snd_soc_component_update_bits(component,
BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xFF,
(rx_priv->rx1_gain_val +
RX_MACRO_MOD_GAIN));
}
break;
case BOLERO_MACRO_EVT_HPHL_HD2_ENABLE:
/* Enable hd2 config for hphl*/
snd_soc_component_update_bits(component,
BOLERO_CDC_RX_RX0_RX_PATH_CFG0, 0x04, data);
break;
case BOLERO_MACRO_EVT_HPHR_HD2_ENABLE:
/* Enable hd2 config for hphr*/
snd_soc_component_update_bits(component,
BOLERO_CDC_RX_RX1_RX_PATH_CFG0, 0x04, data);
break;
}
done:
return ret;
@@ -3877,6 +3934,8 @@ static int rx_macro_init(struct snd_soc_component *component)
return ret;
}
rx_priv->dev_up = true;
rx_priv->rx0_gain_val = 0;
rx_priv->rx1_gain_val = 0;
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF1 Playback");
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback");
snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback");
@@ -4106,6 +4165,8 @@ static int rx_macro_probe(struct platform_device *pdev)
__func__);
return -EPROBE_DEFER;
}
msm_cdc_pinctrl_set_wakeup_capable(
rx_priv->rx_swr_gpio_p, false);
rx_io_base = devm_ioremap(&pdev->dev, rx_base_addr,
RX_MACRO_MAX_OFFSET);

View File

@@ -177,6 +177,8 @@ struct tx_macro_priv {
bool bcs_clk_en;
bool hs_slow_insert_complete;
int amic_sample_rate;
bool lpi_enable;
bool register_event_listener;
};
static bool tx_macro_get_data(struct snd_soc_component *component,
@@ -235,11 +237,11 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv,
}
bolero_clk_rsc_fs_gen_request(tx_priv->dev,
true);
regcache_mark_dirty(regmap);
regcache_sync_region(regmap,
TX_START_OFFSET,
TX_MAX_OFFSET);
if (tx_priv->tx_mclk_users == 0) {
regcache_mark_dirty(regmap);
regcache_sync_region(regmap,
TX_START_OFFSET,
TX_MAX_OFFSET);
/* 9.6MHz MCLK, set value 0x00 if other frequency */
regmap_update_bits(regmap,
BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01);
@@ -330,6 +332,45 @@ static int tx_macro_tx_swr_clk_event(struct snd_soc_dapm_widget *w,
return 0;
}
static int tx_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
int ret = 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;
dev_dbg(tx_dev, "%s: event = %d, lpi_enable = %d\n",
__func__, event, tx_priv->lpi_enable);
if (!tx_priv->lpi_enable)
return ret;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (tx_priv->lpi_enable) {
bolero_register_event_listener(component, true);
tx_priv->register_event_listener = true;
}
break;
case SND_SOC_DAPM_POST_PMD:
if (tx_priv->register_event_listener) {
tx_priv->register_event_listener = false;
bolero_register_event_listener(component, false);
}
break;
default:
dev_err(tx_priv->dev,
"%s: invalid DAPM event %d\n", __func__, event);
ret = -EINVAL;
}
return ret;
}
static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -784,6 +825,38 @@ static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol,
return 0;
}
static int tx_macro_lpi_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
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;
ucontrol->value.integer.value[0] = tx_priv->lpi_enable;
return 0;
}
static int tx_macro_lpi_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
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;
tx_priv->lpi_enable = ucontrol->value.integer.value[0];
return 0;
}
static int tx_macro_bcs_ch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -1675,6 +1748,10 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_common[] = {
SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY_S("TX_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
tx_macro_swr_pwr_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v2[] = {
@@ -2144,6 +2221,19 @@ static const struct snd_soc_dapm_route tx_audio_map_v3[] = {
{"TX SMIC MUX5", NULL, "TX_SWR_CLK"},
{"TX SMIC MUX6", NULL, "TX_SWR_CLK"},
{"TX SMIC MUX7", NULL, "TX_SWR_CLK"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
};
static const struct snd_soc_dapm_route tx_audio_map[] = {
@@ -2406,6 +2496,9 @@ static const struct snd_kcontrol_new tx_macro_snd_controls_common[] = {
BOLERO_CDC_TX3_TX_VOL_CTL,
-84, 40, digital_gain),
SOC_SINGLE_EXT("TX LPI Enable", 0, 0, 1, 0,
tx_macro_lpi_get, tx_macro_lpi_put),
SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
tx_macro_dec_mode_get, tx_macro_dec_mode_put),
@@ -2937,6 +3030,8 @@ static int tx_macro_init(struct snd_soc_component *component)
"%s: priv is null for macro!\n", __func__);
return -EINVAL;
}
tx_priv->lpi_enable = false;
tx_priv->register_event_listener = false;
tx_priv->version = bolero_get_version(tx_dev);
if (tx_priv->version >= BOLERO_VERSION_2_0) {
ret = snd_soc_dapm_new_controls(dapm,

View File

@@ -173,6 +173,7 @@ struct va_macro_priv {
bool lpi_enable;
bool register_event_listener;
int dec_mode[VA_MACRO_NUM_DECIMATORS];
int disable_afe_wakeup_event_listener;
};
static bool va_macro_get_data(struct snd_soc_component *component,
@@ -435,7 +436,8 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
"%s: lpass audio hw enable failed\n",
__func__);
}
if (va_priv->lpi_enable) {
if (va_priv->lpi_enable &&
!va_priv->disable_afe_wakeup_event_listener) {
bolero_register_event_listener(component, true);
va_priv->register_event_listener = true;
}
@@ -2992,7 +2994,10 @@ static int va_macro_probe(struct platform_device *pdev)
u32 default_clk_id = 0;
struct clk *lpass_audio_hw_vote = NULL;
u32 is_used_va_swr_gpio = 0;
u32 disable_afe_wakeup_event_listener = 0;
const char *is_used_va_swr_gpio_dt = "qcom,is-used-swr-gpio";
const char *disable_afe_wakeup_event_listener_dt =
"qcom,disable-afe-wakeup-event-listener";
va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv),
GFP_KERNEL);
@@ -3034,6 +3039,19 @@ static int va_macro_probe(struct platform_device *pdev)
is_used_va_swr_gpio = 0;
}
}
if (of_find_property(pdev->dev.of_node,
disable_afe_wakeup_event_listener_dt, NULL)) {
ret = of_property_read_u32(pdev->dev.of_node,
disable_afe_wakeup_event_listener_dt,
&disable_afe_wakeup_event_listener);
if (ret)
dev_dbg(&pdev->dev, "%s: error reading %s in dt\n",
__func__, disable_afe_wakeup_event_listener_dt);
}
va_priv->disable_afe_wakeup_event_listener =
disable_afe_wakeup_event_listener;
va_priv->va_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
"qcom,va-swr-gpios", 0);
if (!va_priv->va_swr_gpio_p && is_used_va_swr_gpio) {

View File

@@ -843,6 +843,7 @@ static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute)
uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0;
u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
bool adie_lb = false;
if (mute)
return 0;
@@ -879,7 +880,7 @@ static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute)
}
}
}
bolero_wsa_pa_on(wsa_dev);
bolero_wsa_pa_on(wsa_dev, adie_lb);
break;
default:
break;
@@ -1470,6 +1471,7 @@ static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w,
u16 reg = 0;
struct device *wsa_dev = NULL;
struct wsa_macro_priv *wsa_priv = NULL;
bool adie_lb = false;
if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
return -EINVAL;
@@ -1480,9 +1482,10 @@ static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (wsa_macro_adie_lb(component, w->shift)) {
adie_lb = true;
snd_soc_component_update_bits(component,
reg, 0x20, 0x20);
bolero_wsa_pa_on(wsa_dev);
bolero_wsa_pa_on(wsa_dev, adie_lb);
}
break;
default:
@@ -2561,10 +2564,10 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM,
0, 0, &rx1_mix_mux, wsa_macro_enable_mix_path,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM,
SND_SOC_DAPM_PGA_E("WSA_RX INT0 MIX", SND_SOC_NOPM,
0, 0, NULL, 0, wsa_macro_enable_main_path,
SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM,
SND_SOC_DAPM_PGA_E("WSA_RX INT1 MIX", SND_SOC_NOPM,
1, 0, NULL, 0, wsa_macro_enable_main_path,
SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),

View File

@@ -173,6 +173,52 @@ bool msm_cdc_is_ondemand_supply(struct device *dev,
}
EXPORT_SYMBOL(msm_cdc_is_ondemand_supply);
/*
* msm_cdc_set_supply_min_voltage:
* Set min supply voltage for particular supply
*
* @dev: pointer to codec device
* @supplies: pointer to regulator bulk data
* @cdc_vreg: pointer to platform regulator data
* @num_supplies: number of supplies
* @supply_name: Supply name to change voltage for
* @vval_min: Min voltage to be set in uV
* @override_min_vol: True if override min voltage from default
* Return error code if unable to set voltage
*/
int msm_cdc_set_supply_min_voltage(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies, char *supply_name,
int vval_min, bool override_min_vol)
{
int rc = 0, i;
if ((!supply_name) || (!supplies)) {
pr_err("%s: either dev or supplies or cdc_vreg is NULL\n",
__func__);
return -EINVAL;
}
/* input parameter validation */
rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
if (rc)
return rc;
for (i = 0; i < num_supplies; i++) {
if (!strcmp(cdc_vreg[i].name, supply_name)) {
if (override_min_vol)
regulator_set_voltage(supplies[i].consumer,
vval_min, cdc_vreg[i].max_uV);
else
regulator_set_voltage(supplies[i].consumer,
cdc_vreg[i].min_uV, cdc_vreg[i].max_uV);
break;
}
}
return rc;
}
EXPORT_SYMBOL(msm_cdc_set_supply_min_voltage);
/*
* msm_cdc_disable_ondemand_supply:
* Disable codec ondemand supply

View File

@@ -224,7 +224,7 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol,
if (!codec_data->ext_disp_ops.get_audio_edid_blk ||
!codec_data->ext_disp_ops.get_intf_id || rc) {
dev_err(component->dev, "%s: get_audio_edid_blk() or get_intf_id is NULL\n",
dev_err_ratelimited(component->dev, "%s: get_audio_edid_blk() or get_intf_id is NULL\n",
__func__);
rc = -EINVAL;
goto cable_err;

View File

@@ -85,6 +85,11 @@ struct rouleur_priv {
struct mutex main_bias_lock;
bool dev_up;
bool usbc_hs_status;
struct notifier_block psy_nb;
struct work_struct soc_eval_work;
bool low_soc;
int foundry_id_reg;
int foundry_id;
};
struct rouleur_micbias_setting {
@@ -102,6 +107,7 @@ struct rouleur_pdata {
struct cdc_regulator *regulator;
int num_supplies;
int reset_reg;
int foundry_id_reg;
};
struct wcd_ctrl_platform_data {
@@ -131,6 +137,9 @@ enum {
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE, /* To reduce PA gain for low SoC */
WCD_BOLERO_EVT_HPHL_HD2_ENABLE, /* to enable hd2 config for hphl */
WCD_BOLERO_EVT_HPHR_HD2_ENABLE, /* to enable hd2 config for hphr */
};
enum {

View File

@@ -7,11 +7,16 @@
#ifdef CONFIG_PM2250_SPMI
int pm2250_spmi_write(struct device *dev, int reg, int value);
int pm2250_spmi_read(struct device *dev, int reg, int *value);
#else
int pm2250_spmi_write(struct device *dev, int reg, int value)
{
return 0;
}
int pm2250_spmi_read(struct device *dev, int reg, int *value);
{
return 0;
}
#endif /* CONFIG_PM2250_SPMI */
#endif

View File

@@ -25,6 +25,12 @@ static const struct of_device_id pm2250_id_table[] = {
};
MODULE_DEVICE_TABLE(of, pm2250_id_table);
/**
* pm2250_spmi_write: Function to write to PMIC register
* @device: node for rouleur device
* @reg: PMIC register to write value
* @value: Value to be written to PMIC register
*/
int pm2250_spmi_write(struct device *dev, int reg, int value)
{
int rc;
@@ -47,6 +53,34 @@ int pm2250_spmi_write(struct device *dev, int reg, int value)
}
EXPORT_SYMBOL(pm2250_spmi_write);
/**
* pm2250_spmi_read: Function to read PMIC register
* @device: node for rouleur device
* @reg: PMIC register to read value
* @value: Pointer to value of reg to be read
*/
int pm2250_spmi_read(struct device *dev, int reg, int *value)
{
int rc;
struct pm2250_spmi *spmi_dd;
if (!of_device_is_compatible(dev->of_node, "qcom,pm2250-spmi")) {
pr_err("%s: Device node is invalid\n", __func__);
return -EINVAL;
}
spmi_dd = dev_get_drvdata(dev);
if (!spmi_dd)
return -EINVAL;
rc = regmap_read(spmi_dd->regmap, reg, value);
if (rc)
dev_err(dev, "%s: Read from PMIC register failed\n", __func__);
return rc;
}
EXPORT_SYMBOL(pm2250_spmi_read);
static int pm2250_spmi_probe(struct platform_device *pdev)
{
struct pm2250_spmi *spmi_dd;

View File

@@ -36,6 +36,8 @@
#define ROULEUR_HPHL_CROSS_CONN_THRESHOLD 350
#define ROULEUR_HPHR_CROSS_CONN_THRESHOLD 350
#define IMPED_NUM_RETRY 5
static struct wcd_mbhc_register
wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = {
WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN",
@@ -515,6 +517,35 @@ z_right:
*zr = zdet;
}
static void rouleur_mbhc_impedance_fn(struct snd_soc_component *component,
int32_t *z1L, int32_t *z1R,
int32_t *zl, int32_t *zr)
{
int i;
for (i = 0; i < IMPED_NUM_RETRY; i++) {
/* Start of left ch impedance calculation */
rouleur_mbhc_zdet_start(component, z1L, NULL);
if ((*z1L == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
(*z1L > ROULEUR_ZDET_VAL_100K))
*zl = ROULEUR_ZDET_FLOATING_IMPEDANCE;
else
*zl = *z1L/1000;
/* Start of right ch impedance calculation */
rouleur_mbhc_zdet_start(component, NULL, z1R);
if ((*z1R == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
(*z1R > ROULEUR_ZDET_VAL_100K))
*zr = ROULEUR_ZDET_FLOATING_IMPEDANCE;
else
*zr = *z1R/1000;
}
dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
__func__, *zl);
dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
__func__, *zr);
}
static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
uint32_t *zr)
{
@@ -564,27 +595,11 @@ static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
/* 1ms delay needed after disable surge protection */
usleep_range(1000, 1010);
/* Start of left ch impedance calculation */
rouleur_mbhc_zdet_start(component, &z1L, NULL);
if ((z1L == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
(z1L > ROULEUR_ZDET_VAL_100K))
*zl = ROULEUR_ZDET_FLOATING_IMPEDANCE;
else
*zl = z1L/1000;
dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
__func__, *zl);
/* Start of right ch impedance calculation */
rouleur_mbhc_zdet_start(component, NULL, &z1R);
if ((z1R == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
(z1R > ROULEUR_ZDET_VAL_100K))
*zr = ROULEUR_ZDET_FLOATING_IMPEDANCE;
else
*zr = z1R/1000;
dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
__func__, *zr);
/*
* Call impedance detection routine multiple times
* in order to avoid wrong impedance values.
*/
rouleur_mbhc_impedance_fn(component, &z1L, &z1R, zl, zr);
/* Mono/stereo detection */
if ((*zl == ROULEUR_ZDET_FLOATING_IMPEDANCE) &&

View File

@@ -48,6 +48,7 @@ enum {
#define ROULEUR_ANA_MBHC_CTL_CLK (ROULEUR_ANA_BASE_ADDR+0x06D)
#define ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT (ROULEUR_ANA_BASE_ADDR+0x072)
#define ROULEUR_ANA_NCP_EN (ROULEUR_ANA_BASE_ADDR+0x077)
#define ROULEUR_ANA_NCP_VCTRL (ROULEUR_ANA_BASE_ADDR+0x07C)
#define ROULEUR_ANA_HPHPA_CNP_CTL_1 (ROULEUR_ANA_BASE_ADDR+0x083)
#define ROULEUR_ANA_HPHPA_CNP_CTL_2 (ROULEUR_ANA_BASE_ADDR+0x084)
#define ROULEUR_ANA_HPHPA_PA_STATUS (ROULEUR_ANA_BASE_ADDR+0x087)
@@ -58,6 +59,8 @@ enum {
#define ROULEUR_SWR_HPHPA_HD2 (ROULEUR_ANA_BASE_ADDR+0x090)
#define ROULEUR_ANA_SURGE_EN (ROULEUR_ANA_BASE_ADDR+0x097)
#define ROULEUR_ANA_COMBOPA_CTL (ROULEUR_ANA_BASE_ADDR+0x09B)
#define ROULEUR_ANA_COMBOPA_CTL_4 (ROULEUR_ANA_BASE_ADDR+0x09F)
#define ROULEUR_ANA_COMBOPA_CTL_5 (ROULEUR_ANA_BASE_ADDR+0x0A0)
#define ROULEUR_ANA_RXLDO_CTL (ROULEUR_ANA_BASE_ADDR+0x0B2)
#define ROULEUR_ANA_MBIAS_EN (ROULEUR_ANA_BASE_ADDR+0x0B4)

View File

@@ -41,6 +41,7 @@ static const struct reg_default rouleur_defaults[] = {
{ ROULEUR_ANA_MBHC_CTL_CLK, 0x30 },
{ ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT, 0x00 },
{ ROULEUR_ANA_NCP_EN, 0x00 },
{ ROULEUR_ANA_NCP_VCTRL, 0xA7 },
{ ROULEUR_ANA_HPHPA_CNP_CTL_1, 0x54 },
{ ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x2B },
{ ROULEUR_ANA_HPHPA_PA_STATUS, 0x00 },
@@ -51,6 +52,8 @@ static const struct reg_default rouleur_defaults[] = {
{ ROULEUR_ANA_HPHPA_SPARE_CTL, 0x02 },
{ ROULEUR_ANA_SURGE_EN, 0x38 },
{ ROULEUR_ANA_COMBOPA_CTL, 0x35 },
{ ROULEUR_ANA_COMBOPA_CTL_4, 0x84 },
{ ROULEUR_ANA_COMBOPA_CTL_5, 0x05 },
{ ROULEUR_ANA_RXLDO_CTL, 0x86 },
{ ROULEUR_ANA_MBIAS_EN, 0x00 },
{ ROULEUR_DIG_SWR_CHIP_ID0, 0x00 },

View File

@@ -36,6 +36,7 @@ const u8 rouleur_reg_access_analog[ROULEUR_REG(
[ROULEUR_REG(ROULEUR_ANA_MBHC_CTL_CLK)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)] = RD_REG,
[ROULEUR_REG(ROULEUR_ANA_NCP_EN)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_NCP_VCTRL)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_1)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_2)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_HPHPA_PA_STATUS)] = RD_REG,
@@ -46,6 +47,8 @@ const u8 rouleur_reg_access_analog[ROULEUR_REG(
[ROULEUR_REG(ROULEUR_SWR_HPHPA_HD2)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_SURGE_EN)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_COMBOPA_CTL)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_COMBOPA_CTL_4)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_COMBOPA_CTL_5)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_RXLDO_CTL)] = RD_WR_REG,
[ROULEUR_REG(ROULEUR_ANA_MBIAS_EN)] = RD_WR_REG,
};

View File

@@ -26,6 +26,7 @@
#include <asoc/msm-cdc-pinctrl.h>
#include <dt-bindings/sound/audio-codec-port-types.h>
#include <asoc/msm-cdc-supply.h>
#include <linux/power_supply.h>
#define DRV_NAME "rouleur_codec"
@@ -35,6 +36,10 @@
#define ROULEUR_VERSION_ENTRY_SIZE 32
#define NUM_ATTEMPTS 5
#define SOC_THRESHOLD_LEVEL 25
#define LOW_SOC_MBIAS_REG_MIN_VOLTAGE 2850000
#define FOUNDRY_ID_SEC 0x5
enum {
CODEC_TX = 0,
@@ -361,6 +366,8 @@ static int rouleur_rx_clk_enable(struct snd_soc_component *component)
ROULEUR_ANA_HPHPA_FSM_CLK, 0x7F, 0x11);
snd_soc_component_update_bits(component,
ROULEUR_ANA_HPHPA_FSM_CLK, 0x80, 0x80);
snd_soc_component_update_bits(component,
ROULEUR_ANA_NCP_VCTRL, 0x07, 0x06);
snd_soc_component_update_bits(component,
ROULEUR_ANA_NCP_EN, 0x01, 0x01);
usleep_range(500, 510);
@@ -591,12 +598,12 @@ static int rouleur_codec_ear_lo_dac_event(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX0_CTL,
0x80, 0x00);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
0x04, 0x04);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX_CLK_CTL,
0x01, 0x01);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
0x04, 0x04);
break;
case SND_SOC_DAPM_POST_PMD:
@@ -635,7 +642,12 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
true);
set_bit(HPH_PA_DELAY, &rouleur->status_mask);
usleep_range(5000, 5100);
usleep_range(200, 210);
/* Enable HD2 Config for HPHR if foundry id is SEC */
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHR_HD2_ENABLE,
0x04);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_PDM_WD_CTL1,
0x03, 0x03);
@@ -671,9 +683,8 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
break;
case SND_SOC_DAPM_POST_PMD:
/*
* 7ms sleep is required after PA is disabled as per
* HW requirement. If compander is disabled, then
* 20ms delay is required.
* 5ms sleep is required after PA is disabled as per
* HW requirement.
*/
if (test_bit(HPH_PA_DELAY, &rouleur->status_mask)) {
@@ -681,6 +692,10 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
clear_bit(HPH_PA_DELAY, &rouleur->status_mask);
}
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHR_HD2_ENABLE,
0x00);
blocking_notifier_call_chain(&rouleur->mbhc->notifier,
WCD_EVENT_POST_HPHR_PA_OFF,
&rouleur->mbhc->wcd_mbhc);
@@ -710,7 +725,11 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
rouleur->rx_swr_dev->dev_num,
true);
set_bit(HPH_PA_DELAY, &rouleur->status_mask);
usleep_range(5000, 5100);
usleep_range(200, 210);
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHL_HD2_ENABLE,
0x04);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_PDM_WD_CTL0,
0x03, 0x03);
@@ -754,6 +773,10 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
clear_bit(HPH_PA_DELAY, &rouleur->status_mask);
}
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHL_HD2_ENABLE,
0x00);
blocking_notifier_call_chain(&rouleur->mbhc->notifier,
WCD_EVENT_POST_HPHL_PA_OFF,
&rouleur->mbhc->wcd_mbhc);
@@ -783,18 +806,36 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev,
rouleur->rx_swr_dev->dev_num,
true);
usleep_range(5000, 5100);
snd_soc_component_update_bits(component,
ROULEUR_ANA_COMBOPA_CTL_5,
0x04, 0x00);
usleep_range(1000, 1010);
snd_soc_component_update_bits(component,
ROULEUR_ANA_COMBOPA_CTL_4,
0x0F, 0x0F);
usleep_range(1000, 1010);
snd_soc_component_update_bits(component,
ROULEUR_ANA_COMBOPA_CTL,
0x40, 0x00);
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHL_HD2_ENABLE,
0x04);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_PDM_WD_CTL0,
0x03, 0x03);
break;
case SND_SOC_DAPM_POST_PMU:
usleep_range(5000, 5100);
snd_soc_component_update_bits(component,
ROULEUR_ANA_COMBOPA_CTL_4,
0x0F, 0x04);
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10));
wcd_enable_irq(&rouleur->irq_info,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
wcd_enable_irq(&rouleur->irq_info,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
break;
case SND_SOC_DAPM_PRE_PMD:
wcd_disable_irq(&rouleur->irq_info,
@@ -806,6 +847,10 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
break;
case SND_SOC_DAPM_POST_PMD:
usleep_range(5000, 5100);
if (rouleur->foundry_id == FOUNDRY_ID_SEC)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_HPHL_HD2_ENABLE,
0x00);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_PDM_WD_CTL0,
0x03, 0x00);
@@ -830,24 +875,35 @@ static int rouleur_codec_enable_lo_pa(struct snd_soc_dapm_widget *w,
ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev,
rouleur->rx_swr_dev->dev_num,
true);
snd_soc_component_update_bits(component,
ROULEUR_ANA_COMBOPA_CTL_5,
0x04, 0x00);
usleep_range(1000, 1010);
snd_soc_component_update_bits(component,
ROULEUR_ANA_COMBOPA_CTL_4,
0x0F, 0x0F);
usleep_range(1000, 1010);
snd_soc_component_update_bits(component,
ROULEUR_ANA_COMBOPA_CTL,
0x40, 0x40);
usleep_range(5000, 5100);
snd_soc_component_update_bits(component,
ROULEUR_DIG_SWR_PDM_WD_CTL0,
0x03, 0x03);
break;
case SND_SOC_DAPM_POST_PMU:
usleep_range(5000, 5100);
snd_soc_component_update_bits(component,
ROULEUR_ANA_COMBOPA_CTL_4,
0x0F, 0x04);
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_MUTE,
(WCD_RX1 << 0x10));
wcd_enable_irq(&rouleur->irq_info,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
wcd_enable_irq(&rouleur->irq_info,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
break;
case SND_SOC_DAPM_PRE_PMD:
wcd_disable_irq(&rouleur->irq_info,
wcd_disable_irq(&rouleur->irq_info,
ROULEUR_IRQ_HPHL_PDM_WD_INT);
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
@@ -1400,6 +1456,7 @@ static int rouleur_event_notify(struct notifier_block *block,
rouleur_init_reg(component);
regcache_mark_dirty(rouleur->regmap);
regcache_sync(rouleur->regmap);
rouleur->dev_up = true;
/* Initialize MBHC module */
mbhc = &rouleur->mbhc->wcd_mbhc;
ret = rouleur_mbhc_post_ssr_init(rouleur->mbhc, component);
@@ -1412,7 +1469,6 @@ static int rouleur_event_notify(struct notifier_block *block,
mdelay(500);
}
rouleur->mbhc->wcd_mbhc.deinit_in_progress = false;
rouleur->dev_up = true;
break;
default:
dev_err(component->dev, "%s: invalid event %d\n", __func__,
@@ -1974,6 +2030,126 @@ done:
return rc;
}
static int rouleur_battery_supply_cb(struct notifier_block *nb,
unsigned long event, void *data)
{
struct power_supply *psy = data;
struct rouleur_priv *rouleur =
container_of(nb, struct rouleur_priv, psy_nb);
if (strcmp(psy->desc->name, "battery"))
return NOTIFY_OK;
queue_work(system_freezable_wq, &rouleur->soc_eval_work);
return NOTIFY_OK;
}
static int rouleur_read_battery_soc(struct rouleur_priv *rouleur, int *soc_val)
{
static struct power_supply *batt_psy;
union power_supply_propval ret = {0,};
int err = 0;
*soc_val = 100;
if (!batt_psy)
batt_psy = power_supply_get_by_name("battery");
if (batt_psy) {
err = power_supply_get_property(batt_psy,
POWER_SUPPLY_PROP_CAPACITY, &ret);
if (err) {
pr_err("%s: battery SoC read error:%d\n",
__func__, err);
return err;
}
*soc_val = ret.intval;
}
pr_debug("%s: soc:%d\n", __func__, *soc_val);
return err;
}
static void rouleur_evaluate_soc(struct work_struct *work)
{
struct rouleur_priv *rouleur =
container_of(work, struct rouleur_priv, soc_eval_work);
int soc_val = 0, ret = 0;
struct rouleur_pdata *pdata = NULL;
pdata = dev_get_platdata(rouleur->dev);
if (!pdata) {
dev_err(rouleur->dev, "%s: pdata is NULL\n", __func__);
return;
}
if (rouleur_read_battery_soc(rouleur, &soc_val) < 0) {
dev_err(rouleur->dev, "%s unable to read battery SoC\n",
__func__);
return;
}
if (soc_val < SOC_THRESHOLD_LEVEL) {
dev_dbg(rouleur->dev,
"%s battery SoC less than threshold soc_val = %d\n",
__func__, soc_val);
/* Reduce PA Gain by 6DB for low SoC */
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE,
true);
rouleur->low_soc = true;
ret = msm_cdc_set_supply_min_voltage(rouleur->dev,
rouleur->supplies,
pdata->regulator,
pdata->num_supplies,
"cdc-vdd-mic-bias",
LOW_SOC_MBIAS_REG_MIN_VOLTAGE,
true);
if (ret < 0)
dev_err(rouleur->dev,
"%s unable to set mbias min voltage\n",
__func__);
} else {
if (rouleur->low_soc == true) {
/* Reset PA Gain to default for normal SoC */
if (rouleur->update_wcd_event)
rouleur->update_wcd_event(rouleur->handle,
WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE,
false);
ret = msm_cdc_set_supply_min_voltage(rouleur->dev,
rouleur->supplies,
pdata->regulator,
pdata->num_supplies,
"cdc-vdd-mic-bias",
LOW_SOC_MBIAS_REG_MIN_VOLTAGE,
false);
if (ret < 0)
dev_err(rouleur->dev,
"%s unable to set mbias min voltage\n",
__func__);
rouleur->low_soc = false;
}
}
}
static void rouleur_get_foundry_id(struct rouleur_priv *rouleur)
{
int ret;
if (rouleur->foundry_id_reg == 0) {
pr_debug("%s: foundry id not defined\n", __func__);
return;
}
ret = pm2250_spmi_read(rouleur->spmi_dev,
rouleur->foundry_id_reg, &rouleur->foundry_id);
if (ret == 0)
pr_debug("%s: rouleur foundry id = %x\n", rouleur->foundry_id,
__func__);
else
pr_debug("%s: rouleur error in spmi read ret = %d\n",
__func__, ret);
}
static int rouleur_soc_codec_probe(struct snd_soc_component *component)
{
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
@@ -2029,6 +2205,8 @@ static int rouleur_soc_codec_probe(struct snd_soc_component *component)
snd_soc_dapm_sync(dapm);
rouleur_init_reg(component);
/* Get rouleur foundry id */
rouleur_get_foundry_id(rouleur);
rouleur->version = ROULEUR_VERSION_1_0;
/* Register event notifier */
@@ -2044,7 +2222,16 @@ static int rouleur_soc_codec_probe(struct snd_soc_component *component)
return ret;
}
}
rouleur->low_soc = false;
rouleur->dev_up = true;
/* Register notifier to change gain based on state of charge */
INIT_WORK(&rouleur->soc_eval_work, rouleur_evaluate_soc);
rouleur->psy_nb.notifier_call = rouleur_battery_supply_cb;
if (power_supply_reg_notifier(&rouleur->psy_nb) < 0)
dev_dbg(rouleur->dev,
"%s: could not register pwr supply notifier\n",
__func__);
queue_work(system_freezable_wq, &rouleur->soc_eval_work);
done:
return ret;
}
@@ -2278,6 +2465,12 @@ struct rouleur_pdata *rouleur_populate_dt_data(struct device *dev)
}
pdata->reset_reg = reg;
if (of_property_read_u32(dev->of_node, "qcom,foundry-id-reg", &reg))
dev_dbg(dev, "%s: Failed to obtain foundry id\n",
__func__);
else
pdata->foundry_id_reg = reg;
/* Parse power supplies */
msm_cdc_get_power_supplies(dev, &pdata->regulator,
&pdata->num_supplies);
@@ -2353,6 +2546,7 @@ static int rouleur_bind(struct device *dev)
rouleur->spmi_dev = &pdev->dev;
rouleur->reset_reg = pdata->reset_reg;
rouleur->foundry_id_reg = pdata->foundry_id_reg;
ret = msm_cdc_init_supplies(dev, &rouleur->supplies,
pdata->regulator, pdata->num_supplies);
if (!rouleur->supplies) {

View File

@@ -33,6 +33,8 @@
#define NUM_ATTEMPTS 5
#define SWRS_SCP_CONTROL 0x44
#define MAX_NAME_LEN 40
static int swr_master_channel_map[] = {
ZERO,
SWRM_TX1_CH1,
@@ -94,6 +96,9 @@ const char *aif_name_list[] = {
static int swr_dmic_reset(struct swr_device *pdev);
static int swr_dmic_up(struct swr_device *pdev);
static int swr_dmic_down(struct swr_device *pdev);
static int swr_dmic_event_notify(struct notifier_block *block,
unsigned long val,
void *data);
static inline int swr_dmic_tx_get_slave_port_type_idx(const char *wname,
unsigned int *port_idx)
@@ -269,23 +274,41 @@ static const struct snd_kcontrol_new dmic_switch[] = {
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
};
static const struct snd_kcontrol_new va_dmic_switch[] = {
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
};
static const struct snd_soc_dapm_widget swr_dmic_dapm_widgets[] = {
SND_SOC_DAPM_MIXER_E("SWR_DMIC_MIXER", SND_SOC_NOPM, 0, 0,
dmic_switch, ARRAY_SIZE(dmic_switch), dmic_swr_ctrl,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER_E("SWR_DMIC_VA_MIXER", SND_SOC_NOPM, 0, 0,
va_dmic_switch, ARRAY_SIZE(va_dmic_switch), dmic_swr_ctrl,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_INPUT("SWR_DMIC"),
SND_SOC_DAPM_INPUT("VA_SWR_DMIC"),
SND_SOC_DAPM_OUT_DRV_E("SMIC_PORT_EN", SND_SOC_NOPM, 0, 0, NULL, 0,
swr_dmic_port_enable,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_OUT_DRV_E("SMIC_VA_PORT_EN", SND_SOC_NOPM, 0, 0, NULL, 0,
swr_dmic_port_enable,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_OUTPUT("SWR_DMIC_OUTPUT"),
SND_SOC_DAPM_OUTPUT("SWR_DMIC_VA_OUTPUT"),
};
static const struct snd_soc_dapm_route swr_dmic_audio_map[] = {
{"SWR_DMIC_MIXER", "Switch", "SWR_DMIC"},
{"SMIC_PORT_EN", NULL, "SWR_DMIC_MIXER"},
{"SWR_DMIC_OUTPUT", NULL, "SMIC_PORT_EN"},
{"SWR_DMIC_VA_MIXER", "Switch", "VA_SWR_DMIC"},
{"SMIC_VA_PORT_EN", NULL, "SWR_DMIC_VA_MIXER"},
{"SWR_DMIC_VA_OUTPUT", NULL, "SMIC_VA_PORT_EN"},
};
static int swr_dmic_codec_probe(struct snd_soc_component *component)
@@ -294,36 +317,45 @@ static int swr_dmic_codec_probe(struct snd_soc_component *component)
snd_soc_component_get_drvdata(component);
struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(component);
char w_name[100];
char w_name[MAX_NAME_LEN];
if (!swr_dmic)
return -EINVAL;
swr_dmic->component = component;
snd_soc_dapm_ignore_suspend(dapm,
swr_dmic->dai_driver->capture.stream_name);
memset(w_name, 0, 100);
strlcpy(w_name, component->name_prefix, 100);
strlcat(w_name, " SWR_DMIC", 100);
if (!component->name_prefix) {
dev_err(component->dev, "%s: component prefix is NULL\n", __func__);
return -EPROBE_DEFER;
}
memset(w_name, 0, sizeof(w_name));
strlcpy(w_name, component->name_prefix, sizeof(w_name));
strlcat(w_name, " ", sizeof(w_name));
strlcat(w_name, swr_dmic->dai_driver->capture.stream_name,
sizeof(w_name));
snd_soc_dapm_ignore_suspend(dapm, w_name);
memset(w_name, 0, 100);
strlcpy(w_name, component->name_prefix, 100);
strlcat(w_name, " SMIC_SUPPLY", 100);
memset(w_name, 0, sizeof(w_name));
strlcpy(w_name, component->name_prefix, sizeof(w_name));
strlcat(w_name, " SWR_DMIC", sizeof(w_name));
snd_soc_dapm_ignore_suspend(dapm, w_name);
memset(w_name, 0, 100);
strlcpy(w_name, component->name_prefix, 100);
strlcat(w_name, " SMIC_PORT_EN", 100);
memset(w_name, 0, sizeof(w_name));
strlcpy(w_name, component->name_prefix, sizeof(w_name));
strlcat(w_name, " SMIC_PORT_EN", sizeof(w_name));
snd_soc_dapm_ignore_suspend(dapm, w_name);
memset(w_name, 0, 100);
strlcpy(w_name, component->name_prefix, 100);
strlcat(w_name, " SWR_DMIC_OUTPUT", 100);
memset(w_name, 0, sizeof(w_name));
strlcpy(w_name, component->name_prefix, sizeof(w_name));
strlcat(w_name, " SWR_DMIC_OUTPUT", sizeof(w_name));
snd_soc_dapm_ignore_suspend(dapm, w_name);
snd_soc_dapm_sync(dapm);
swr_dmic->nblock.notifier_call = swr_dmic_event_notify;
wcd938x_swr_dmic_register_notifier(swr_dmic->supply_component,
&swr_dmic->nblock, true);
return 0;
}
@@ -472,6 +504,8 @@ static int swr_dmic_probe(struct swr_device *pdev)
ret = enable_wcd_codec_supply(swr_dmic, true);
if (ret) {
ret = -EPROBE_DEFER;
swr_dmic->is_wcd_supply = false;
swr_dmic->wcd_handle = NULL;
goto err;
}
++swr_dmic->is_en_supply;
@@ -516,11 +550,17 @@ static int swr_dmic_probe(struct swr_device *pdev)
"%s get devnum %d for dev addr %llx failed\n",
__func__, swr_devnum, pdev->addr);
ret = -EPROBE_DEFER;
goto dev_err;
if (swr_dmic->is_en_supply == 1) {
enable_wcd_codec_supply(swr_dmic, false);
--swr_dmic->is_en_supply;
}
swr_dmic->is_wcd_supply = false;
swr_dmic->wcd_handle = NULL;
goto err;
}
pdev->dev_num = swr_devnum;
swr_dmic->driver = devm_kzalloc(&pdev->dev,
sizeof(struct snd_soc_component_driver), GFP_KERNEL);
if (!swr_dmic->driver) {
@@ -586,10 +626,6 @@ static int swr_dmic_probe(struct swr_device *pdev)
strlen(swr_dmic_name_prefix_of) + 1);
component->name_prefix = prefix_name;
swr_dmic->nblock.notifier_call = swr_dmic_event_notify;
wcd938x_swr_dmic_register_notifier(swr_dmic->supply_component,
&swr_dmic->nblock, true);
return 0;
dev_err:

View File

@@ -456,48 +456,33 @@ static int swr_haptics_device_down(struct swr_device *sdev)
static int swr_haptics_suspend(struct device *dev)
{
struct swr_haptics_dev *swr_hap;
int rc;
int rc = 0;
swr_hap = swr_get_dev_data(to_swr_device(dev));
if (!swr_hap) {
dev_err(dev, "%s: no data for swr_hap\n", __func__);
return -ENODEV;
}
trace_printk("%s: suspended\n", __func__);
/* Put SWR slave into reset */
rc = regulator_disable(swr_hap->vdd);
if (rc < 0) {
dev_err(swr_hap->dev, "%s: disable swr-slave failed, rc=%d\n",
__func__, rc);
return rc;
}
return 0;
return rc;
}
static int swr_haptics_resume(struct device *dev)
{
struct swr_haptics_dev *swr_hap;
int rc;
int rc = 0;
swr_hap = swr_get_dev_data(to_swr_device(dev));
if (!swr_hap) {
dev_err(dev, "%s: no data for swr_hap\n", __func__);
return -ENODEV;
}
trace_printk("%s: resumed\n", __func__);
/* Take SWR slave out of reset */
rc = regulator_enable(swr_hap->vdd);
if (rc < 0) {
dev_err(swr_hap->dev, "%s: enable swr-slave failed, rc=%d\n",
__func__, rc);
return rc;
}
return 0;
return rc;
}
static const struct of_device_id swr_haptics_match_table[] = {
{ .compatible = "qcom,swr-haptics", },
{ .compatible = "qcom,pm8350b-swr-haptics", },

View File

@@ -26,8 +26,6 @@
#include "wcd937x.h"
#include "internal.h"
#define DRV_NAME "wcd937x_codec"
#define WCD9370_VARIANT 0
#define WCD9375_VARIANT 5
#define WCD937X_VARIANT_ENTRY_SIZE 32
@@ -40,6 +38,18 @@
#define NUM_ATTEMPTS 5
#define WCD937X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
SNDRV_PCM_RATE_384000)
/* Fractional Rates */
#define WCD937X_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
#define WCD937X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S24_LE |\
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
enum {
CODEC_TX = 0,
CODEC_RX,
@@ -91,12 +101,39 @@ static struct regmap_irq_chip wcd937x_regmap_irq_chip = {
.mask_base = WCD937X_DIGITAL_INTR_MASK_0,
.ack_base = WCD937X_DIGITAL_INTR_CLEAR_0,
.use_ack = 1,
#if IS_ENABLED(CONFIG_AUDIO_QGKI)
.clear_ack = 1,
#endif
.type_base = WCD937X_DIGITAL_INTR_LEVEL_0,
.runtime_pm = false,
.handle_post_irq = wcd937x_handle_post_irq,
.irq_drv_data = NULL,
};
static struct snd_soc_dai_driver wcd937x_dai[] = {
{
.name = "wcd937x_cdc",
.playback = {
.stream_name = "WCD937X_AIF Playback",
.rates = WCD937X_RATES | WCD937X_FRAC_RATES,
.formats = WCD937X_FORMATS,
.rate_max = 384000,
.rate_min = 8000,
.channels_min = 1,
.channels_max = 4,
},
.capture = {
.stream_name = "WCD937X_AIF Capture",
.rates = WCD937X_RATES,
.formats = WCD937X_FORMATS,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
.channels_max = 4,
},
},
};
static int wcd937x_handle_post_irq(void *data)
{
struct wcd937x_priv *wcd937x = data;
@@ -278,7 +315,7 @@ static int wcd937x_tx_connect_port(struct snd_soc_component *component,
u8 ch_mask;
u32 ch_rate;
u8 ch_type = 0;
int slave_port_idx;
int slave_ch_idx;
u8 num_port = 1;
int ret = 0;
@@ -2195,6 +2232,14 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("IN2_HPHR"),
SND_SOC_DAPM_INPUT("IN3_AUX"),
/*
* These dummy widgets are null connected to WCD937x dapm input and
* output widgets which are not actual path endpoints. This ensures
* dapm doesnt set these dapm input and output widgets as endpoints.
*/
SND_SOC_DAPM_INPUT("WCD_TX_DUMMY"),
SND_SOC_DAPM_OUTPUT("WCD_RX_DUMMY"),
/*tx widgets*/
SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0,
wcd937x_codec_enable_adc,
@@ -2224,15 +2269,15 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = {
SND_SOC_DAPM_POST_PMD),
/* micbias widgets*/
SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, 0, 0,
wcd937x_codec_enable_micbias,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, 0, 0,
wcd937x_codec_enable_micbias,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, 0, 0,
wcd937x_codec_enable_micbias,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD),
@@ -2316,15 +2361,15 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("HPHR"),
/* micbias pull up widgets*/
SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS1", SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY("VA MIC BIAS1", SND_SOC_NOPM, 0, 0,
wcd937x_codec_enable_micbias_pullup,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS2", SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY("VA MIC BIAS2", SND_SOC_NOPM, 0, 0,
wcd937x_codec_enable_micbias_pullup,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS3", SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_SUPPLY("VA MIC BIAS3", SND_SOC_NOPM, 0, 0,
wcd937x_codec_enable_micbias_pullup,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD),
@@ -2405,6 +2450,7 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = {
};
static const struct snd_soc_dapm_route wcd937x_audio_map[] = {
{"WCD_TX_DUMMY", NULL, "WCD_TX_OUTPUT"},
{"WCD_TX_OUTPUT", NULL, "ADC1_MIXER"},
{"ADC1_MIXER", "Switch", "ADC1 REQ"},
{"ADC1 REQ", NULL, "ADC1"},
@@ -2417,6 +2463,7 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = {
{"ADC2 MUX", "INP3", "AMIC3"},
{"ADC2 MUX", "INP2", "AMIC2"},
{"IN1_HPHL", NULL, "WCD_RX_DUMMY"},
{"IN1_HPHL", NULL, "VDD_BUCK"},
{"IN1_HPHL", NULL, "CLS_H_PORT"},
{"RX1", NULL, "IN1_HPHL"},
@@ -2425,6 +2472,7 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = {
{"HPHL PGA", NULL, "HPHL_RDAC"},
{"HPHL", NULL, "HPHL PGA"},
{"IN2_HPHR", NULL, "WCD_RX_DUMMY"},
{"IN2_HPHR", NULL, "VDD_BUCK"},
{"IN2_HPHR", NULL, "CLS_H_PORT"},
{"RX2", NULL, "IN2_HPHR"},
@@ -2433,6 +2481,7 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = {
{"HPHR PGA", NULL, "HPHR_RDAC"},
{"HPHR", NULL, "HPHR PGA"},
{"IN3_AUX", NULL, "WCD_RX_DUMMY"},
{"IN3_AUX", NULL, "VDD_BUCK"},
{"IN3_AUX", NULL, "CLS_H_PORT"},
{"RX3", NULL, "IN3_AUX"},
@@ -2451,6 +2500,7 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = {
static const struct snd_soc_dapm_route wcd9375_audio_map[] = {
{"WCD_TX_DUMMY", NULL, "WCD_TX_OUTPUT"},
{"WCD_TX_OUTPUT", NULL, "ADC3_MIXER"},
{"ADC3_OUTPUT", NULL, "ADC3_MIXER"},
{"ADC3_MIXER", "Switch", "ADC3 REQ"},
@@ -2576,19 +2626,25 @@ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root,
return 0;
}
card = component->card;
priv->entry = snd_info_create_subdir(codec_root->module,
priv->entry = snd_info_create_module_entry(codec_root->module,
"wcd937x", codec_root);
if (!priv->entry) {
dev_dbg(component->dev, "%s: failed to create wcd937x entry\n",
__func__);
return -ENOMEM;
}
priv->entry->mode = S_IFDIR | 0555;
if (snd_info_register(priv->entry) < 0) {
snd_info_free_entry(priv->entry);
return -ENOMEM;
}
version_entry = snd_info_create_card_entry(card->snd_card,
"version",
priv->entry);
if (!version_entry) {
dev_dbg(component->dev, "%s: failed to create wcd937x version entry\n",
__func__);
snd_info_free_entry(priv->entry);
return -ENOMEM;
}
@@ -2599,6 +2655,7 @@ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root,
if (snd_info_register(version_entry) < 0) {
snd_info_free_entry(version_entry);
snd_info_free_entry(priv->entry);
return -ENOMEM;
}
priv->version_entry = version_entry;
@@ -2610,6 +2667,8 @@ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root,
dev_dbg(component->dev,
"%s: failed to create wcd937x variant entry\n",
__func__);
snd_info_free_entry(version_entry);
snd_info_free_entry(priv->entry);
return -ENOMEM;
}
@@ -2620,6 +2679,8 @@ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root,
if (snd_info_register(variant_entry) < 0) {
snd_info_free_entry(variant_entry);
snd_info_free_entry(version_entry);
snd_info_free_entry(priv->entry);
return -ENOMEM;
}
priv->variant_entry = variant_entry;
@@ -2713,6 +2774,8 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component)
snd_soc_dapm_ignore_suspend(dapm, "AUX");
snd_soc_dapm_ignore_suspend(dapm, "HPHL");
snd_soc_dapm_ignore_suspend(dapm, "HPHR");
snd_soc_dapm_ignore_suspend(dapm, "WCD_TX_DUMMY");
snd_soc_dapm_ignore_suspend(dapm, "WCD_RX_DUMMY");
snd_soc_dapm_sync(dapm);
wcd_cls_h_init(&wcd937x->clsh_info);
@@ -2781,7 +2844,7 @@ static void wcd937x_soc_codec_remove(struct snd_soc_component *component)
}
static const struct snd_soc_component_driver soc_codec_dev_wcd937x = {
.name = DRV_NAME,
.name = WCD937X_DRV_NAME,
.probe = wcd937x_soc_codec_probe,
.remove = wcd937x_soc_codec_remove,
.controls = wcd937x_snd_controls,
@@ -3185,7 +3248,7 @@ static int wcd937x_bind(struct device *dev)
wcd_disable_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT);
ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x,
NULL, 0);
wcd937x_dai, ARRAY_SIZE(wcd937x_dai));
if (ret) {
dev_err(dev, "%s: Codec registration failed\n",
__func__);

View File

@@ -10,12 +10,14 @@
#define WCD937X_MAX_SLAVE_CH_TYPES 10
#define ZERO 0
struct swr_slave_ch_map {
#define WCD937X_DRV_NAME "wcd937x_codec"
struct wcd937x_swr_slave_ch_map {
u8 ch_type;
u8 index;
};
static const struct swr_slave_ch_map swr_slv_tx_ch_idx[] = {
static const struct wcd937x_swr_slave_ch_map wcd937x_swr_slv_tx_ch_idx[] = {
{ADC1, 0},
{ADC2, 1},
{ADC3, 2},
@@ -28,7 +30,7 @@ static const struct swr_slave_ch_map swr_slv_tx_ch_idx[] = {
{DMIC5, 9},
};
static int swr_master_ch_map[] = {
static int wcd937x_swr_master_ch_map[] = {
ZERO,
SWRM_TX1_CH1,
SWRM_TX1_CH2,
@@ -54,14 +56,14 @@ static inline int wcd937x_slave_get_master_ch_val(int ch)
int i;
for (i = 0; i < WCD937X_MAX_SLAVE_CH_TYPES; i++)
if (ch == swr_master_ch_map[i])
if (ch == wcd937x_swr_master_ch_map[i])
return i;
return 0;
}
static inline int wcd937x_slave_get_master_ch(int idx)
{
return swr_master_ch_map[idx];
return wcd937x_swr_master_ch_map[idx];
}
static inline int wcd937x_slave_get_slave_ch_val(int ch)
@@ -69,8 +71,8 @@ static inline int wcd937x_slave_get_slave_ch_val(int ch)
int i;
for (i = 0; i < WCD937X_MAX_SLAVE_CH_TYPES; i++)
if (ch == swr_slv_tx_ch_idx[i].ch_type)
return swr_slv_tx_ch_idx[i].index;
if (ch == wcd937x_swr_slv_tx_ch_idx[i].ch_type)
return wcd937x_swr_slv_tx_ch_idx[i].index;
return -EINVAL;
}

View File

@@ -69,6 +69,7 @@ struct wcd938x_priv {
u32 hph_mode;
u32 tx_mode[TX_ADC_MAX];
s32 adc_count;
bool comp1_enable;
bool comp2_enable;
bool ldoh;

View File

@@ -105,6 +105,7 @@ static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
static int wcd938x_handle_post_irq(void *data);
static int wcd938x_reset(struct device *dev);
static int wcd938x_reset_low(struct device *dev);
static int wcd938x_get_adc_mode(int val);
static const struct regmap_irq wcd938x_irqs[WCD938X_NUM_IRQS] = {
REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01),
@@ -1412,8 +1413,7 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w,
true);
break;
case SND_SOC_DAPM_POST_PMD:
ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
wcd938x->tx_swr_dev->dev_num,
wcd938x_tx_connect_port(component, DMIC0 + (w->shift), 0,
false);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_AMIC_CTL,
@@ -1542,8 +1542,47 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
bank = (wcd938x_swr_slv_get_current_bank(wcd938x->tx_swr_dev,
wcd938x->tx_swr_dev->dev_num) ? 0 : 1);
/* power mode is applicable only to analog mics */
if (strnstr(w->name, "ADC", sizeof("ADC"))) {
/* Get channel rate */
rate = wcd938x_get_clk_rate(wcd938x->tx_mode[w->shift - ADC1]);
}
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
/* Check AMIC2 is connected to ADC2 to take an action on BCS */
if (w->shift == ADC2 && !(snd_soc_component_read32(component,
WCD938X_TX_NEW_AMIC_MUX_CFG) & 0x80)) {
if (!wcd938x->bcs_dis)
wcd938x_tx_connect_port(component, MBHC,
SWR_CLK_RATE_4P8MHZ, true);
set_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask);
}
if (strnstr(w->name, "ADC", sizeof("ADC"))) {
set_bit(w->shift - ADC1, &wcd938x->status_mask);
wcd938x_tx_connect_port(component, w->shift, rate,
true);
} else {
wcd938x_tx_connect_port(component, w->shift,
SWR_CLK_RATE_2P4MHZ, true);
}
break;
case SND_SOC_DAPM_POST_PMD:
if (strnstr(w->name, "ADC", sizeof("ADC"))) {
if (strnstr(w->name, "ADC1", sizeof("ADC1"))) {
clear_bit(WCD_ADC1, &wcd938x->status_mask);
clear_bit(WCD_ADC1_MODE, &wcd938x->status_mask);
} else if (strnstr(w->name, "ADC2", sizeof("ADC2"))) {
clear_bit(WCD_ADC2, &wcd938x->status_mask);
clear_bit(WCD_ADC2_MODE, &wcd938x->status_mask);
} else if (strnstr(w->name, "ADC3", sizeof("ADC3"))) {
clear_bit(WCD_ADC3, &wcd938x->status_mask);
clear_bit(WCD_ADC3_MODE, &wcd938x->status_mask);
} else if (strnstr(w->name, "ADC4", sizeof("ADC4"))) {
clear_bit(WCD_ADC4, &wcd938x->status_mask);
clear_bit(WCD_ADC4_MODE, &wcd938x->status_mask);
}
}
if (strnstr(w->name, "ADC", sizeof("ADC"))) {
if (test_bit(WCD_ADC1, &wcd938x->status_mask) ||
test_bit(WCD_ADC1_MODE, &wcd938x->status_mask))
@@ -1567,49 +1606,19 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
}
}
rate = wcd938x_get_clk_rate(i);
if (wcd938x->adc_count) {
rate = (wcd938x->adc_count * rate);
if (rate > SWR_CLK_RATE_9P6MHZ)
rate = SWR_CLK_RATE_9P6MHZ;
}
wcd938x_set_swr_clk_rate(component, rate, bank);
}
if (w->shift == ADC2 && !(snd_soc_component_read32(component,
WCD938X_TX_NEW_AMIC_MUX_CFG) & 0x80)) {
if (!wcd938x->bcs_dis)
wcd938x_tx_connect_port(component, MBHC,
SWR_CLK_RATE_4P8MHZ, true);
set_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask);
}
if (strnstr(w->name, "ADC", sizeof("ADC"))) {
wcd938x_tx_connect_port(component, w->shift, rate,
true);
/* Copy clk settings to active bank */
wcd938x_set_swr_clk_rate(component, rate, !bank);
} else {
wcd938x_tx_connect_port(component, w->shift,
SWR_CLK_RATE_2P4MHZ, true);
}
break;
case SND_SOC_DAPM_POST_PMD:
if (strnstr(w->name, "ADC", sizeof("ADC"))) {
rate = wcd938x_get_clk_rate(ADC_MODE_INVALID);
wcd938x_set_swr_clk_rate(component, rate, !bank);
}
wcd938x_tx_connect_port(component, w->shift, 0, false);
if (w->shift == ADC2 &&
test_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask)) {
if (!wcd938x->bcs_dis)
wcd938x_tx_connect_port(component, MBHC, 0,
false);
clear_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask);
}
ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
wcd938x->tx_swr_dev->dev_num,
false);
if (strnstr(w->name, "ADC", sizeof("ADC")))
wcd938x_set_swr_clk_rate(component, rate, bank);
if (strnstr(w->name, "ADC1", sizeof("ADC1")))
clear_bit(WCD_ADC1_MODE, &wcd938x->status_mask);
else if (strnstr(w->name, "ADC2", sizeof("ADC2")))
clear_bit(WCD_ADC2_MODE, &wcd938x->status_mask);
else if (strnstr(w->name, "ADC3", sizeof("ADC3")))
clear_bit(WCD_ADC3_MODE, &wcd938x->status_mask);
else if (strnstr(w->name, "ADC4", sizeof("ADC4")))
clear_bit(WCD_ADC4_MODE, &wcd938x->status_mask);
wcd938x_set_swr_clk_rate(component, rate, !bank);
break;
};
@@ -1697,7 +1706,91 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
snd_soc_dapm_to_component(w->dapm);
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
int clk_rate = 0, ret = 0;
int mode;
int mode = 0, i = 0, bank = 0;
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
w->name, event);
bank = (wcd938x_swr_slv_get_current_bank(wcd938x->tx_swr_dev,
wcd938x->tx_swr_dev->dev_num) ? 0 : 1);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
wcd938x->adc_count++;
if (test_bit(WCD_ADC1, &wcd938x->status_mask) ||
test_bit(WCD_ADC1_MODE, &wcd938x->status_mask))
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC1]];
if (test_bit(WCD_ADC2, &wcd938x->status_mask) ||
test_bit(WCD_ADC2_MODE, &wcd938x->status_mask))
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC2]];
if (test_bit(WCD_ADC3, &wcd938x->status_mask) ||
test_bit(WCD_ADC3_MODE, &wcd938x->status_mask))
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC3]];
if (test_bit(WCD_ADC4, &wcd938x->status_mask) ||
test_bit(WCD_ADC4_MODE, &wcd938x->status_mask))
mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC4]];
if (mode != 0) {
for (i = 0; i < ADC_MODE_ULP2; i++) {
if (mode & (1 << i)) {
i++;
break;
}
}
}
clk_rate = wcd938x_get_clk_rate(i);
/* clk_rate depends on number of paths getting enabled */
clk_rate = (wcd938x->adc_count * clk_rate);
if (clk_rate > SWR_CLK_RATE_9P6MHZ)
clk_rate = SWR_CLK_RATE_9P6MHZ;
wcd938x_set_swr_clk_rate(component, clk_rate, bank);
ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
wcd938x->tx_swr_dev->dev_num,
true);
wcd938x_set_swr_clk_rate(component, clk_rate, !bank);
break;
case SND_SOC_DAPM_POST_PMD:
wcd938x->adc_count--;
if (wcd938x->adc_count < 0)
wcd938x->adc_count = 0;
wcd938x_tx_connect_port(component, ADC1 + w->shift, 0, false);
if (w->shift + ADC1 == ADC2 &&
test_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask)) {
if (!wcd938x->bcs_dis)
wcd938x_tx_connect_port(component, MBHC, 0,
false);
clear_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask);
}
break;
};
return ret;
}
void wcd938x_disable_bcs_before_slow_insert(struct snd_soc_component *component,
bool bcs_disable)
{
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
if (wcd938x->update_wcd_event) {
if (bcs_disable)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_BCS_CLK_OFF, 0);
else
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_BCS_CLK_OFF, 1);
}
}
static int wcd938x_enable_req(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
struct wcd938x_priv *wcd938x =
snd_soc_component_get_drvdata(component);
int ret = 0;
u8 mode = 0;
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
w->name, event);
@@ -1708,11 +1801,12 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10);
set_bit(w->shift, &wcd938x->status_mask);
clk_rate = wcd938x_get_clk_rate(wcd938x->tx_mode[w->shift]);
ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
wcd938x->tx_swr_dev->dev_num,
true);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_REQ_CTL, 0x02, 0x02);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00);
ret = wcd938x_tx_channel_config(component, w->shift, 1);
mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]);
if (mode < 0) {
@@ -1788,53 +1882,9 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
default:
break;
}
ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
wcd938x->tx_swr_dev->dev_num,
false);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00);
clear_bit(w->shift, &wcd938x->status_mask);
break;
};
return ret;
}
void wcd938x_disable_bcs_before_slow_insert(struct snd_soc_component *component,
bool bcs_disable)
{
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
if (wcd938x->update_wcd_event) {
if (bcs_disable)
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_BCS_CLK_OFF, 0);
else
wcd938x->update_wcd_event(wcd938x->handle,
WCD_BOLERO_EVT_BCS_CLK_OFF, 1);
}
}
static int wcd938x_enable_req(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
int ret = 0;
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
w->name, event);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_REQ_CTL, 0x02, 0x02);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00);
break;
case SND_SOC_DAPM_POST_PMD:
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00);
if (wcd938x->adc_count == 0)
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00);
break;
};
return ret;

View File

@@ -35,6 +35,19 @@
#define SPK_GAIN_12DB 4
#define WIDGET_NAME_MAX_SIZE 80
#define MAX_NAME_LEN 30
#define WSA881X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
SNDRV_PCM_RATE_384000)
/* Fractional Rates */
#define WSA881X_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
#define WSA881X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S24_LE |\
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
/*
* Private data Structure for wsa881x. All parameters related to
* WSA881X codec needs to be defined here.
@@ -66,6 +79,9 @@ struct wsa881x_pdata {
struct device_node *wsa_vi_gpio_p;
struct device_node *wsa_clk_gpio_p;
struct device_node *wsa_reset_gpio_p;
char *wsa881x_name_prefix;
struct snd_soc_dai_driver *dai_driver;
struct snd_soc_component_driver *driver;
};
enum {
@@ -1130,8 +1146,6 @@ static int wsa881x_probe(struct snd_soc_component *component)
struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(component);
char *widget_name = NULL;
struct snd_soc_card *card = component->card;
struct snd_soc_codec_conf *codec_conf = card->codec_conf;
client = dev_get_drvdata(component->dev);
ret = wsa881x_i2c_get_client_index(client, &wsa881x_index);
@@ -1155,17 +1169,17 @@ static int wsa881x_probe(struct snd_soc_component *component)
INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work,
wsa881x_ocp_ctl_work);
if (codec_conf->name_prefix) {
if (component->name_prefix) {
widget_name = kcalloc(WIDGET_NAME_MAX_SIZE, sizeof(char),
GFP_KERNEL);
if (!widget_name)
return -ENOMEM;
snprintf(widget_name, WIDGET_NAME_MAX_SIZE,
"%s WSA_SPKR", codec_conf->name_prefix);
"%s WSA_SPKR", component->name_prefix);
snd_soc_dapm_ignore_suspend(dapm, widget_name);
snprintf(widget_name, WIDGET_NAME_MAX_SIZE,
"%s WSA_IN", codec_conf->name_prefix);
"%s WSA_IN", component->name_prefix);
snd_soc_dapm_ignore_suspend(dapm, widget_name);
kfree(widget_name);
} else {
@@ -1190,7 +1204,8 @@ static void wsa881x_remove(struct snd_soc_component *component)
mutex_destroy(&wsa881x->res_lock);
}
static const struct snd_soc_component_driver soc_component_dev_wsa881x = {
static const struct snd_soc_component_driver soc_codec_dev_wsa881x = {
.name = "",
.probe = wsa881x_probe,
.remove = wsa881x_remove,
@@ -1205,6 +1220,21 @@ static const struct snd_soc_component_driver soc_component_dev_wsa881x = {
.num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map),
};
static struct snd_soc_dai_driver wsa_dai[] = {
{
.name = "",
.playback = {
.stream_name = "",
.rates = WSA881X_RATES | WSA881X_FRAC_RATES,
.formats = WSA881X_FORMATS,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
.channels_max = 2,
},
},
};
static int wsa881x_reset(struct wsa881x_pdata *pdata, bool enable)
{
int ret = 0;
@@ -1332,6 +1362,9 @@ static int wsa881x_i2c_probe(struct i2c_client *client,
int wsa881x_index = 0;
struct wsa881x_pdata *pdata = NULL;
struct clk *wsa_mclk = NULL;
char buffer[MAX_NAME_LEN];
const char *wsa881x_name_prefix_of = NULL;
struct snd_soc_component *component;
ret = wsa881x_i2c_get_client_index(client, &wsa881x_index);
if (ret != 0) {
@@ -1454,13 +1487,84 @@ static int wsa881x_i2c_probe(struct i2c_client *client,
}
wsa881x_presence_count++;
wsa881x_probing_count++;
ret = snd_soc_register_component(&client->dev,
&soc_component_dev_wsa881x,
NULL, 0);
if (ret < 0)
ret = of_property_read_string(client->dev.of_node,
"qcom,wsa-prefix", &wsa881x_name_prefix_of);
if (ret) {
dev_err(&client->dev,
"%s: Looking up %s property in node %s failed\n",
__func__, "qcom,wsa-prefix",
client->dev.of_node->full_name);
goto err1;
}
pdata->driver = devm_kzalloc(&client->dev,
sizeof(struct snd_soc_component_driver),
GFP_KERNEL);
if (!pdata->driver) {
ret = -ENOMEM;
goto err1;
}
memcpy(pdata->driver, &soc_codec_dev_wsa881x,
sizeof(struct snd_soc_component_driver));
pdata->dai_driver = devm_kzalloc(&client->dev,
sizeof(struct snd_soc_dai_driver),
GFP_KERNEL);
if (!pdata->dai_driver) {
ret = -ENOMEM;
goto err_mem;
}
memcpy(pdata->dai_driver, wsa_dai,
sizeof(struct snd_soc_dai_driver));
snprintf(buffer, sizeof(buffer), "wsa-codec%d", wsa881x_index);
pdata->driver->name = kstrndup(buffer,
strlen(buffer), GFP_KERNEL);
snprintf(buffer, sizeof(buffer), "wsa_rx%d", wsa881x_index);
pdata->dai_driver->name =
kstrndup(buffer, strlen(buffer), GFP_KERNEL);
snprintf(buffer, sizeof(buffer),
"WSA881X_AIF%d Playback", wsa881x_index);
pdata->dai_driver->playback.stream_name =
kstrndup(buffer, strlen(buffer), GFP_KERNEL);
/* Number of DAI's used is 1 */
ret = snd_soc_register_component(&client->dev,
pdata->driver, pdata->dai_driver, 1);
pdata->wsa881x_name_prefix = kstrndup(wsa881x_name_prefix_of,
strlen(wsa881x_name_prefix_of), GFP_KERNEL);
component = snd_soc_lookup_component(&client->dev, pdata->driver->name);
if (!component) {
dev_err(&client->dev, "%s: component is NULL \n", __func__);
ret = -EINVAL;
goto err_mem;
}
component->name_prefix = pdata->wsa881x_name_prefix;
pdata->status = WSA881X_STATUS_I2C;
goto err1;
}
err_mem:
kfree(pdata->wsa881x_name_prefix);
if (pdata->dai_driver) {
kfree(pdata->dai_driver->name);
kfree(pdata->dai_driver->playback.stream_name);
kfree(pdata->dai_driver);
}
if (pdata->driver) {
kfree(pdata->driver->name);
kfree(pdata->driver);
}
err1:
wsa881x_reset(pdata, false);
err:
@@ -1472,6 +1576,16 @@ static int wsa881x_i2c_remove(struct i2c_client *client)
struct wsa881x_pdata *wsa881x = client->dev.platform_data;
snd_soc_unregister_component(&client->dev);
kfree(wsa881x->wsa881x_name_prefix);
if (wsa881x->dai_driver) {
kfree(wsa881x->dai_driver->name);
kfree(wsa881x->dai_driver->playback.stream_name);
kfree(wsa881x->dai_driver);
}
if (wsa881x->driver) {
kfree(wsa881x->driver->name);
kfree(wsa881x->driver);
}
i2c_set_clientdata(client, NULL);
kfree(wsa881x);
return 0;

View File

@@ -118,6 +118,7 @@ enum {
BOLERO_WSA_EVT_SSR_DOWN,
BOLERO_WSA_EVT_SSR_UP,
BOLERO_WSA_EVT_PA_ON_POST_FSCLK,
BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB,
};
struct wsa_ctrl_platform_data {
@@ -1403,6 +1404,7 @@ static int wsa881x_event_notify(struct notifier_block *nb,
0x80, 0x00);
break;
case BOLERO_WSA_EVT_PA_ON_POST_FSCLK:
case BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB:
if ((snd_soc_component_read32(wsa881x->component,
WSA881X_SPKR_DAC_CTL) & 0x80) == 0x80)
snd_soc_component_update_bits(wsa881x->component,

View File

@@ -66,6 +66,7 @@ enum {
BOLERO_WSA_EVT_SSR_DOWN,
BOLERO_WSA_EVT_SSR_UP,
BOLERO_WSA_EVT_PA_ON_POST_FSCLK,
BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB,
};
struct wsa_ctrl_platform_data {

View File

@@ -37,7 +37,7 @@
#define TEMP_INVALID 0xFFFF
#define WSA883X_TEMP_RETRY 3
#define MAX_NAME_LEN 30
#define MAX_NAME_LEN 40
#define WSA883X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
@@ -99,7 +99,6 @@ static const struct wsa_reg_mask_val reg_init[] = {
{WSA883X_CDC_SPK_DSM_R7, 0xFF, 0x3F},
{WSA883X_DRE_CTL_0, 0xF0, 0x90},
{WSA883X_DRE_IDLE_DET_CTL, 0x10, 0x00},
{WSA883X_PDM_WD_CTL, 0x01, 0x01},
{WSA883X_CURRENT_LIMIT, 0x78, 0x20},
{WSA883X_DRE_CTL_0, 0x07, 0x02},
{WSA883X_VAGC_TIME, 0x0F, 0x0F},
@@ -119,6 +118,7 @@ static const struct wsa_reg_mask_val reg_init[] = {
{WSA883X_ADC_7, 0x04, 0x04},
{WSA883X_ADC_7, 0x02, 0x02},
{WSA883X_CKWD_CTL_0, 0x60, 0x00},
{WSA883X_DRE_CTL_1, 0x3E, 0x20},
{WSA883X_CKWD_CTL_1, 0x1F, 0x1B},
{WSA883X_GMAMP_SUP1, 0x60, 0x60},
};
@@ -134,6 +134,7 @@ enum {
enum {
SPKR_STATUS = 0,
WSA_SUPPLIES_LPM_MODE,
SPKR_ADIE_LB,
};
enum {
@@ -799,6 +800,30 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
}
EXPORT_SYMBOL(wsa883x_codec_info_create_codec_entry);
/*
* wsa883x_codec_get_dev_num - returns swr device number
* @component: Codec instance
*
* Return: swr device number on success or negative error
* code on failure.
*/
int wsa883x_codec_get_dev_num(struct snd_soc_component *component)
{
struct wsa883x_priv *wsa883x;
if (!component)
return -EINVAL;
wsa883x = snd_soc_component_get_drvdata(component);
if (!wsa883x) {
pr_err("%s: wsa883x component is NULL\n", __func__);
return -EINVAL;
}
return wsa883x->swr_slave->dev_num;
}
EXPORT_SYMBOL(wsa883x_codec_get_dev_num);
static int wsa883x_get_compander(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -962,6 +987,7 @@ static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
&port_type[0]);
break;
case SND_SOC_DAPM_POST_PMU:
set_bit(SPKR_STATUS, &wsa883x->status_mask);
break;
case SND_SOC_DAPM_PRE_PMD:
wsa883x_set_port(component, SWR_DAC_PORT,
@@ -1015,19 +1041,31 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,
swr_slvdev_datapath_control(wsa883x->swr_slave,
wsa883x->swr_slave->dev_num,
true);
wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
/* Added delay as per HW sequence */
usleep_range(250, 300);
snd_soc_component_update_bits(component, WSA883X_DRE_CTL_1,
0x01, 0x01);
/* Added delay as per HW sequence */
usleep_range(250, 300);
wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO);
/* Force remove group */
swr_remove_from_group(wsa883x->swr_slave,
wsa883x->swr_slave->dev_num);
set_bit(SPKR_STATUS, &wsa883x->status_mask);
if (test_bit(SPKR_ADIE_LB, &wsa883x->status_mask))
snd_soc_component_update_bits(component,
WSA883X_PA_FSM_CTL, 0x01, 0x01);
break;
case SND_SOC_DAPM_PRE_PMD:
if (!test_bit(SPKR_ADIE_LB, &wsa883x->status_mask))
wcd_disable_irq(&wsa883x->irq_info,
WSA883X_IRQ_INT_PDM_WD);
snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
0x01, 0x00);
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
snd_soc_component_update_bits(component, WSA883X_PDM_WD_CTL,
0x01, 0x00);
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO);
clear_bit(SPKR_STATUS, &wsa883x->status_mask);
clear_bit(SPKR_ADIE_LB, &wsa883x->status_mask);
break;
}
return 0;
@@ -1212,6 +1250,7 @@ static int wsa883x_get_temperature(struct snd_soc_component *component,
static int wsa883x_codec_probe(struct snd_soc_component *component)
{
char w_name[MAX_NAME_LEN];
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
struct swr_device *dev;
int variant = 0, version = 0;
@@ -1220,6 +1259,10 @@ static int wsa883x_codec_probe(struct snd_soc_component *component)
if (!wsa883x)
return -EINVAL;
if (!component->name_prefix)
return -EINVAL;
snd_soc_component_init_regmap(component, wsa883x->regmap);
dev = wsa883x->swr_slave;
@@ -1236,8 +1279,28 @@ static int wsa883x_codec_probe(struct snd_soc_component *component)
wsa883x_codec_init(component);
wsa883x->global_pa_cnt = 0;
snd_soc_dapm_ignore_suspend(dapm,
wsa883x->dai_driver->playback.stream_name);
memset(w_name, 0, sizeof(w_name));
strlcpy(w_name, component->name_prefix, sizeof(w_name));
strlcat(w_name, " ", sizeof(w_name));
strlcat(w_name, wsa883x->dai_driver->playback.stream_name,
sizeof(w_name));
snd_soc_dapm_ignore_suspend(dapm, w_name);
memset(w_name, 0, sizeof(w_name));
strlcpy(w_name, component->name_prefix, sizeof(w_name));
strlcat(w_name, " IN", sizeof(w_name));
snd_soc_dapm_ignore_suspend(dapm, w_name);
memset(w_name, 0, sizeof(w_name));
strlcpy(w_name, component->name_prefix, sizeof(w_name));
strlcat(w_name, " SWR DAC_PORT", sizeof(w_name));
snd_soc_dapm_ignore_suspend(dapm, w_name);
memset(w_name, 0, sizeof(w_name));
strlcpy(w_name, component->name_prefix, sizeof(w_name));
strlcat(w_name, " SPKR", sizeof(w_name));
snd_soc_dapm_ignore_suspend(dapm, w_name);
snd_soc_dapm_sync(dapm);
return 0;
@@ -1375,10 +1438,27 @@ static int wsa883x_event_notify(struct notifier_block *nb,
break;
case BOLERO_WSA_EVT_PA_ON_POST_FSCLK:
if (test_bit(SPKR_STATUS, &wsa883x->status_mask))
if (test_bit(SPKR_STATUS, &wsa883x->status_mask)) {
snd_soc_component_update_bits(wsa883x->component,
WSA883X_PDM_WD_CTL,
0x01, 0x01);
snd_soc_component_update_bits(wsa883x->component,
WSA883X_PA_FSM_CTL,
0x01, 0x01);
wcd_enable_irq(&wsa883x->irq_info,
WSA883X_IRQ_INT_PDM_WD);
/* Added delay as per HW sequence */
usleep_range(3000, 3100);
snd_soc_component_update_bits(wsa883x->component,
WSA883X_DRE_CTL_1,
0x01, 0x00);
/* Added delay as per HW sequence */
usleep_range(5000, 5050);
}
break;
case BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB:
if (test_bit(SPKR_STATUS, &wsa883x->status_mask))
set_bit(SPKR_ADIE_LB, &wsa883x->status_mask);
break;
default:
dev_dbg(wsa883x->dev, "%s: unknown event %d\n",

View File

@@ -21,6 +21,7 @@ int wsa883x_set_channel_map(struct snd_soc_component *component,
int wsa883x_codec_info_create_codec_entry(
struct snd_info_entry *codec_root,
struct snd_soc_component *component);
int wsa883x_codec_get_dev_num(struct snd_soc_component *component);
#else
static int wsa883x_set_channel_map(struct snd_soc_component *component,
u8 *port, u8 num_port, unsigned int *ch_mask,
@@ -36,6 +37,10 @@ static int wsa883x_codec_info_create_codec_entry(
return 0;
}
static int wsa883x_codec_get_dev_num(struct snd_soc_component *component)
{
return 0;
}
#endif
#endif /* _WSA883X_H */

61
asoc/holi-port-config.h Normal file
View File

@@ -0,0 +1,61 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#ifndef _HOLI_PORT_CONFIG
#define _HOLI_PORT_CONFIG
#include <soc/swr-common.h>
#define WSA_MSTR_PORT_MASK 0xFF
/*
* Add port configuration in the format
*{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl, dir,
* stream_type}
*/
static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00},
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x00},
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x00},
{7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0, 0x00, 0x00},
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0, 0x00, 0x00},
};
/* Headset + PCM Haptics */
static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */
{31, 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 */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* LO/AUX */
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0x00, 0x00}, /* DSD */
{0x18F, 0, 0, 0x8, 0x8, 0x0F, 0x00, 0, 0, 0x00, 0x01}, /* PCM_OUT */
};
/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
static struct port_params tx_frame_params_wcd937x[SWR_MSTR_PORT_LEN] = {
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX2 */
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
static struct swr_mstr_port_map sm_port_map[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_default},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
};
static struct swr_mstr_port_map sm_port_map_wcd937x[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_wcd937x},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
};
#endif /* _HOLI_PORT_CONFIG */

6813
asoc/holi.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -46,13 +46,35 @@ static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = {
/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX2 */
{7, 5, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
static struct port_params tx_frame_params_shima[SWR_MSTR_PORT_LEN] = {
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX2 */
{7, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
/* 4.8 MHz clock */
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}, /* TX2 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
static struct swr_mstr_port_map sm_port_map[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_default},
{TX_MACRO, SWR_UC1, tx_frame_params_4p8MHz},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
};
static struct swr_mstr_port_map sm_port_map_shima[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_shima},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},

View File

@@ -5,6 +5,7 @@
#include <sound/soc.h>
SND_SOC_DAILINK_DEFS(usb_audio_rx,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_DUMMY()),

471
asoc/msm_holi_dailink.h Normal file
View File

@@ -0,0 +1,471 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#include <sound/soc.h>
/* FE dai-links */
SND_SOC_DAILINK_DEFS(multimedia1,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia1")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-dsp.0")));
SND_SOC_DAILINK_DEFS(multimedia2,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia2")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-dsp.0")));
SND_SOC_DAILINK_DEFS(voicemmode1,
DAILINK_COMP_ARRAY(COMP_CPU("VoiceMMode1")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-voice")));
SND_SOC_DAILINK_DEFS(msmvoip,
DAILINK_COMP_ARRAY(COMP_CPU("VoIP")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-voip-dsp")));
SND_SOC_DAILINK_DEFS(multimedia3,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia3")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-dsp.2")));
SND_SOC_DAILINK_DEFS(afepcm_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.241")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-afe")));
SND_SOC_DAILINK_DEFS(afepcm_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.240")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-afe")));
SND_SOC_DAILINK_DEFS(multimedia4,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia4")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-compress-dsp")));
SND_SOC_DAILINK_DEFS(auxpcm_hostless,
DAILINK_COMP_ARRAY(COMP_CPU("AUXPCM_HOSTLESS")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
SND_SOC_DAILINK_DEFS(multimedia5,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia5")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-dsp.1")));
SND_SOC_DAILINK_DEFS(listen1,
DAILINK_COMP_ARRAY(COMP_CPU("LSM1")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-lsm-client")));
SND_SOC_DAILINK_DEFS(multimedia7,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia7")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-compress-dsp")));
SND_SOC_DAILINK_DEFS(multimedia10,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia10")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-dsp.1")));
SND_SOC_DAILINK_DEFS(multimedia8,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia8")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-dsp-noirq")));
SND_SOC_DAILINK_DEFS(hdmi_rx_hostless,
DAILINK_COMP_ARRAY(COMP_CPU("HDMI_HOSTLESS")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
SND_SOC_DAILINK_DEFS(voicemmode2,
DAILINK_COMP_ARRAY(COMP_CPU("VoiceMMode2")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-voice")));
SND_SOC_DAILINK_DEFS(listen2,
DAILINK_COMP_ARRAY(COMP_CPU("LSM2")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-lsm-client")));
SND_SOC_DAILINK_DEFS(listen3,
DAILINK_COMP_ARRAY(COMP_CPU("LSM3")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-lsm-client")));
SND_SOC_DAILINK_DEFS(listen4,
DAILINK_COMP_ARRAY(COMP_CPU("LSM4")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-lsm-client")));
SND_SOC_DAILINK_DEFS(listen5,
DAILINK_COMP_ARRAY(COMP_CPU("LSM5")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-lsm-client")));
SND_SOC_DAILINK_DEFS(listen6,
DAILINK_COMP_ARRAY(COMP_CPU("LSM6")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-lsm-client")));
SND_SOC_DAILINK_DEFS(listen7,
DAILINK_COMP_ARRAY(COMP_CPU("LSM7")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-lsm-client")));
SND_SOC_DAILINK_DEFS(listen8,
DAILINK_COMP_ARRAY(COMP_CPU("LSM8")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-lsm-client")));
SND_SOC_DAILINK_DEFS(multimedia9,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia9")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-dsp.0")));
SND_SOC_DAILINK_DEFS(multimedia11,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia11")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-compress-dsp")));
SND_SOC_DAILINK_DEFS(multimedia12,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia12")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-compress-dsp")));
SND_SOC_DAILINK_DEFS(multimedia13,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia13")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-compress-dsp")));
SND_SOC_DAILINK_DEFS(multimedia14,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia14")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-compress-dsp")));
SND_SOC_DAILINK_DEFS(multimedia15,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia15")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-compress-dsp")));
SND_SOC_DAILINK_DEFS(multimedia16,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia16")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-dsp-noirq")));
SND_SOC_DAILINK_DEFS(cdcdma_hostless,
DAILINK_COMP_ARRAY(COMP_CPU("CDC_DMA_HOSTLESS")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
SND_SOC_DAILINK_DEFS(tx3_cdcdma_hostless,
DAILINK_COMP_ARRAY(COMP_CPU("TX3_CDC_DMA_HOSTLESS")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
SND_SOC_DAILINK_DEFS(tert_mi2s_tx_hostless,
DAILINK_COMP_ARRAY(COMP_CPU("TERT_MI2S_TX_HOSTLESS")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
SND_SOC_DAILINK_DEFS(multimedia6,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia6")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-loopback")));
SND_SOC_DAILINK_DEFS(usbaudio_hostless,
DAILINK_COMP_ARRAY(COMP_CPU("USBAUDIO_HOSTLESS")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
SND_SOC_DAILINK_DEFS(slimbus7_hostless,
DAILINK_COMP_ARRAY(COMP_CPU("SLIMBUS7_HOSTLESS")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
SND_SOC_DAILINK_DEFS(multimedia17,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia17")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-compress-dsp")));
SND_SOC_DAILINK_DEFS(slimbus8_hostless,
DAILINK_COMP_ARRAY(COMP_CPU("SLIMBUS8_HOSTLESS")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
SND_SOC_DAILINK_DEFS(tx_cdcdma5_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45115")),
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "tx_macro_tx3"),
COMP_CODEC("wcd938x_codec", "wcd938x_cdc")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
SND_SOC_DAILINK_DEFS(multimedia31,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia31")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-dsp.0")));
SND_SOC_DAILINK_DEFS(multimedia32,
DAILINK_COMP_ARRAY(COMP_CPU("MultiMedia32")),
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-dsp.0")));
SND_SOC_DAILINK_DEFS(afepcm_tx1,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.242")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-afe")));
/* BE dai-links */
SND_SOC_DAILINK_DEFS(afe_pcm_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.224")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(afe_pcm_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.225")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(incall_record_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.32772")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(incall_record_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.32771")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(voice_playback_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.32773")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(voice2_playback_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.32770")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(usb_audio_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.28672")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(usb_audio_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.28673")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(pri_tdm_rx_0,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-tdm.36864")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(pri_tdm_tx_0,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-tdm.36865")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(sec_tdm_rx_0,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-tdm.36880")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(sec_tdm_tx_0,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-tdm.36881")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(tert_tdm_rx_0,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-tdm.36896")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(tert_tdm_tx_0,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-tdm.36897")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(quat_tdm_rx_0,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-tdm.36912")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(quat_tdm_tx_0,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-tdm.36913")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(slimbus_7_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.16398")),
DAILINK_COMP_ARRAY(COMP_CODEC("btfmslim_slave",
"btfm_bt_sco_a2dp_slim_rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(slimbus_7_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.16399")),
DAILINK_COMP_ARRAY(COMP_CODEC("btfmslim_slave",
"btfm_bt_sco_slim_tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(slimbus_8_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.16401")),
DAILINK_COMP_ARRAY(COMP_CODEC("btfmslim_slave",
"btfm_fm_slim_tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(pri_mi2s_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.0")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(pri_mi2s_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.0")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(sec_mi2s_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.1")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(sec_mi2s_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.1")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(tert_mi2s_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.2")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(tert_mi2s_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.2")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(quat_mi2s_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.3")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(quat_mi2s_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.3")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(auxpcm_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-auxpcm.1")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(auxpcm_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-auxpcm.1")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(sec_auxpcm_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-auxpcm.2")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(sec_auxpcm_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-auxpcm.2")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(tert_auxpcm_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-auxpcm.3")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(tert_auxpcm_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-auxpcm.3")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(quat_auxpcm_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-auxpcm.4")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(quat_auxpcm_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-auxpcm.4")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(rx_dma_rx0,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45104")),
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "rx_macro_rx1"),
COMP_CODEC("wcd938x_codec", "wcd938x_cdc"),
COMP_CODEC("wcd937x_codec", "wcd937x_cdc")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(rx_dma_rx1,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45106")),
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "rx_macro_rx2"),
COMP_CODEC("wsa-codec0", "wsa_rx0"),
COMP_CODEC("wsa-codec1", "wsa_rx1"),
COMP_CODEC("wcd938x_codec", "wcd938x_cdc"),
COMP_CODEC("wcd937x_codec", "wcd937x_cdc")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(rx_dma_rx2,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45108")),
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "rx_macro_rx3"),
COMP_CODEC("wcd938x_codec", "wcd938x_cdc"),
COMP_CODEC("wcd937x_codec", "wcd937x_cdc")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(rx_dma_rx3,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45110")),
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "rx_macro_rx4"),
COMP_CODEC("wcd938x_codec", "wcd938x_cdc"),
COMP_CODEC("wcd937x_codec", "wcd937x_cdc")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(tx_dma_tx3,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45111")),
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "tx_macro_tx1"),
COMP_CODEC("wcd938x_codec", "wcd938x_cdc"),
COMP_CODEC("wcd937x_codec", "wcd937x_cdc")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(tx_dma_tx4,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45113")),
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "tx_macro_tx2"),
COMP_CODEC("wcd938x_codec", "wcd938x_cdc"),
COMP_CODEC("wcd937x_codec", "wcd937x_cdc")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(va_dma_tx0,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45089")),
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "va_macro_tx1")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(va_dma_tx1,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45091")),
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "va_macro_tx2")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(va_dma_tx2,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45093")),
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "va_macro_tx3")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(afe_loopback_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.24577")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(proxy_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.8195")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(proxy_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.8194")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));

34
config/holiauto.conf Normal file
View File

@@ -0,0 +1,34 @@
export CONFIG_PINCTRL_LPI=m
export CONFIG_AUDIO_EXT_CLK=m
export CONFIG_SND_SOC_WCD9XXX_V2=m
export CONFIG_SND_SOC_WCD_MBHC=m
export CONFIG_WCD9XXX_CODEC_CORE_V2=m
export CONFIG_MSM_CDC_PINCTRL=m
export CONFIG_MSM_QDSP6V2_CODECS=m
export CONFIG_MSM_QDSP6_APRV2_RPMSG=m
export CONFIG_MSM_ADSP_LOADER=m
export CONFIG_REGMAP_SWR=m
export CONFIG_MSM_QDSP6_SSR=m
export CONFIG_MSM_QDSP6_PDR=m
export CONFIG_MSM_QDSP6_NOTIFIER=m
export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m
export CONFIG_SOUNDWIRE=m
export CONFIG_SOUNDWIRE_MSTR_CTRL=m
export CONFIG_SND_SOC_QDSP6V2=m
export CONFIG_SND_SOC_WCD_MBHC_ADC=m
export CONFIG_QTI_PP=m
export CONFIG_SND_HWDEP_ROUTING=m
export CONFIG_SND_SOC_MSM_STUB=m
export CONFIG_SND_SOC_BOLERO=m
export CONFIG_VA_MACRO=m
export CONFIG_RX_MACRO=m
export CONFIG_TX_MACRO=m
export CONFIG_SND_SOC_WCD_IRQ=m
export CONFIG_SND_SOC_WCD938X=m
export CONFIG_SND_SOC_WCD938X_SLAVE=m
export CONFIG_SND_SOC_WCD937X=m
export CONFIG_SND_SOC_WCD937X_SLAVE=m
export CONFIG_SND_SOC_WSA881X_ANALOG=m
export CONFIG_SND_SOC_HOLI=m
export CONFIG_SND_EVENT=m
export CONFIG_DIGITAL_CDC_RSC_MGR=m

38
config/holiautoconf.h Normal file
View File

@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#define CONFIG_PINCTRL_LPI 1
#define CONFIG_AUDIO_EXT_CLK 1
#define CONFIG_SND_SOC_WCD9XXX_V2 1
#define CONFIG_SND_SOC_WCD_MBHC 1
#define CONFIG_WCD9XXX_CODEC_CORE_V2 1
#define CONFIG_MSM_CDC_PINCTRL 1
#define CONFIG_MSM_QDSP6V2_CODECS 1
#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1
#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1
#define CONFIG_MSM_ADSP_LOADER 1
#define CONFIG_REGMAP_SWR 1
#define CONFIG_MSM_QDSP6_SSR 1
#define CONFIG_MSM_QDSP6_PDR 1
#define CONFIG_MSM_QDSP6_NOTIFIER 1
#define CONFIG_SOUNDWIRE 1
#define CONFIG_SOUNDWIRE_MSTR_CTRL 1
#define CONFIG_SND_SOC_WCD_MBHC_ADC 1
#define CONFIG_SND_SOC_QDSP6V2 1
#define CONFIG_QTI_PP 1
#define CONFIG_SND_HWDEP_ROUTING 1
#define CONFIG_SND_SOC_MSM_STUB 1
#define CONFIG_SND_SOC_BOLERO 1
#define CONFIG_VA_MACRO 1
#define CONFIG_RX_MACRO 1
#define CONFIG_TX_MACRO 1
#define CONFIG_SND_SOC_WCD_IRQ 1
#define CONFIG_SND_SOC_WCD938X 1
#define CONFIG_SND_SOC_WCD938X_SLAVE 1
#define CONFIG_SND_SOC_WCD937X 1
#define CONFIG_SND_SOC_WCD937X_SLAVE 1
#define CONFIG_SND_SOC_WSA881X_ANALOG 1
#define CONFIG_SND_SOC_HOLI 1
#define CONFIG_SND_EVENT 1
#define CONFIG_DIGITAL_CDC_RSC_MGR 1

View File

@@ -404,7 +404,7 @@ static int adsp_loader_probe(struct platform_device *pdev)
&adsp_fuse_not_supported);
if (ret) {
dev_dbg(&pdev->dev,
"%s: adsp_fuse_not_supported prop not found",
"%s: adsp_fuse_not_supported prop not found %d\n",
__func__, ret);
goto wqueue;
}

View File

@@ -41,6 +41,7 @@
struct msm_audio_ion_private {
bool smmu_enabled;
struct device *cb_dev;
struct device *cb_cma_dev;
u8 device_status;
struct list_head alloc_list;
struct mutex list_mutex;
@@ -127,7 +128,8 @@ exit:
}
static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
dma_addr_t *addr, size_t *len, bool is_iova)
dma_addr_t *addr, size_t *len, bool is_iova,
bool cma_mem)
{
struct msm_audio_alloc_data *alloc_data;
@@ -136,7 +138,10 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
int rc = 0;
void *vaddr = NULL;
cb_dev = msm_audio_ion_data.cb_dev;
if (cma_mem)
cb_dev = msm_audio_ion_data.cb_cma_dev;
else
cb_dev = msm_audio_ion_data.cb_dev;
/* Data required per buffer mapping */
alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL);
@@ -213,14 +218,18 @@ free_alloc_data:
return rc;
}
static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf)
static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf, bool cma_mem)
{
int rc = 0;
struct msm_audio_alloc_data *alloc_data = NULL;
struct list_head *ptr, *next;
struct device *cb_dev = msm_audio_ion_data.cb_dev;
struct device *cb_dev;
bool found = false;
if (cma_mem)
cb_dev = msm_audio_ion_data.cb_cma_dev;
else
cb_dev = msm_audio_ion_data.cb_dev;
/*
* Though list_for_each_safe is delete safe, lock
* should be explicitly acquired to avoid race condition
@@ -266,7 +275,7 @@ static int msm_audio_ion_get_phys(struct dma_buf *dma_buf,
{
int rc = 0;
rc = msm_audio_dma_buf_map(dma_buf, addr, len, is_iova);
rc = msm_audio_dma_buf_map(dma_buf, addr, len, is_iova, false);
if (rc) {
pr_err("%s: failed to map DMA buf, err = %d\n",
__func__, rc);
@@ -364,7 +373,7 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
if (IS_ERR_OR_NULL(*vaddr)) {
pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
rc = -ENOMEM;
msm_audio_dma_buf_unmap(dma_buf);
msm_audio_dma_buf_unmap(dma_buf, false);
goto err;
}
@@ -606,7 +615,7 @@ void msm_audio_get_handle(int fd, void **handle)
* @bufsz: buffer size
* @paddr: Physical address to be assigned with allocated region
* @plen: length of allocated region to be assigned
* vaddr: virtual address to be assigned
* @vaddr: virtual address to be assigned
*
* Returns 0 on success or error on failure
*/
@@ -662,6 +671,67 @@ err:
}
EXPORT_SYMBOL(msm_audio_ion_import);
/**
* msm_audio_ion_import_cma-
* Import ION buffer with given file descriptor
*
* @dma_buf: dma_buf for the ION memory
* @fd: file descriptor for the ION memory
* @ionflag: flags associated with ION buffer
* @bufsz: buffer size
* @paddr: Physical address to be assigned with allocated region
* @plen: length of allocated region to be assigned
* vaddr: virtual address to be assigned
*
* Returns 0 on success or error on failure
*/
int msm_audio_ion_import_cma(struct dma_buf **dma_buf, int fd,
unsigned long *ionflag, size_t bufsz,
dma_addr_t *paddr, size_t *plen, void **vaddr)
{
int rc = 0;
if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
pr_debug("%s: probe is not done, deferred\n", __func__);
return -EPROBE_DEFER;
}
if (!dma_buf || !paddr || !vaddr || !plen ||
!msm_audio_ion_data.cb_cma_dev) {
pr_err("%s: Invalid params\n", __func__);
return -EINVAL;
}
/* bufsz should be 0 and fd shouldn't be 0 as of now */
*dma_buf = dma_buf_get(fd);
pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd);
if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
pr_err("%s: dma_buf_get failed\n", __func__);
rc = -EINVAL;
goto err;
}
if (ionflag != NULL) {
rc = dma_buf_get_flags(*dma_buf, ionflag);
if (rc) {
pr_err("%s: could not get flags for the dma_buf\n",
__func__);
goto err_ion_flag;
}
}
msm_audio_dma_buf_map(*dma_buf, paddr, plen, true, true);
return 0;
err_ion_flag:
dma_buf_put(*dma_buf);
err:
*dma_buf = NULL;
return rc;
}
EXPORT_SYMBOL(msm_audio_ion_import_cma);
/**
* msm_audio_ion_free -
* fress ION memory for given client and handle
@@ -683,7 +753,7 @@ int msm_audio_ion_free(struct dma_buf *dma_buf)
if (ret)
return ret;
msm_audio_dma_buf_unmap(dma_buf);
msm_audio_dma_buf_unmap(dma_buf, false);
return 0;
}
@@ -717,6 +787,27 @@ void msm_audio_ion_crash_handler(void)
}
EXPORT_SYMBOL(msm_audio_ion_crash_handler);
/**
* msm_audio_ion_free_cma -
* fress ION memory for given client and handle
*
* @dma_buf: dma_buf for the ION memory
*
* Returns 0 on success or error on failure
*/
int msm_audio_ion_free_cma(struct dma_buf *dma_buf)
{
if (!dma_buf) {
pr_err("%s: dma_buf invalid\n", __func__);
return -EINVAL;
}
msm_audio_dma_buf_unmap(dma_buf, true);
return 0;
}
EXPORT_SYMBOL(msm_audio_ion_free_cma);
/**
* msm_audio_ion_mmap -
* Audio ION memory map
@@ -954,6 +1045,7 @@ static int msm_audio_smmu_init(struct device *dev)
static const struct of_device_id msm_audio_ion_dt_match[] = {
{ .compatible = "qcom,msm-audio-ion" },
{ .compatible = "qcom,msm-audio-ion-cma"},
{ }
};
MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match);
@@ -1047,6 +1139,10 @@ static int msm_audio_ion_probe(struct platform_device *pdev)
msm_audio_ion_non_hyp);
msm_audio_ion_data.is_non_hypervisor = is_non_hypervisor_en;
if (of_device_is_compatible(dev->of_node, "qcom,msm-audio-ion-cma")) {
msm_audio_ion_data.cb_cma_dev = dev;
return 0;
}
smmu_enabled = of_property_read_bool(dev->of_node,
msm_audio_ion_dt);
msm_audio_ion_data.smmu_enabled = smmu_enabled;

View File

@@ -69,5 +69,10 @@ extern int msm_cdc_init_supplies_v2(struct device *dev,
int msm_cdc_init_wcd_supply(struct device_node *np, const char *name,
struct cdc_wcd_supply *cdc_supply);
int msm_cdc_enable_wcd_supply(struct cdc_wcd_supply *cdc_supply, bool enable);
extern int msm_cdc_set_supply_min_voltage(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies, char *supply_name,
int vval_min, bool override_min_vol);
#endif

View File

@@ -5467,6 +5467,7 @@ struct afe_param_id_lpass_core_shared_clk_cfg {
#define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX 0x10015002
#define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_AUDIOSPHERE 0x10028000
#define VPM_TX_DM_FLUENCE_EF_COPP_TOPOLOGY 0x10000005
#define AUDIO_RX_MONO_VOIP_COPP_TOPOLOGY 0x11000101
/* Memory map regions command payload used by the
* #ASM_CMD_SHARED_MEM_MAP_REGIONS ,#ADM_CMD_SHARED_MEM_MAP_REGIONS
@@ -11717,6 +11718,10 @@ struct avcs_fwk_ver_info {
#define LSM_SESSION_CMD_SET_PARAMS (0x00012A83)
#define LSM_SESSION_CMD_SET_PARAMS_V2 (0x00012A8F)
#define LSM_SESSION_CMD_SET_PARAMS_V3 (0x00012A92)
#define LSM_SESSION_CMD_GET_PARAMS_V2 (0x00012A90)
#define LSM_SESSION_CMDRSP_GET_PARAMS_V2 (0x00012A91)
#define LSM_SESSION_CMD_GET_PARAMS_V3 (0x00012A93)
#define LSM_SESSION_CMDRSP_GET_PARAMS_V3 (0x00012A94)
#define LSM_SESSION_CMD_REGISTER_SOUND_MODEL (0x00012A84)
#define LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL (0x00012A85)
#define LSM_SESSION_CMD_START (0x00012A86)

View File

@@ -30,6 +30,7 @@ struct cal_block_data {
struct list_head list;
struct cal_data cal_data;
bool cal_stale;
bool cma_mem;
struct mem_map_data map_data;
int32_t buffer_number;
};

View File

@@ -34,6 +34,10 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
unsigned long *ionflag, size_t bufsz,
dma_addr_t *paddr, size_t *pa_len, void **vaddr);
int msm_audio_ion_free(struct dma_buf *dma_buf);
int msm_audio_ion_import_cma(struct dma_buf **dma_buf, int fd,
unsigned long *ionflag, size_t bufsz,
dma_addr_t *paddr, size_t *pa_len, void **vaddr);
int msm_audio_ion_free_cma(struct dma_buf *dma_buf);
int msm_audio_ion_mmap(struct audio_buffer *abuff, struct vm_area_struct *vma);
int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op);

View File

@@ -126,6 +126,7 @@ enum {
#define TOPOLOGY_SPECIFIC_CHANNEL_INFO
#define MSM_SPKR_PROT_SPV3
#define MSM_SPKR_PROT_SPV4
#define MSM_CMA_MEM_ALLOC
enum {
VERSION_0_0,
@@ -156,7 +157,10 @@ struct audio_cal_data {
__s32 cal_size;
/* If mem_handle if shared memory is used*/
__s32 mem_handle;
/* size of virtual memory if shared memory not used */
#ifdef MSM_CMA_MEM_ALLOC
/* cma allocation flag if cma heap memory is used */
__u32 cma_mem;
#endif
};

View File

@@ -0,0 +1,90 @@
#ifndef __AUDIO_COMPRESSED_FORMATS_H
#define __AUDIO_COMPRESSED_FORMATS_H
#include <linux/types.h>
#define AUDIO_COMP_FORMAT_ALAC 0x1
#define AUDIO_COMP_FORMAT_APE 0x2
#define AUDIO_COMP_FORMAT_APTX 0x3
#define AUDIO_COMP_FORMAT_DSD 0x4
#define AUDIO_COMP_FORMAT_FLAC 0x5
#define AUDIO_COMP_FORMAT_VORBIS 0x6
#define AUDIO_COMP_FORMAT_WMA 0x7
#define AUDIO_COMP_FORMAT_WMA_PRO 0x8
#define SND_COMPRESS_DEC_HDR
struct snd_generic_dec_aac {
__u16 audio_obj_type;
__u16 pce_bits_size;
} __attribute__((packed, aligned(4)));
struct snd_generic_dec_flac {
__u16 sample_size;
__u16 min_blk_size;
__u16 max_blk_size;
__u16 min_frame_size;
__u16 max_frame_size;
} __attribute__((packed, aligned(4)));
struct snd_generic_dec_alac {
__u32 frame_length;
__u8 compatible_version;
__u8 bit_depth;
__u8 pb;
__u8 mb;
__u8 kb;
__u8 num_channels;
__u16 max_run;
__u32 max_frame_bytes;
__u32 avg_bit_rate;
__u32 sample_rate;
__u32 channel_layout_tag;
} __attribute__((packed, aligned(4)));
struct snd_generic_dec_ape {
__u16 compatible_version;
__u16 compression_level;
__u32 format_flags;
__u32 blocks_per_frame;
__u32 final_frame_blocks;
__u32 total_frames;
__u16 bits_per_sample;
__u16 num_channels;
__u32 sample_rate;
__u32 seek_table_present;
} __attribute__((packed, aligned(4)));
struct snd_generic_dec_wma {
__u32 super_block_align;
__u32 bits_per_sample;
__u32 channelmask;
__u32 encodeopt;
__u32 encodeopt1;
__u32 encodeopt2;
__u32 avg_bit_rate;
} __attribute__((packed, aligned(4)));
#define SND_DEC_WMA_EXTENTED_SUPPORT
struct snd_generic_dec_aptx {
__u32 lap;
__u32 uap;
__u32 nap;
} __attribute__((packed, aligned(4)));
struct snd_generic_dec_vorbis {
__u32 bit_stream_fmt;
} __attribute__((packed, aligned(4)));
/** struct snd_generic_dec_dsd - codec for DSD format
* @blk_size - dsd channel block size
*/
struct snd_generic_dec_dsd {
__u32 blk_size;
} __attribute__((packed, aligned(4)));
struct snd_generic_dec_amrwb_plus {
__u32 bit_stream_fmt;
} __attribute__((packed, aligned(4)));
#endif

View File

@@ -36,7 +36,8 @@
#define LSM_REG_MULTI_SND_MODEL (10)
#define LSM_DEREG_MULTI_SND_MODEL (11)
#define LSM_MULTI_SND_MODEL_CONFIDENCE_LEVELS (12)
#define LSM_PARAMS_MAX (LSM_MULTI_SND_MODEL_CONFIDENCE_LEVELS + 1)
#define LSM_GET_CUSTOM_PARAMS (13)
#define LSM_PARAMS_MAX (LSM_GET_CUSTOM_PARAMS + 1)
#define LSM_EVENT_NON_TIME_STAMP_MODE (0)
#define LSM_EVENT_TIME_STAMP_MODE (1)
@@ -288,6 +289,29 @@ struct snd_lsm_input_hw_params {
__u16 num_channels;
} __packed;
/*
* Param get info for each parameter type
* add "for SNDRV_LSM_GET_MODULE_PARAMS ioctl"
* Existing member variables:
* @module_id: Module to which parameter is to be set
* @instance_id: instance id of the param to which parameter is to be set
* @param_id: Parameter that is to be set
* @param_size: size of requested param
* @param_type: Parameter type as defined in values upto LSM_PARAMS_MAX
* @stage_idx: detection stage for which the param is applicable
* @payload: memory where requested param info will be populated
*/
struct lsm_params_get_info {
__u32 module_id;
__u16 instance_id;
__u16 reserved;
__u32 param_id;
__u32 param_size;
__u32 param_type;
__u16 stage_idx;
__u8 payload[0];
} __packed;
#define SNDRV_LSM_DEREG_SND_MODEL _IOW('U', 0x01, int)
#define SNDRV_LSM_EVENT_STATUS _IOW('U', 0x02, struct snd_lsm_event_status)
#define SNDRV_LSM_ABORT_EVENT _IOW('U', 0x03, int)
@@ -315,5 +339,6 @@ struct snd_lsm_input_hw_params {
struct snd_lsm_session_data_v2)
#define SNDRV_LSM_SET_MODULE_PARAMS_V2 _IOW('U', 0x13, \
struct snd_lsm_module_params)
#define SNDRV_LSM_GET_MODULE_PARAMS _IOWR('U', 0x14, \
struct lsm_params_get_info)
#endif

View File

@@ -26,6 +26,7 @@
#include "swr-slave-registers.h"
#include <dsp/digital-cdc-rsc-mgr.h>
#include "swr-mstr-ctrl.h"
#include "swr-slave-port-config.h"
#define SWR_NUM_PORTS 4 /* TODO - Get this info from DT */
@@ -80,6 +81,8 @@
#define SWRM_DP_PORT_CTRL_OFFSET2_SHFT 0x10
#define SWRM_DP_PORT_CTRL_OFFSET1_SHFT 0x08
#define SWR_OVERFLOW_RETRY_COUNT 30
/* pm runtime auto suspend timer in msecs */
static int auto_suspend_timer = 500;
module_param(auto_suspend_timer, int, 0664);
@@ -108,6 +111,11 @@ enum {
LPASS_AUDIO_CORE,
};
enum {
SWRM_WR_CHECK_AVAIL,
SWRM_RD_CHECK_AVAIL,
};
#define TRUE 1
#define FALSE 0
@@ -122,6 +130,32 @@ static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr);
static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val);
static int swrm_runtime_resume(struct device *dev);
static u64 swrm_phy_dev[] = {
0,
0xd01170223,
0x858350223,
0x858350222,
0x858350221,
0x858350220,
};
static u8 swrm_get_device_id(struct swr_mstr_ctrl *swrm, u8 devnum)
{
int i;
for (i = 1; i < (swrm->num_dev + 1); i++) {
if (swrm->logical_dev[devnum] == swrm_phy_dev[i])
break;
}
if (i == (swrm->num_dev + 1)) {
pr_info("%s: could not find the slave\n", __func__);
i = devnum;
}
return i;
}
static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq)
{
int clk_div = 0;
@@ -719,6 +753,9 @@ static int swrm_get_port_config(struct swr_mstr_ctrl *swrm)
(swrm->master_id == MASTER_ID_RX))
usecase = 1;
if (swrm->bus_clk == SWR_CLK_RATE_4P8MHZ)
usecase = 1;
params = swrm->port_param[usecase];
copy_port_tables(swrm, params);
@@ -790,6 +827,54 @@ static u32 swrm_get_packed_reg_val(u8 *cmd_id, u8 cmd_data,
return val;
}
static void swrm_wait_for_fifo_avail(struct swr_mstr_ctrl *swrm, int swrm_rd_wr)
{
u32 fifo_outstanding_cmd;
u32 fifo_retry_count = SWR_OVERFLOW_RETRY_COUNT;
if (swrm_rd_wr) {
/* Check for fifo underflow during read */
/* Check no of outstanding commands in fifo before read */
fifo_outstanding_cmd = ((swr_master_read(swrm,
SWRM_CMD_FIFO_STATUS) & 0x001F0000) >> 16);
if (fifo_outstanding_cmd == 0) {
while (fifo_retry_count) {
usleep_range(500, 510);
fifo_outstanding_cmd =
((swr_master_read (swrm,
SWRM_CMD_FIFO_STATUS) & 0x001F0000)
>> 16);
fifo_retry_count--;
if (fifo_outstanding_cmd > 0)
break;
}
}
if (fifo_outstanding_cmd == 0)
dev_err_ratelimited(swrm->dev,
"%s err read underflow\n", __func__);
} else {
/* Check for fifo overflow during write */
/* Check no of outstanding commands in fifo before write */
fifo_outstanding_cmd = ((swr_master_read(swrm,
SWRM_CMD_FIFO_STATUS) & 0x00001F00)
>> 8);
if (fifo_outstanding_cmd == swrm->wr_fifo_depth) {
while (fifo_retry_count) {
usleep_range(500, 510);
fifo_outstanding_cmd =
((swr_master_read(swrm, SWRM_CMD_FIFO_STATUS)
& 0x00001F00) >> 8);
fifo_retry_count--;
if (fifo_outstanding_cmd < swrm->wr_fifo_depth)
break;
}
}
if (fifo_outstanding_cmd == swrm->wr_fifo_depth)
dev_err_ratelimited(swrm->dev,
"%s err write overflow\n", __func__);
}
}
static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data,
u8 dev_addr, u8 cmd_id, u16 reg_addr,
u32 len)
@@ -803,12 +888,19 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data,
/* skip delay if read is handled in platform driver */
swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val);
} else {
/*
* Check for outstanding cmd wrt. write fifo depth to avoid
* overflow as read will also increase write fifo cnt.
*/
swrm_wait_for_fifo_avail(swrm, SWRM_WR_CHECK_AVAIL);
/* wait for FIFO RD to complete to avoid overflow */
usleep_range(100, 105);
swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val);
/* wait for FIFO RD CMD complete to avoid overflow */
usleep_range(250, 255);
}
/* Check if slave responds properly after FIFO RD is complete */
swrm_wait_for_fifo_avail(swrm, SWRM_RD_CHECK_AVAIL);
retry_read:
*cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO);
dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, rcmd_id: 0x%x, \
@@ -855,6 +947,11 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data,
dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x,wcmd_id: 0x%x, \
dev_num: 0x%x, cmd_data: 0x%x\n", __func__,
reg_addr, cmd_id, swrm->wcmd_id,dev_addr, cmd_data);
/*
* Check for outstanding cmd wrt. write fifo depth to avoid
* overflow.
*/
swrm_wait_for_fifo_avail(swrm, SWRM_WR_CHECK_AVAIL);
swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val);
/*
* wait for FIFO WR command to complete to avoid overflow
@@ -1102,9 +1199,9 @@ int swrm_get_clk_div_rate(int mclk_freq, int bus_clk_freq)
if (bus_clk_freq <= SWR_CLK_RATE_0P6MHZ)
bus_clk_freq = SWR_CLK_RATE_0P6MHZ;
else if (bus_clk_freq <= SWR_CLK_RATE_1P2MHZ)
bus_clk_freq = SWR_CLK_RATE_1P2MHZ;
bus_clk_freq = SWR_CLK_RATE_4P8MHZ;
else if (bus_clk_freq <= SWR_CLK_RATE_2P4MHZ)
bus_clk_freq = SWR_CLK_RATE_2P4MHZ;
bus_clk_freq = SWR_CLK_RATE_4P8MHZ;
else if(bus_clk_freq <= SWR_CLK_RATE_4P8MHZ)
bus_clk_freq = SWR_CLK_RATE_4P8MHZ;
else if(bus_clk_freq <= SWR_CLK_RATE_9P6MHZ)
@@ -1235,26 +1332,91 @@ static void swrm_cleanup_disabled_port_reqs(struct swr_master *master)
}
}
}
static u8 swrm_get_controller_offset1(struct swr_mstr_ctrl *swrm,
u8* dev_offset, u8 off1)
{
u8 offset1 = 0x0F;
int i = 0;
if (swrm->master_id == MASTER_ID_TX) {
for (i = 1; i < SWRM_NUM_AUTO_ENUM_SLAVES; i++) {
pr_debug("%s: dev offset: %d\n",
__func__, dev_offset[i]);
if (offset1 > dev_offset[i])
offset1 = dev_offset[i];
}
} else {
offset1 = off1;
}
pr_debug("%s: offset: %d\n", __func__, offset1);
return offset1;
}
static void swrm_get_device_frame_shape(struct swr_mstr_ctrl *swrm,
struct swrm_mports *mport,
struct swr_port_info *port_req)
{
u32 port_id = 0;
u8 dev_num = 0;
struct port_params *pp_dev;
struct port_params *pp_port;
if ((swrm->master_id == MASTER_ID_TX) &&
((swrm->bus_clk == SWR_CLK_RATE_9P6MHZ) ||
(swrm->bus_clk == SWR_CLK_RATE_4P8MHZ))) {
dev_num = swrm_get_device_id(swrm, port_req->dev_num);
port_id = port_req->slave_port_id;
if (swrm->bus_clk == SWR_CLK_RATE_9P6MHZ)
pp_dev = swrdev_frame_params_9p6MHz[dev_num].pp;
else
pp_dev = swrdev_frame_params_4p8MHz[dev_num].pp;
pp_port = &pp_dev[port_id];
port_req->sinterval = pp_port->si;
port_req->offset1 = pp_port->off1;
port_req->offset2 = pp_port->off2;
port_req->hstart = pp_port->hstart;
port_req->hstop = pp_port->hstop;
port_req->word_length = pp_port->wd_len;
port_req->blk_pack_mode = pp_port->bp_mode;
port_req->blk_grp_count = pp_port->bgp_ctrl;
port_req->lane_ctrl = pp_port->lane_ctrl;
} else {
/* copy master port config to slave */
port_req->sinterval = mport->sinterval;
port_req->offset1 = mport->offset1;
port_req->offset2 = mport->offset2;
port_req->hstart = mport->hstart;
port_req->hstop = mport->hstop;
port_req->word_length = mport->word_length;
port_req->blk_pack_mode = mport->blk_pack_mode;
port_req->blk_grp_count = mport->blk_grp_count;
port_req->lane_ctrl = mport->lane_ctrl;
}
}
static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
{
u32 value, slv_id;
u32 value = 0, slv_id = 0;
struct swr_port_info *port_req;
int i;
struct swrm_mports *mport;
struct swrm_mports *prev_mport = NULL;
u32 reg[SWRM_MAX_PORT_REG];
u32 val[SWRM_MAX_PORT_REG];
int len = 0;
u8 hparams;
u8 offset1 = 0;
u8 hparams = 0;
u32 controller_offset = 0;
struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
u8 dev_offset[SWRM_NUM_AUTO_ENUM_SLAVES];
if (!swrm) {
pr_err("%s: swrm is null\n", __func__);
return;
}
memset(dev_offset, 0xff, SWRM_NUM_AUTO_ENUM_SLAVES);
dev_dbg(swrm->dev, "%s: master num_port: %d\n", __func__,
master->num_port);
@@ -1268,6 +1430,12 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
list_for_each_entry(port_req, &mport->port_req_list, list) {
slv_id = port_req->slave_port_id;
/* Assumption: If different channels in the same port
* on master is enabled for different slaves, then each
* slave offset should be configured differently.
*/
swrm_get_device_frame_shape(swrm, mport, port_req);
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(port_req->req_ch,
port_req->dev_num, 0x00,
@@ -1275,36 +1443,36 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
bank));
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(mport->sinterval,
val[len++] = SWR_REG_VAL_PACK(
port_req->sinterval & 0xFF,
port_req->dev_num, 0x00,
SWRS_DP_SAMPLE_CONTROL_1_BANK(slv_id,
bank));
/* Assumption: If different channels in the same port
* on master is enabled for different slaves, then each
* slave offset should be configured differently.
*/
if (prev_mport == mport)
offset1 += mport->offset1;
else {
offset1 = mport->offset1;
prev_mport = mport;
}
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(offset1,
val[len++] = SWR_REG_VAL_PACK(
(port_req->sinterval >> 8)& 0xFF,
port_req->dev_num, 0x00,
SWRS_DP_SAMPLE_CONTROL_2_BANK(slv_id,
bank));
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(port_req->offset1,
port_req->dev_num, 0x00,
SWRS_DP_OFFSET_CONTROL_1_BANK(slv_id,
bank));
if (mport->offset2 != SWR_INVALID_PARAM) {
if (port_req->offset2 != SWR_INVALID_PARAM) {
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(mport->offset2,
val[len++] = SWR_REG_VAL_PACK(port_req->offset2,
port_req->dev_num, 0x00,
SWRS_DP_OFFSET_CONTROL_2_BANK(
slv_id, bank));
}
if (mport->hstart != SWR_INVALID_PARAM
&& mport->hstop != SWR_INVALID_PARAM) {
hparams = (mport->hstart << 4) | mport->hstop;
if (port_req->hstart != SWR_INVALID_PARAM
&& port_req->hstop != SWR_INVALID_PARAM) {
hparams = (port_req->hstart << 4) |
port_req->hstop;
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(hparams,
@@ -1312,39 +1480,42 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
SWRS_DP_HCONTROL_BANK(slv_id,
bank));
}
if (mport->word_length != SWR_INVALID_PARAM) {
if (port_req->word_length != SWR_INVALID_PARAM) {
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] =
SWR_REG_VAL_PACK(mport->word_length,
SWR_REG_VAL_PACK(port_req->word_length,
port_req->dev_num, 0x00,
SWRS_DP_BLOCK_CONTROL_1(slv_id));
}
if (mport->blk_pack_mode != SWR_INVALID_PARAM
if (port_req->blk_pack_mode != SWR_INVALID_PARAM
&& swrm->master_id != MASTER_ID_WSA) {
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] =
SWR_REG_VAL_PACK(mport->blk_pack_mode,
SWR_REG_VAL_PACK(
port_req->blk_pack_mode,
port_req->dev_num, 0x00,
SWRS_DP_BLOCK_CONTROL_3_BANK(slv_id,
bank));
}
if (mport->blk_grp_count != SWR_INVALID_PARAM) {
if (port_req->blk_grp_count != SWR_INVALID_PARAM) {
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] =
SWR_REG_VAL_PACK(mport->blk_grp_count,
SWR_REG_VAL_PACK(
port_req->blk_grp_count,
port_req->dev_num, 0x00,
SWRS_DP_BLOCK_CONTROL_2_BANK(slv_id,
bank));
SWRS_DP_BLOCK_CONTROL_2_BANK(
slv_id, bank));
}
if (mport->lane_ctrl != SWR_INVALID_PARAM) {
if (port_req->lane_ctrl != SWR_INVALID_PARAM) {
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] =
SWR_REG_VAL_PACK(mport->lane_ctrl,
SWR_REG_VAL_PACK(port_req->lane_ctrl,
port_req->dev_num, 0x00,
SWRS_DP_LANE_CONTROL_BANK(slv_id,
bank));
SWRS_DP_LANE_CONTROL_BANK(
slv_id, bank));
}
port_req->ch_en = port_req->req_ch;
dev_offset[port_req->dev_num] = port_req->offset1;
}
value = ((mport->req_ch)
<< SWRM_DP_PORT_CTRL_EN_CHAN_SHFT);
@@ -1352,15 +1523,16 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
if (mport->offset2 != SWR_INVALID_PARAM)
value |= ((mport->offset2)
<< SWRM_DP_PORT_CTRL_OFFSET2_SHFT);
value |= ((mport->offset1)
<< SWRM_DP_PORT_CTRL_OFFSET1_SHFT);
controller_offset = (swrm_get_controller_offset1(swrm,
dev_offset, mport->offset1));
value |= (controller_offset << SWRM_DP_PORT_CTRL_OFFSET1_SHFT);
mport->offset1 = controller_offset;
value |= (mport->sinterval & 0xFF);
reg[len] = SWRM_DP_PORT_CTRL_BANK((i + 1), bank);
val[len++] = value;
dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n",
__func__, i,
__func__, (i + 1),
(SWRM_DP_PORT_CTRL_BANK((i + 1), bank)), value);
reg[len] = SWRM_DP_SAMPLECTRL2_BANK((i + 1), bank);
@@ -1746,6 +1918,7 @@ static void swrm_enable_slave_irq(struct swr_mstr_ctrl *swrm)
{
int i;
int status = 0;
u32 temp;
status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS);
if (!status) {
@@ -1756,6 +1929,8 @@ static void swrm_enable_slave_irq(struct swr_mstr_ctrl *swrm)
dev_dbg(swrm->dev, "%s: slave status: 0x%x\n", __func__, status);
for (i = 0; i < (swrm->master.num_dev + 1); i++) {
if (status & SWRM_MCP_SLV_STATUS_MASK) {
swrm_cmd_fifo_rd_cmd(swrm, &temp, i, 0x0,
SWRS_SCP_INT_STATUS_CLEAR_1, 1);
swrm_cmd_fifo_wr_cmd(swrm, 0xFF, i, 0x0,
SWRS_SCP_INT_STATUS_CLEAR_1);
swrm_cmd_fifo_wr_cmd(swrm, 0x4, i, 0x0,
@@ -1894,10 +2069,7 @@ handle_irq:
* as hw will mask host_irq at slave
* but will not unmask it afterwards.
*/
swrm_cmd_fifo_wr_cmd(swrm, 0xFF, devnum, 0x0,
SWRS_SCP_INT_STATUS_CLEAR_1);
swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0,
SWRS_SCP_INT_STATUS_MASK_1);
swrm->enable_slave_irq = true;
}
break;
case SWR_ATTACHED_OK:
@@ -1905,11 +2077,7 @@ handle_irq:
"%s: device %d got attached\n",
__func__, devnum);
/* enable host irq from slave device*/
swrm_cmd_fifo_wr_cmd(swrm, 0xFF, devnum, 0x0,
SWRS_SCP_INT_STATUS_CLEAR_1);
swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0,
SWRS_SCP_INT_STATUS_MASK_1);
swrm->enable_slave_irq = true;
break;
case SWR_ALERT:
dev_dbg(swrm->dev,
@@ -1931,19 +2099,19 @@ handle_irq:
case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW:
value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
dev_err(swrm->dev,
"%s: SWR read FIFO overflow fifo status\n",
"%s: SWR read FIFO overflow fifo status %x\n",
__func__, value);
break;
case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW:
value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
dev_err(swrm->dev,
"%s: SWR read FIFO underflow fifo status\n",
"%s: SWR read FIFO underflow fifo status %x\n",
__func__, value);
break;
case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW:
value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
dev_err(swrm->dev,
"%s: SWR write FIFO overflow fifo status\n",
"%s: SWR write FIFO overflow fifo status %x\n",
__func__, value);
swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
break;
@@ -2023,6 +2191,12 @@ handle_irq:
swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, intr_sts);
swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x0);
if (swrm->enable_slave_irq) {
/* Enable slave irq here */
swrm_enable_slave_irq(swrm);
swrm->enable_slave_irq = false;
}
intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS);
intr_sts_masked = intr_sts & swrm->intr_mask;
@@ -2058,7 +2232,7 @@ static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev)
trace_printk("%s enter\n", __func__);
mutex_lock(&swrm->devlock);
if (!swrm->dev_up) {
if (swrm->state == SWR_MSTR_SSR || !swrm->dev_up) {
if (swrm->wake_irq > 0) {
if (unlikely(!irq_get_irq_data(swrm->wake_irq))) {
pr_err("%s: irq data is NULL\n", __func__);
@@ -2191,6 +2365,7 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id,
"%s: devnum %d assigned for dev %llx\n",
__func__, i,
swr_dev->addr);
swrm->logical_dev[i] = swr_dev->addr;
}
}
}
@@ -2694,6 +2869,11 @@ static int swrm_probe(struct platform_device *pdev)
if (pdev->dev.of_node)
of_register_swr_devices(&swrm->master);
swrm->rd_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS)
& SWRM_COMP_PARAMS_RD_FIFO_DEPTH) >> 15);
swrm->wr_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS)
& SWRM_COMP_PARAMS_WR_FIFO_DEPTH) >> 10);
#ifdef CONFIG_DEBUG_FS
swrm->debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0);
if (!IS_ERR(swrm->debugfs_swrm_dent)) {
@@ -2737,9 +2917,10 @@ err_mstr_fail:
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
swrm, SWR_IRQ_FREE);
} else if (swrm->irq) {
irqd_set_trigger_type(
irq_get_irq_data(swrm->irq),
IRQ_TYPE_NONE);
if (irq_get_irq_data(swrm->irq) != NULL)
irqd_set_trigger_type(
irq_get_irq_data(swrm->irq),
IRQ_TYPE_NONE);
if (swrm->swr_irq_wakeup_capable)
irq_set_irq_wake(swrm->irq, 0);
free_irq(swrm->irq, swrm);
@@ -2767,9 +2948,10 @@ static int swrm_remove(struct platform_device *pdev)
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
swrm, SWR_IRQ_FREE);
} else if (swrm->irq) {
irqd_set_trigger_type(
irq_get_irq_data(swrm->irq),
IRQ_TYPE_NONE);
if (irq_get_irq_data(swrm->irq) != NULL)
irqd_set_trigger_type(
irq_get_irq_data(swrm->irq),
IRQ_TYPE_NONE);
if (swrm->swr_irq_wakeup_capable)
irq_set_irq_wake(swrm->irq, 0);
free_irq(swrm->irq, swrm);

View File

@@ -190,6 +190,10 @@ struct swr_mstr_ctrl {
int aud_core_clk_en;
int clk_src;
u32 disable_div2_clk_switch;
u32 rd_fifo_depth;
u32 wr_fifo_depth;
bool enable_slave_irq;
u64 logical_dev[SWRM_NUM_AUTO_ENUM_SLAVES];
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_swrm_dent;
struct dentry *debugfs_peek;

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015, 2018-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2015, 2018-2020 The Linux Foundation. All rights reserved.
*/
#ifndef _SWRM_REGISTERS_H
@@ -108,4 +108,7 @@
#define SWRM_INTERRUPT_STATUS_EXT_CLK_STOP_WAKEUP 0x10000
#define SWRM_INTERRUPT_MAX 0x11
#define SWRM_COMP_PARAMS_WR_FIFO_DEPTH 0x00007C00
#define SWRM_COMP_PARAMS_RD_FIFO_DEPTH 0x000F8000
#endif /* _SWRM_REGISTERS_H */

113
soc/swr-slave-port-config.h Normal file
View File

@@ -0,0 +1,113 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _SWR_SLAVE_PORT_CONFIG
#define _SWR_SLAVE_PORT_CONFIG
#include <soc/swr-common.h>
#define WSA_MSTR_PORT_MASK 0xFF
/*
* Add port configuration in the format
*{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl, dir,
* stream_type}
*/
/* DUMMY */
static struct port_params tx_dummy[SWR_MSTR_PORT_LEN] = {
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
/* AMIC 9.6 MHz clock */
static struct port_params tx_wcd_9p6MHz[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
{7, 5, 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}, /* TX4 */
};
/* AMIC 4.8 MHz clock */
static struct port_params tx_wcd_4p8MHz[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */
};
/* 4 Channel configuration */
/* SWR DMIC0 */
static struct port_params tx_bottom_mic_9p6MHz[SWR_MSTR_PORT_LEN] = {
{7, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{7, 6, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
};
/* SWR DMIC1 */
static struct port_params tx_receiver_mic_9p6MHz[SWR_MSTR_PORT_LEN] = {
{7, 4, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{7, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
};
/* SWR DMIC2 */
static struct port_params tx_back_mic_9p6MHz[SWR_MSTR_PORT_LEN] = {
{7, 3, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
};
/* SWR DMIC3 */
static struct port_params tx_top_mic_9p6MHz[SWR_MSTR_PORT_LEN] = {
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{7, 5, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
};
/* 3 Channel configuration */
/* SWR DMIC0 */
static struct port_params tx_bottom_mic_4p8MHz[SWR_MSTR_PORT_LEN] = {
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 3, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
};
/* SWR DMIC1 */
static struct port_params tx_receiver_mic_4p8MHz[SWR_MSTR_PORT_LEN] = {
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
};
/* SWR DMIC2 */
static struct port_params tx_back_mic_4p8MHz[SWR_MSTR_PORT_LEN] = {
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
};
/* SWR DMIC3 */
static struct port_params tx_top_mic_4p8MHz[SWR_MSTR_PORT_LEN] = {
{3, 3, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
};
struct swr_dev_frame_config {
struct port_params *pp;
};
static struct swr_dev_frame_config swrdev_frame_params_9p6MHz[] = {
{tx_dummy},
{tx_wcd_9p6MHz},
{tx_top_mic_9p6MHz},
{tx_back_mic_9p6MHz},
{tx_receiver_mic_9p6MHz},
{tx_bottom_mic_9p6MHz},
};
static struct swr_dev_frame_config swrdev_frame_params_4p8MHz[] = {
{tx_dummy},
{tx_wcd_4p8MHz},
{tx_top_mic_4p8MHz},
{tx_back_mic_4p8MHz},
{tx_receiver_mic_4p8MHz},
{tx_bottom_mic_4p8MHz},
};
#endif /* _LAHAINA_PORT_CONFIG */

View File

@@ -232,6 +232,8 @@
SWRS_DP_REG_OFFSET(n, m))
#define SWRS_DP_SAMPLE_CONTROL_1_BANK(n, m) (SWRS_BASE_ADDRESS + 0x122 + \
SWRS_DP_REG_OFFSET(n, m))
#define SWRS_DP_SAMPLE_CONTROL_2_BANK(n, m) (SWRS_BASE_ADDRESS + 0x123 + \
SWRS_DP_REG_OFFSET(n, m))
#define SWRS_DP_OFFSET_CONTROL_1_BANK(n, m) (SWRS_BASE_ADDRESS + 0x124 + \
SWRS_DP_REG_OFFSET(n, m))
#define SWRS_DP_OFFSET_CONTROL_2_BANK(n, m) (SWRS_BASE_ADDRESS + 0x125 + \