Merge 4baeac42b1 on remote branch

Change-Id: Ie62d6d9d8a9d387f0491e8fd2a615f047878b959
This commit is contained in:
Linux Build Service Account 2022-05-09 06:46:52 -07:00
commit 5396bb7623
22 changed files with 604 additions and 573 deletions

View file

@ -15,6 +15,9 @@ endif
ifeq ($(TARGET_SUPPORT), qrbx210)
KBUILD_OPTIONS += CONFIG_ARCH_BENGAL=y
endif
ifeq ($(TARGET_SUPPORT), qrb5165)
KBUILD_OPTIONS += CONFIG_ARCH_KONA=y
endif
subdir-ccflags-y += -I$(AUDIO_ROOT)/include/uapi/
@ -39,12 +42,18 @@ obj-m += asoc/codecs/bolero/
obj-m += asoc/codecs/wcd937x/
KBUILD_CFLAGS += -Wno-error
endif
ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), qrb5165))
obj-m += asoc/codecs/bolero/
obj-m += asoc/codecs/wcd938x/
bj-m += asoc/codecs/wsa883x/
KBUILD_CFLAGS += -Wno-error
endif
ifeq ($(TARGET_SUPPORT), sdmsteppe)
obj-m += asoc/codecs/bolero/
obj-m += asoc/codecs/wcd937x/
endif
ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa6155 sa8195 qtiquingvm qtiquingvm8295 sa8295 qtigvmi3))
ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa6155 sa8195 qtiquingvm qtiquingvm8295 sa8295))
KBUILD_OPTIONS += CONFIG_SND_SOC_AUTO=y
obj-m := ipc/
obj-m += dsp/
@ -57,14 +66,22 @@ endif
ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa6155))
KBUILD_OPTIONS += CONFIG_SND_SOC_SA6155=m
endif
ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), qtiquingvm qtigvmi3))
ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), qtiquingvm))
KBUILD_OPTIONS += CONFIG_SND_SOC_GVM=m
endif
ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), qtiquingvm8295))
KBUILD_OPTIONS += CONFIG_SND_SOC_GVM_SA8295=m
endif
endif
ifeq ($(AR_SUPPORT), $(filter $(AR_SUPPORT), yes))
obj-m := ipc/
obj-m += dsp/
obj-m += asoc/
obj-m += asoc/codecs/
obj-m += soc/
KBUILD_OPTIONS += CONFIG_SND_SOC_AUTO=y
KBUILD_OPTIONS += CONFIG_SND_SOC_AR=m
endif
all:
$(shell rm -fr $(shell pwd)/soc/core.h)
$(shell ln -s $(KERNEL_SRC)/drivers/pinctrl/core.h $(shell pwd)/soc/core.h)

5
asoc/Kbuild Normal file → Executable file
View file

@ -29,6 +29,11 @@ ifeq ($(CONFIG_SND_SOC_AUTO), y)
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h
endif
ifdef CONFIG_SND_SOC_AR
include $(AUDIO_ROOT)/config/arauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/arautoconf.h
endif
ifdef CONFIG_SND_SOC_GVM_SA8295
include $(AUDIO_ROOT)/config/sa8295gvmauto.conf
export

View file

@ -29,6 +29,11 @@ ifeq ($(CONFIG_SND_SOC_AUTO), y)
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h
endif
ifdef CONFIG_SND_SOC_AR
include $(AUDIO_ROOT)/config/arauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/arautoconf.h
endif
ifdef CONFIG_SND_SOC_GVM_SA8295
include $(AUDIO_ROOT)/config/sa8295gvmauto.conf
export

View file

@ -505,7 +505,8 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMU:
if ((snd_soc_component_read32(component,
WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) &&
hph_mode == CLS_H_ULP)
((snd_soc_component_read32(component,
WCD937X_ANA_HPH) & 0x0C) == 0x0C))
snd_soc_component_update_bits(component,
WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x90);
if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI)
@ -551,7 +552,8 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMD:
if ((snd_soc_component_read32(component,
WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) &&
hph_mode == CLS_H_ULP)
((snd_soc_component_read32(component,
WCD937X_ANA_HPH) & 0x0C) == 0x0C))
snd_soc_component_update_bits(component,
WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x80);
snd_soc_component_update_bits(component,
@ -589,7 +591,8 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMU:
if ((snd_soc_component_read32(component,
WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) &&
hph_mode == CLS_H_ULP)
((snd_soc_component_read32(component,
WCD937X_ANA_HPH) & 0x0C) == 0x0C))
snd_soc_component_update_bits(component,
WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x90);
if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI)
@ -635,7 +638,8 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMD:
if ((snd_soc_component_read32(component,
WCD937X_DIGITAL_EFUSE_REG_16) == 0x02) &&
hph_mode == CLS_H_ULP)
((snd_soc_component_read32(component,
WCD937X_ANA_HPH) & 0x0C) == 0x0C))
snd_soc_component_update_bits(component,
WCD937X_RX_BIAS_HPH_LOWPOWER, 0xF0, 0x80);
snd_soc_component_update_bits(component,

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _WCD938X_INTERNAL_H
@ -110,6 +111,7 @@ struct wcd938x_priv {
/* wcd to swr dmic notification */
bool notify_swr_dmic;
struct blocking_notifier_head notifier;
int micb_enabled[WCD938X_MAX_MICBIAS];
};
struct wcd938x_micbias_setting {

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@ -2919,6 +2920,95 @@ static int wcd938x_bcs_put(struct snd_kcontrol *kcontrol,
return 0;
}
/*
* wcd938x_codec_enable_standalone_micbias - enable micbias standalone
* @component: pointer to component instance
* @micb_num: number of micbias to be enabled
* @enable: true to enable micbias or false to disable
*
* This function is used to enable micbias (1, 2, 3 or 4) during
* standalone independent of whether TX use-case is running or not
*
* Return: error code in case of failure or 0 for success
*/
int wcd938x_codec_enable_standalone_micbias(struct snd_soc_component *component,
int micb_num,
bool enable)
{
const char * const micb_names[] = {
DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE,
DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE
};
int micb_index = micb_num - 1;
int rc;
struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(component);
if ((micb_index < 0) || (micb_index > WCD938X_MAX_MICBIAS - 1)) {
dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n",
__func__, micb_index);
return -EINVAL;
}
if (enable)
rc = snd_soc_dapm_force_enable_pin(
dapm,
micb_names[micb_index]);
else
rc = snd_soc_dapm_disable_pin(
dapm,
micb_names[micb_index]);
if (!rc)
snd_soc_dapm_sync(dapm);
else
dev_err(component->dev, "%s: micbias%d force %s pin failed\n",
__func__, micb_num, (enable ? "enable" : "disable"));
return rc;
}
EXPORT_SYMBOL(wcd938x_codec_enable_standalone_micbias);
static int wcd938x_get_micbias(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
int micb_num = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->shift;
ucontrol->value.integer.value[0] = wcd938x->micb_enabled[micb_num - 1];
return 0;
}
static int wcd938x_set_micbias(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
int micb_num = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->shift;
int value = ucontrol->value.integer.value[0];
bool enable;
int ret;
if ((micb_num != MIC_BIAS_1) && (micb_num != MIC_BIAS_2) &&
(micb_num != MIC_BIAS_3) && (micb_num != MIC_BIAS_4))
return -EINVAL;
enable = !!value;
ret = wcd938x_codec_enable_standalone_micbias(component, micb_num,
enable);
if (ret) {
dev_err(component->dev, "%s: Failed to enable standalone micb:%d\n",
__func__, micb_num);
return ret;
}
wcd938x->micb_enabled[micb_num - 1] = enable;
return ret;
}
static const char * const tx_mode_mux_text_wcd9380[] = {
"ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
};
@ -3045,6 +3135,14 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("DMIC7 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_SINGLE_EXT("MIC BIAS1 Standalone", SND_SOC_NOPM, MIC_BIAS_1, 1, 0,
wcd938x_get_micbias, wcd938x_set_micbias),
SOC_SINGLE_EXT("MIC BIAS2 Standalone", SND_SOC_NOPM, MIC_BIAS_2, 1, 0,
wcd938x_get_micbias, wcd938x_set_micbias),
SOC_SINGLE_EXT("MIC BIAS3 Standalone", SND_SOC_NOPM, MIC_BIAS_3, 1, 0,
wcd938x_get_micbias, wcd938x_set_micbias),
SOC_SINGLE_EXT("MIC BIAS4 Standalone", SND_SOC_NOPM, MIC_BIAS_4, 1, 0,
wcd938x_get_micbias, wcd938x_set_micbias),
};
static const struct snd_kcontrol_new adc1_switch[] = {

View file

@ -274,7 +274,8 @@ static int wsa881x_i2c_read_device(struct wsa881x_pdata *wsa881x,
}
pr_debug("read success reg = %x val = %x\n",
reg, val);
} else {
} else if (wsa881x->client[wsa881x_index]) {
reg_addr = (u8)reg;
msg = &wsa881x->xfer_msg[0];
msg->addr = wsa881x->client[wsa881x_index]->addr;
@ -302,6 +303,9 @@ static int wsa881x_i2c_read_device(struct wsa881x_pdata *wsa881x,
}
}
val = dest[0];
} else {
pr_err("failed for i2c client is not initilized\n");
return -EINVAL;
}
return val;
}
@ -1202,15 +1206,16 @@ static int wsa881x_probe(struct snd_soc_component *component)
wsa881x_temp_reg_read;
snd_soc_component_set_drvdata(component, &wsa_pdata[wsa881x_index]);
while (retry) {
if (wsa_pdata[wsa881x_index].regmap[WSA881X_ANALOG_SLAVE]
!= NULL)
if (wsa_pdata[wsa881x_index].regmap_flag)
break;
msleep(100);
retry--;
}
if (!retry)
if (!retry) {
dev_err(&client->dev, "%s: max retry expired and regmap of\n"
"analog slave not initilized\n", __func__);
return -EPROBE_DEFER;
}
wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata);
INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work,
wsa881x_ocp_ctl_work);

View file

@ -198,6 +198,8 @@ struct msm_asoc_mach_data {
struct clk *lpass_audio_hw_vote;
int core_audio_vote_count;
u32 tdm_max_slots; /* Max TDM slots used */
int wcd_disabled;
u32 wsa_max_devs;
};
struct tdm_port {
@ -905,6 +907,9 @@ static int dmic_4_5_gpio_cnt;
static void *def_wcd_mbhc_cal(void);
static int msm_rx_tx_codec_init(struct snd_soc_pcm_runtime*);
static int msm_int_wsa_init(struct snd_soc_pcm_runtime*);
/*
* Need to report LINEIN
* if R/L channel impedance is larger than 5K ohm
@ -932,6 +937,68 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = {
.moisture_duty_cycle_en = true,
};
/* set audio task affinity to core 1 & 2 */
static const unsigned int audio_core_list[] = {1, 2};
static cpumask_t audio_cpu_map = CPU_MASK_NONE;
static struct dev_pm_qos_request *msm_audio_req;
static unsigned int qos_client_active_cnt;
static void msm_audio_add_qos_request(void)
{
int i;
int cpu = 0;
msm_audio_req = kcalloc(num_possible_cpus(),
sizeof(struct dev_pm_qos_request), GFP_KERNEL);
if (!msm_audio_req)
return;
for (i = 0; i < ARRAY_SIZE(audio_core_list); i++) {
if (audio_core_list[i] >= num_possible_cpus())
pr_err("%s incorrect cpu id: %d specified.\n",
__func__, audio_core_list[i]);
else
cpumask_set_cpu(audio_core_list[i], &audio_cpu_map);
}
for_each_cpu(cpu, &audio_cpu_map) {
dev_pm_qos_add_request(get_cpu_device(cpu),
&msm_audio_req[cpu],
DEV_PM_QOS_RESUME_LATENCY,
PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE);
pr_debug("%s set cpu affinity to core %d.\n", __func__, cpu);
}
}
static void msm_audio_remove_qos_request(void)
{
int cpu = 0;
if (msm_audio_req) {
for_each_cpu(cpu, &audio_cpu_map) {
dev_pm_qos_remove_request(
&msm_audio_req[cpu]);
pr_debug("%s remove cpu affinity of core %d.\n",
__func__, cpu);
}
kfree(msm_audio_req);
}
}
static void msm_audio_update_qos_request(u32 latency)
{
int cpu = 0;
if (msm_audio_req) {
for_each_cpu(cpu, &audio_cpu_map) {
dev_pm_qos_update_request(
&msm_audio_req[cpu], latency);
pr_debug("%s update latency of core %d to %ul.\n",
__func__, cpu, latency);
}
}
}
static inline int param_is_mask(int p)
{
return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
@ -4990,24 +5057,26 @@ err:
static int msm_fe_qos_prepare(struct snd_pcm_substream *substream)
{
cpumask_t mask;
if (pm_qos_request_active(&substream->latency_pm_qos_req))
pm_qos_remove_request(&substream->latency_pm_qos_req);
cpumask_clear(&mask);
cpumask_set_cpu(1, &mask); /* affine to core 1 */
cpumask_set_cpu(2, &mask); /* affine to core 2 */
cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask);
qos_client_active_cnt++;
if (qos_client_active_cnt == 1)
msm_audio_update_qos_request(MSM_LL_QOS_VALUE);
substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES;
pm_qos_add_request(&substream->latency_pm_qos_req,
PM_QOS_CPU_DMA_LATENCY,
MSM_LL_QOS_VALUE);
return 0;
}
static void msm_fe_qos_shutdown(struct snd_pcm_substream *substream)
{
(void)substream;
if (qos_client_active_cnt > 0)
qos_client_active_cnt--;
if (qos_client_active_cnt == 0)
msm_audio_update_qos_request(PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE);
}
void mi2s_disable_audio_vote(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@ -5275,6 +5344,7 @@ static struct snd_soc_ops msm_mi2s_be_ops = {
static struct snd_soc_ops msm_fe_qos_ops = {
.prepare = msm_fe_qos_prepare,
.shutdown = msm_fe_qos_shutdown,
};
static struct snd_soc_ops msm_cdc_dma_be_ops = {
@ -5466,17 +5536,86 @@ static void msm_add_auxpcm_snd_controls(struct snd_soc_component *component)
}
#endif
static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
static int msm_int_wsa_init(struct snd_soc_pcm_runtime *rtd)
{
u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {0, 1, 2, 3};
u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {0, 1, 2, 3};
u8 spkleft_port_types[WSA881X_MAX_SWR_PORTS] = {SPKR_L, SPKR_L_COMP,
SPKR_L_BOOST, SPKR_L_VI};
u8 spkright_port_types[WSA881X_MAX_SWR_PORTS] = {SPKR_R, SPKR_R_COMP,
SPKR_R_BOOST, SPKR_R_VI};
unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200};
unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3};
struct snd_soc_component *component = NULL;
struct snd_soc_dapm_context *dapm = NULL;
struct msm_asoc_mach_data *pdata =
snd_soc_card_get_drvdata(rtd->card);
int wsa_active_devs = 0;
if (pdata->wsa_max_devs > 0) {
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.1");
if (component) {
dapm = snd_soc_component_get_dapm(component);
wsa881x_set_channel_map(component, &spkleft_ports[0],
WSA883X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0], &spkleft_port_types[0]);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
}
/*
* Send speaker configuration only for WSA8810.
* Default configuration is for WSA8815.
*/
wsa_macro_set_spkr_mode(component,WSA_MACRO_SPKR_MODE_1);
wsa_macro_set_spkr_gain_offset(component,WSA_MACRO_GAIN_OFFSET_M1P5_DB);
wsa881x_codec_info_create_codec_entry(pdata->codec_root,
component);
wsa_active_devs++;
} else {
pr_info("%s: wsa-codec.1 component is NULL\n", __func__);
}
}
/* If current platform has more than one WSA */
if (pdata->wsa_max_devs > wsa_active_devs) {
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.2");
if (!component) {
pr_err("%s: wsa-codec.2 component is NULL\n", __func__);
pr_err("%s: %d WSA is found. Expect %d WSA.",
__func__, wsa_active_devs, pdata->wsa_max_devs);
return -EINVAL;
}
dapm = snd_soc_component_get_dapm(component);
wsa881x_set_channel_map(component, &spkright_ports[0],
WSA883X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0], &spkright_port_types[0]);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");
}
wsa881x_codec_info_create_codec_entry(pdata->codec_root,
component);
}
return 0;
}
static int msm_rx_tx_codec_init(struct snd_soc_pcm_runtime *rtd)
{
int ret = -EINVAL;
struct snd_soc_component *component;
struct snd_soc_dapm_context *dapm;
struct snd_card *card;
struct snd_soc_component *component = NULL;
struct snd_soc_component *bolero_component = NULL;
struct snd_soc_dapm_context *dapm = NULL;
struct snd_card *card = NULL;
struct snd_info_entry *entry;
struct snd_soc_component *aux_comp;
struct platform_device *pdev = NULL;
int i = 0;
bool is_wcd937x_used = false;
int codec_variant = -1;
char *data = NULL;
struct msm_asoc_mach_data *pdata =
snd_soc_card_get_drvdata(rtd->card);
@ -5486,6 +5625,8 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
pr_err("%s: could not find component for bolero_codec\n",
__func__);
return ret;
} else {
bolero_component = component;
}
dapm = snd_soc_component_get_dapm(component);
@ -5534,87 +5675,104 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_sync(dapm);
/*
* Send speaker configuration only for WSA8810.
* Default configuration is for WSA8815.
*/
dev_dbg(component->dev, "%s: Number of aux devices: %d\n",
__func__, rtd->card->num_aux_devs);
if (rtd->card->num_aux_devs &&
!list_empty(&rtd->card->component_dev_list)) {
list_for_each_entry(aux_comp,
&rtd->card->aux_comp_list,
card_aux_list) {
if (aux_comp->name != NULL && (
!strcmp(aux_comp->name, WSA8810_NAME_1) ||
!strcmp(aux_comp->name, WSA8810_NAME_2))) {
wsa_macro_set_spkr_mode(component,
WSA_MACRO_SPKR_MODE_1);
wsa_macro_set_spkr_gain_offset(component,
WSA_MACRO_GAIN_OFFSET_M1P5_DB);
} else if (aux_comp->name != NULL && (
!strcmp(aux_comp->name, WSA8815_NAME_1) ||
!strcmp(aux_comp->name, WSA8815_NAME_2))) {
wsa_macro_set_spkr_mode(component,
WSA_MACRO_SPKR_MODE_DEFAULT);
}
}
}
for (i = 0; i < rtd->card->num_aux_devs; i++)
{
if (msm_aux_dev[i].name != NULL ) {
if (strstr(msm_aux_dev[i].name, "wsa"))
continue;
}
if (msm_aux_dev[i].codec_of_node) {
pdev = of_find_device_by_node(
msm_aux_dev[i].codec_of_node);
if (pdev)
data = (char*) of_device_get_match_data(
&pdev->dev);
if (data != NULL) {
if (!strncmp(data, "wcd937x",
sizeof("wcd937x"))) {
is_wcd937x_used = true;
break;
}
}
}
}
if (is_wcd937x_used) {
bolero_set_port_map(component,
ARRAY_SIZE(sm_port_map_wcd937x),
sm_port_map_wcd937x);
} else if (pdata->lito_v2_enabled) {
/*
* Enable tx data line3 for saipan version v2 and
* write corresponding lpi register.
*/
bolero_set_port_map(component, ARRAY_SIZE(sm_port_map_v2),
sm_port_map_v2);
} else {
bolero_set_port_map(component, ARRAY_SIZE(sm_port_map),
sm_port_map);
}
card = rtd->card->snd_card;
if (!pdata->codec_root) {
entry = msm_snd_info_create_subdir(card->module, "codecs",
card->proc_root);
if (!entry) {
pr_debug("%s: Cannot create codecs module entry\n",
__func__);
ret = 0;
goto err;
return 0;
}
pdata->codec_root = entry;
}
bolero_info_create_codec_entry(pdata->codec_root, component);
bolero_register_wake_irq(component, false);
/*
* Send speaker configuration only for WSA8810.
* Default configuration is for WSA8815.
*/
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.1");
if (!component) {
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.3");
if (!component) {
pr_debug("%s: wsa-codec.3 component is NULL\n",
__func__);
} else {
wsa_macro_set_spkr_mode(bolero_component,WSA_MACRO_SPKR_MODE_DEFAULT);
}
} else {
wsa_macro_set_spkr_mode(bolero_component,WSA_MACRO_SPKR_MODE_1);
wsa_macro_set_spkr_gain_offset(bolero_component,WSA_MACRO_GAIN_OFFSET_M1P5_DB);
}
if (pdata->wcd_disabled) {
codec_reg_done = true;
return 0;
}
component = snd_soc_rtdcom_lookup(rtd, WCD938X_DRV_NAME);
if (!component) {
component = snd_soc_rtdcom_lookup(rtd, WCD937X_DRV_NAME);
if (!component) {
pr_err("%s component is NULL\n", __func__);
return -EINVAL;
}
}
dapm = snd_soc_component_get_dapm(component);
card = component->card->snd_card;
snd_soc_dapm_ignore_suspend(dapm, "EAR");
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, "AMIC1");
snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
snd_soc_dapm_sync(dapm);
if (!strncmp(component->driver->name, "wcd937x", 7)) {
wcd937x_info_create_codec_entry(pdata->codec_root, component);
ret = snd_soc_add_component_controls(component,
msm_int_wcd937x_snd_controls,
ARRAY_SIZE(msm_int_wcd937x_snd_controls));
bolero_set_port_map(bolero_component,
ARRAY_SIZE(sm_port_map_wcd937x),
sm_port_map_wcd937x);
} else {
wcd938x_info_create_codec_entry(pdata->codec_root, component);
codec_variant = wcd938x_get_codec_variant(component);
dev_dbg(component->dev, "%s: variant %d\n", __func__, codec_variant);
if (codec_variant == WCD9380)
ret = snd_soc_add_component_controls(bolero_component,
msm_int_wcd9380_snd_controls,
ARRAY_SIZE(msm_int_wcd9380_snd_controls));
else if (codec_variant == WCD9385)
ret = snd_soc_add_component_controls(bolero_component,
msm_int_wcd9385_snd_controls,
ARRAY_SIZE(msm_int_wcd9385_snd_controls));
if (pdata->lito_v2_enabled) {
/*
* Enable tx data line3 for saipan version v2 and
* write corresponding lpi register.
*/
bolero_set_port_map(component, ARRAY_SIZE(sm_port_map_v2),
sm_port_map_v2);
} else {
bolero_set_port_map(component, ARRAY_SIZE(sm_port_map),
sm_port_map);
}
}
if (ret < 0) {
dev_err(component->dev, "%s: add codec specific snd controls failed: %d\n",
__func__, ret);
return ret;
}
codec_reg_done = true;
return 0;
err:
@ -6811,7 +6969,7 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = {
.stream_name = "WSA CDC DMA0 Playback",
.no_pcm = 1,
.dpcm_playback = 1,
.init = &msm_int_audrx_init,
.init = &msm_int_wsa_init,
.id = MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0,
.be_hw_params_fixup = msm_be_hw_params_fixup,
.ignore_pmdown_time = 1,
@ -6869,6 +7027,7 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = {
.ignore_suspend = 1,
.ops = &msm_cdc_dma_be_ops,
SND_SOC_DAILINK_REG(rx_dma_rx0),
.init = &msm_rx_tx_codec_init,
},
{
.name = LPASS_BE_RX_CDC_DMA_RX_1,
@ -7181,6 +7340,62 @@ static const struct of_device_id kona_asoc_machine_of_match[] = {
{},
};
static int msm_snd_card_late_probe(struct snd_soc_card *card)
{
struct snd_soc_component *component = NULL;
const char *be_dl_name = LPASS_BE_RX_CDC_DMA_RX_0;
struct snd_soc_pcm_runtime *rtd;
struct msm_asoc_mach_data *pdata;
int ret = 0;
void *mbhc_calibration;
bool is_wcd937x = false;
pdata = snd_soc_card_get_drvdata(card);
if (!pdata)
return -EINVAL;
if (pdata->wcd_disabled)
return 0;
rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
if (!rtd) {
dev_err(card->dev,
"%s: snd_soc_get_pcm_runtime for %s failed!\n",
__func__, be_dl_name);
return -EINVAL;
}
component = snd_soc_rtdcom_lookup(rtd, WCD938X_DRV_NAME);
if (!component) {
component = snd_soc_rtdcom_lookup(rtd, WCD937X_DRV_NAME);
if (!component) {
pr_err("%s component is NULL\n", __func__);
return -EINVAL;
} else {
is_wcd937x = true;
}
}
mbhc_calibration = def_wcd_mbhc_cal();
if (!mbhc_calibration)
return -ENOMEM;
wcd_mbhc_cfg.calibration = mbhc_calibration;
if (!is_wcd937x)
ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
else
ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
if (ret) {
dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n",
__func__, ret);
goto err_hs_detect;
}
return 0;
err_hs_detect:
kfree(mbhc_calibration);
return ret;
}
static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
{
struct snd_soc_card *card = NULL;
@ -7350,470 +7565,12 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
if (card) {
card->dai_link = dailink;
card->num_links = total_links;
card->late_probe = msm_snd_card_late_probe;
}
return card;
}
static int msm_wsa881x_init(struct snd_soc_component *component)
{
u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {0, 1, 2, 3};
u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {0, 1, 2, 3};
u8 spkleft_port_types[WSA881X_MAX_SWR_PORTS] = {SPKR_L, SPKR_L_COMP,
SPKR_L_BOOST, SPKR_L_VI};
u8 spkright_port_types[WSA881X_MAX_SWR_PORTS] = {SPKR_R, SPKR_R_COMP,
SPKR_R_BOOST, SPKR_R_VI};
unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200};
unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3};
struct msm_asoc_mach_data *pdata;
struct snd_soc_dapm_context *dapm;
struct snd_card *card;
struct snd_info_entry *entry;
int ret = 0;
if (!component) {
pr_err("%s component is NULL\n", __func__);
return -EINVAL;
}
card = component->card->snd_card;
dapm = snd_soc_component_get_dapm(component);
if (!strcmp(component->name_prefix, "SpkrLeft")) {
dev_dbg(component->dev, "%s: setting left ch map to codec %s\n",
__func__, component->name);
if (strnstr(component->name, "wsa883x", sizeof(component->name)))
wsa883x_set_channel_map(component, &spkleft_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0], &spkleft_port_types[0]);
else
wsa881x_set_channel_map(component, &spkleft_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0], &spkleft_port_types[0]);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
}
} else if (!strcmp(component->name_prefix, "SpkrRight")) {
dev_dbg(component->dev, "%s: setting right ch map to codec %s\n",
__func__, component->name);
if (strnstr(component->name, "wsa883x", sizeof(component->name)))
wsa883x_set_channel_map(component, &spkright_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0], &spkright_port_types[0]);
else
wsa881x_set_channel_map(component, &spkright_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0], &spkright_port_types[0]);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");
}
} else {
dev_err(component->dev, "%s: wrong codec name %s\n", __func__,
component->name);
ret = -EINVAL;
goto err;
}
pdata = snd_soc_card_get_drvdata(component->card);
if (!pdata->codec_root) {
entry = msm_snd_info_create_subdir(card->module, "codecs",
card->proc_root);
if (!entry) {
pr_err("%s: Cannot create codecs module entry\n",
__func__);
ret = 0;
goto err;
}
pdata->codec_root = entry;
}
if (strnstr(component->name, "wsa883x", sizeof(component->name)))
wsa883x_codec_info_create_codec_entry(pdata->codec_root,
component);
else
wsa881x_codec_info_create_codec_entry(pdata->codec_root,
component);
err:
return ret;
}
static int msm_aux_codec_init(struct snd_soc_component *component)
{
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
int ret = 0;
int codec_variant = -1;
void *mbhc_calibration;
struct snd_info_entry *entry;
struct snd_card *card = component->card->snd_card;
struct msm_asoc_mach_data *pdata;
snd_soc_dapm_ignore_suspend(dapm, "EAR");
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, "AMIC1");
snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
snd_soc_dapm_sync(dapm);
pdata = snd_soc_card_get_drvdata(component->card);
if (!pdata->codec_root) {
entry = msm_snd_info_create_subdir(card->module, "codecs",
card->proc_root);
if (!entry) {
dev_dbg(component->dev, "%s: Cannot create codecs module entry\n",
__func__);
ret = 0;
goto mbhc_cfg_cal;
}
pdata->codec_root = entry;
}
if (!strncmp(component->driver->name, "wcd937x", 7)) {
wcd937x_info_create_codec_entry(pdata->codec_root, component);
ret = snd_soc_add_component_controls(component,
msm_int_wcd937x_snd_controls,
ARRAY_SIZE(msm_int_wcd937x_snd_controls));
} else {
wcd938x_info_create_codec_entry(pdata->codec_root, component);
codec_variant = wcd938x_get_codec_variant(component);
dev_dbg(component->dev, "%s: variant %d\n", __func__, codec_variant);
if (codec_variant == WCD9380)
ret = snd_soc_add_component_controls(component,
msm_int_wcd9380_snd_controls,
ARRAY_SIZE(msm_int_wcd9380_snd_controls));
else if (codec_variant == WCD9385)
ret = snd_soc_add_component_controls(component,
msm_int_wcd9385_snd_controls,
ARRAY_SIZE(msm_int_wcd9385_snd_controls));
}
if (ret < 0) {
dev_err(component->dev, "%s: add codec specific snd controls failed: %d\n",
__func__, ret);
return ret;
}
mbhc_cfg_cal:
mbhc_calibration = def_wcd_mbhc_cal();
if (!mbhc_calibration)
return -ENOMEM;
wcd_mbhc_cfg.calibration = mbhc_calibration;
if (!strncmp(component->driver->name, "wcd937x", 7))
ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
else
ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
if (ret) {
dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n",
__func__, ret);
goto err_hs_detect;
}
return 0;
err_hs_detect:
kfree(mbhc_calibration);
return ret;
}
static int msm_init_aux_dev(struct platform_device *pdev,
struct snd_soc_card *card)
{
struct device_node *wsa_of_node;
struct device_node *aux_codec_of_node;
u32 wsa_max_devs;
u32 wsa_dev_cnt;
u32 codec_max_aux_devs = 0;
u32 codec_aux_dev_cnt = 0;
int i;
struct msm_wsa881x_dev_info *wsa881x_dev_info;
struct aux_codec_dev_info *aux_cdc_dev_info;
struct snd_soc_dai_link_component *dlc;
const char *auxdev_name_prefix[1];
char *dev_name_str = NULL;
int found = 0;
int codecs_found = 0;
int ret = 0;
dlc = devm_kcalloc(&pdev->dev, 1,
sizeof(struct snd_soc_dai_link_component),
GFP_KERNEL);
/* Get maximum WSA device count for this platform */
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,wsa-max-devs", &wsa_max_devs);
if (ret) {
dev_info(&pdev->dev,
"%s: wsa-max-devs property missing in DT %s, ret = %d\n",
__func__, pdev->dev.of_node->full_name, ret);
wsa_max_devs = 0;
goto codec_aux_dev;
}
if (wsa_max_devs == 0) {
dev_warn(&pdev->dev,
"%s: Max WSA devices is 0 for this target?\n",
__func__);
goto codec_aux_dev;
}
/* Get count of WSA device phandles for this platform */
wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node,
"qcom,wsa-devs", NULL);
if (wsa_dev_cnt == -ENOENT) {
dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n",
__func__);
goto err;
} else if (wsa_dev_cnt <= 0) {
dev_err(&pdev->dev,
"%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n",
__func__, wsa_dev_cnt);
ret = -EINVAL;
goto err;
}
/*
* Expect total phandles count to be NOT less than maximum possible
* WSA count. However, if it is less, then assign same value to
* max count as well.
*/
if (wsa_dev_cnt < wsa_max_devs) {
dev_dbg(&pdev->dev,
"%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n",
__func__, wsa_max_devs, wsa_dev_cnt);
wsa_max_devs = wsa_dev_cnt;
}
/* Make sure prefix string passed for each WSA device */
ret = of_property_count_strings(pdev->dev.of_node,
"qcom,wsa-aux-dev-prefix");
if (ret != wsa_dev_cnt) {
dev_err(&pdev->dev,
"%s: expecting %d wsa prefix. Defined only %d in DT\n",
__func__, wsa_dev_cnt, ret);
ret = -EINVAL;
goto err;
}
/*
* Alloc mem to store phandle and index info of WSA device, if already
* registered with ALSA core
*/
wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs,
sizeof(struct msm_wsa881x_dev_info),
GFP_KERNEL);
if (!wsa881x_dev_info) {
ret = -ENOMEM;
goto err;
}
/*
* search and check whether all WSA devices are already
* registered with ALSA core or not. If found a node, store
* the node and the index in a local array of struct for later
* use.
*/
for (i = 0; i < wsa_dev_cnt; i++) {
wsa_of_node = of_parse_phandle(pdev->dev.of_node,
"qcom,wsa-devs", i);
if (unlikely(!wsa_of_node)) {
/* we should not be here */
dev_err(&pdev->dev,
"%s: wsa dev node is not present\n",
__func__);
ret = -EINVAL;
goto err;
}
dlc->of_node = wsa_of_node;
dlc->name = NULL;
if (soc_find_component(dlc)) {
/* WSA device registered with ALSA core */
wsa881x_dev_info[found].of_node = wsa_of_node;
wsa881x_dev_info[found].index = i;
found++;
if (found == wsa_max_devs)
break;
}
}
if (found < wsa_max_devs) {
dev_dbg(&pdev->dev,
"%s: failed to find %d components. Found only %d\n",
__func__, wsa_max_devs, found);
return -EPROBE_DEFER;
}
dev_info(&pdev->dev,
"%s: found %d wsa881x devices registered with ALSA core\n",
__func__, found);
codec_aux_dev:
/* Get maximum aux codec device count for this platform */
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,codec-max-aux-devs",
&codec_max_aux_devs);
if (ret) {
dev_err(&pdev->dev,
"%s: codec-max-aux-devs property missing in DT %s, ret = %d\n",
__func__, pdev->dev.of_node->full_name, ret);
codec_max_aux_devs = 0;
goto aux_dev_register;
}
if (codec_max_aux_devs == 0) {
dev_dbg(&pdev->dev,
"%s: Max aux codec devices is 0 for this target?\n",
__func__);
goto aux_dev_register;
}
/* Get count of aux codec device phandles for this platform */
codec_aux_dev_cnt = of_count_phandle_with_args(
pdev->dev.of_node,
"qcom,codec-aux-devs", NULL);
if (codec_aux_dev_cnt == -ENOENT) {
dev_warn(&pdev->dev, "%s: No aux codec defined in DT.\n",
__func__);
goto err;
} else if (codec_aux_dev_cnt <= 0) {
dev_err(&pdev->dev,
"%s: Error reading aux codec device from DT, dev_cnt=%d\n",
__func__, codec_aux_dev_cnt);
ret = -EINVAL;
goto err;
}
/*
* Expect total phandles count to be NOT less than maximum possible
* AUX device count. However, if it is less, then assign same value to
* max count as well.
*/
if (codec_aux_dev_cnt < codec_max_aux_devs) {
dev_dbg(&pdev->dev,
"%s: codec_max_aux_devs = %d cannot exceed codec_aux_dev_cnt = %d\n",
__func__, codec_max_aux_devs,
codec_aux_dev_cnt);
codec_max_aux_devs = codec_aux_dev_cnt;
}
/*
* Alloc mem to store phandle and index info of aux codec
* if already registered with ALSA core
*/
aux_cdc_dev_info = devm_kcalloc(&pdev->dev, codec_aux_dev_cnt,
sizeof(struct aux_codec_dev_info),
GFP_KERNEL);
if (!aux_cdc_dev_info) {
ret = -ENOMEM;
goto err;
}
/*
* search and check whether all aux codecs are already
* registered with ALSA core or not. If found a node, store
* the node and the index in a local array of struct for later
* use.
*/
for (i = 0; i < codec_aux_dev_cnt; i++) {
aux_codec_of_node = of_parse_phandle(pdev->dev.of_node,
"qcom,codec-aux-devs", i);
if (unlikely(!aux_codec_of_node)) {
/* we should not be here */
dev_err(&pdev->dev,
"%s: aux codec dev node is not present\n",
__func__);
ret = -EINVAL;
goto err;
}
dlc->of_node = aux_codec_of_node;
dlc->name = NULL;
if (soc_find_component(dlc)) {
/* AUX codec registered with ALSA core */
aux_cdc_dev_info[codecs_found].of_node =
aux_codec_of_node;
aux_cdc_dev_info[codecs_found].index = i;
codecs_found++;
}
}
if (codecs_found < codec_aux_dev_cnt) {
dev_dbg(&pdev->dev,
"%s: failed to find %d components. Found only %d\n",
__func__, codec_aux_dev_cnt, codecs_found);
return -EPROBE_DEFER;
}
dev_info(&pdev->dev,
"%s: found %d AUX codecs registered with ALSA core\n",
__func__, codecs_found);
aux_dev_register:
card->num_aux_devs = wsa_max_devs + codec_aux_dev_cnt;
card->num_configs = wsa_max_devs + codec_aux_dev_cnt;
/* Alloc array of AUX devs struct */
msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs,
sizeof(struct snd_soc_aux_dev),
GFP_KERNEL);
if (!msm_aux_dev) {
ret = -ENOMEM;
goto err;
}
/* Alloc array of codec conf struct */
msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_configs,
sizeof(struct snd_soc_codec_conf),
GFP_KERNEL);
if (!msm_codec_conf) {
ret = -ENOMEM;
goto err;
}
for (i = 0; i < wsa_max_devs; i++) {
dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN,
GFP_KERNEL);
if (!dev_name_str) {
ret = -ENOMEM;
goto err;
}
ret = of_property_read_string_index(pdev->dev.of_node,
"qcom,wsa-aux-dev-prefix",
wsa881x_dev_info[i].index,
auxdev_name_prefix);
if (ret) {
dev_err(&pdev->dev,
"%s: failed to read wsa aux dev prefix, ret = %d\n",
__func__, ret);
ret = -EINVAL;
goto err;
}
snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i);
msm_aux_dev[i].dlc.name = dev_name_str;
msm_aux_dev[i].dlc.dai_name = NULL;
msm_aux_dev[i].dlc.of_node =
wsa881x_dev_info[i].of_node;
msm_aux_dev[i].init = msm_wsa881x_init;
msm_codec_conf[i].dev_name = NULL;
msm_codec_conf[i].name_prefix = auxdev_name_prefix[0];
msm_codec_conf[i].of_node =
wsa881x_dev_info[i].of_node;
}
for (i = 0; i < codec_aux_dev_cnt; i++) {
msm_aux_dev[wsa_max_devs + i].dlc.name = NULL;
msm_aux_dev[wsa_max_devs + i].dlc.dai_name = NULL;
msm_aux_dev[wsa_max_devs + i].dlc.of_node =
aux_cdc_dev_info[i].of_node;
msm_aux_dev[wsa_max_devs + i].init = msm_aux_codec_init;
msm_codec_conf[wsa_max_devs + i].dev_name = NULL;
msm_codec_conf[wsa_max_devs + i].name_prefix =
NULL;
msm_codec_conf[wsa_max_devs + i].of_node =
aux_cdc_dev_info[i].of_node;
}
card->codec_conf = msm_codec_conf;
card->aux_dev = msm_aux_dev;
err:
return ret;
}
static void msm_i2s_auxpcm_init(struct platform_device *pdev)
{
int count = 0;
@ -7954,6 +7711,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
"qcom,lito-is-v2-enabled",
&pdata->lito_v2_enabled);
of_property_read_u32(pdev->dev.of_node,
"qcom,wcd-disabled",
&pdata->wcd_disabled);
card = populate_snd_card_dailinks(&pdev->dev);
if (!card) {
dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);
@ -7985,9 +7746,15 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
goto err;
}
ret = msm_init_aux_dev(pdev, card);
if (ret)
goto err;
/* Get maximum WSA device count for this platform */
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,wsa-max-devs", &pdata->wsa_max_devs);
if (ret) {
dev_info(&pdev->dev,
"%s: wsa-max-devs property missing in DT %s, ret = %d\n",
__func__, pdev->dev.of_node->full_name, ret);
pdata->wsa_max_devs = 0;
}
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret == -EPROBE_DEFER) {
@ -8132,6 +7899,9 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
is_initial_boot = true;
/* Add QoS request for audio tasks */
msm_audio_add_qos_request();
return 0;
err:
devm_kfree(&pdev->dev, pdata);
@ -8145,6 +7915,7 @@ static int msm_asoc_machine_remove(struct platform_device *pdev)
snd_event_master_deregister(&pdev->dev);
snd_soc_unregister_card(card);
msm_i2s_auxpcm_deinit();
msm_audio_remove_qos_request();
return 0;
}

7
asoc/msm-pcm-q6-v2.c Executable file → Normal file
View file

@ -751,9 +751,11 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
else if (params_format(params) == SNDRV_PCM_FORMAT_S32_LE)
bits_per_sample = 32;
/* ULL mode is not supported in capture path */
/* ULL mode is not supported in capture path so using LLNP insted of ULL */
if (pdata->perf_mode == LEGACY_PCM_MODE)
prtd->audio_client->perf_mode = LEGACY_PCM_MODE;
else if (pdata->perf_mode == ULTRA_LOW_LATENCY_PCM_MODE)
prtd->audio_client->perf_mode = LOW_LATENCY_PCM_NOPROC_MODE;
else
prtd->audio_client->perf_mode = LOW_LATENCY_PCM_MODE;
@ -3774,6 +3776,9 @@ static int msm_pcm_probe(struct platform_device *pdev)
else if (!strcmp(latency_level, "ull-pp"))
pdata->perf_mode =
ULL_POST_PROCESSING_PCM_MODE;
else if (!strcmp(latency_level, "llnp"))
pdata->perf_mode =
LOW_LATENCY_PCM_NOPROC_MODE;
}
} else {
pdata->perf_mode = LEGACY_PCM_MODE;

View file

@ -1456,6 +1456,8 @@ int msm_pcm_routing_set_channel_mixer_cfg(
struct msm_pcm_channel_mixer *params)
{
int i, j = 0;
int num_ch_input_map = 0;
int num_ch_out_map = 0;
channel_mixer_v2[fe_id][type].enable = params->enable;
channel_mixer_v2[fe_id][type].rule = params->rule;
@ -1465,12 +1467,18 @@ int msm_pcm_routing_set_channel_mixer_cfg(
params->output_channel;
channel_mixer_v2[fe_id][type].port_idx = params->port_idx;
for (i = 0; i < ADM_MAX_CHANNELS; i++)
for (i = 0; i < ADM_MAX_CHANNELS; i++) {
channel_mixer_v2[fe_id][type].in_ch_map[i] =
params->in_ch_map[i];
for (i = 0; i < ADM_MAX_CHANNELS; i++)
if (channel_mixer_v2[fe_id][type].in_ch_map[i] > 0)
num_ch_input_map++;
}
for (i = 0; i < ADM_MAX_CHANNELS; i++) {
channel_mixer_v2[fe_id][type].out_ch_map[i] =
params->out_ch_map[i];
if (channel_mixer_v2[fe_id][type].out_ch_map[i] > 0)
num_ch_out_map++;
}
for (i = 0; i < ADM_MAX_CHANNELS; i++)
for (j = 0; j < ADM_MAX_CHANNELS; j++)
@ -1481,7 +1489,14 @@ int msm_pcm_routing_set_channel_mixer_cfg(
params->override_in_ch_map;
channel_mixer_v2[fe_id][type].override_out_ch_map =
params->override_out_ch_map;
if (channel_mixer_v2[fe_id][type].input_channel != num_ch_input_map && channel_mixer_v2[fe_id][type].override_in_ch_map) {
channel_mixer_v2[fe_id][type].override_in_ch_map =false;
pr_info("%s: mismatched with num_ch_input_map %d override_in_ch_map set to false \n", __func__,num_ch_input_map);
}
if (channel_mixer_v2[fe_id][type].output_channel != num_ch_out_map && channel_mixer_v2[fe_id][type].override_out_ch_map) {
channel_mixer_v2[fe_id][type].override_out_ch_map =false;
pr_info("%s: mismatched with num_ch_out_map %d override_out_ch_map set to false \n", __func__,num_ch_out_map);
}
return 0;
}
EXPORT_SYMBOL(msm_pcm_routing_set_channel_mixer_cfg);
@ -2209,7 +2224,7 @@ static int msm_pcm_routing_channel_mixer_v2(int fe_id, bool perf_mode,
int j = 0, be_id = 0;
int ret = 0;
if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
pr_err("%s: invalid FE %d\n", __func__, fe_id);
return 0;
}
@ -2276,7 +2291,7 @@ static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode,
return ret;
}
if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
pr_err("%s: invalid FE %d\n", __func__, fe_id);
return 0;
}
@ -3702,6 +3717,12 @@ static int msm_routing_adm_get_backend_idx(struct snd_kcontrol *kcontrol)
backend_id = MSM_BACKEND_DAI_SLIMBUS_7_TX;
} else if (strnstr(kcontrol->id.name, "TERT_TDM_TX_0", sizeof("TERT_TDM_TX_0"))) {
backend_id = MSM_BACKEND_DAI_TERT_TDM_TX_0;
} else if (strnstr(kcontrol->id.name, "TERT_TDM_RX_0", sizeof("TERT_TDM_RX_0"))) {
backend_id = MSM_BACKEND_DAI_TERT_TDM_RX_0;
} else if (strnstr(kcontrol->id.name, "SEC_TDM_TX_0", sizeof("SEC_TDM_TX_0"))) {
backend_id = MSM_BACKEND_DAI_SEC_TDM_TX_0;
} else if (strnstr(kcontrol->id.name, "SEC_TDM_RX_0", sizeof("SEC_TDM_RX_0"))) {
backend_id = MSM_BACKEND_DAI_SEC_TDM_RX_0;
} else {
pr_err("%s: unsupported backend id: %s",
__func__, kcontrol->id.name);
@ -3752,6 +3773,15 @@ static const struct snd_kcontrol_new adm_channel_config_controls[] = {
SOC_ENUM_EXT("TERT_TDM_TX_0 ADM Channels", adm_override_chs,
msm_routing_adm_channel_config_get,
msm_routing_adm_channel_config_put),
SOC_ENUM_EXT("TERT_TDM_RX_0 ADM Channels", adm_override_chs,
msm_routing_adm_channel_config_get,
msm_routing_adm_channel_config_put),
SOC_ENUM_EXT("SEC_TDM_TX_0 ADM Channels", adm_override_chs,
msm_routing_adm_channel_config_get,
msm_routing_adm_channel_config_put),
SOC_ENUM_EXT("SEC_TDM_RX_0 ADM Channels", adm_override_chs,
msm_routing_adm_channel_config_get,
msm_routing_adm_channel_config_put),
};
static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol,
@ -32041,6 +32071,10 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0],
MSM_FRONTEND_DAI_MM_SIZE) {
if (i >= MSM_FRONTEND_DAI_MAX) {
pr_debug("%s: Invalid FE id %d\n", __func__, i);
return -EINVAL;
}
if ((fe_dai_map[i][session_type].passthr_mode == LEGACY_PCM) ||
(fe_dai_map[i][session_type].passthr_mode == LISTEN))
compr_passthr_mode = false;
@ -32747,6 +32781,10 @@ static void get_drift_and_put_asrc(struct work_struct *work)
else
pr_debug("%s: Succeed to get drift\n", __func__);
if (NULL == &p_asrc_cfg->modules) {
pr_err("%s: Failed to get asrc config modules\n", __func__);
goto exit;
}
list_for_each_safe(ptr, next, &p_asrc_cfg->modules) {
config_node = list_entry(ptr, struct asrc_module_config_node,
list);

View file

@ -1721,10 +1721,13 @@ done:
EXPORT_SYMBOL(msm_pcm_routing_get_stream_app_type_cfg);
static struct cal_block_data *msm_routing_find_topology_by_path(int path,
int cal_index)
int cal_index,
int app_type,
int acdb_id)
{
struct list_head *ptr, *next;
struct cal_block_data *cal_block = NULL;
struct audio_cal_info_adm_top *cal_info;
pr_debug("%s\n", __func__);
list_for_each_safe(ptr, next,
@ -1735,9 +1738,11 @@ static struct cal_block_data *msm_routing_find_topology_by_path(int path,
if (cal_utils_is_cal_stale(cal_block))
continue;
if (((struct audio_cal_info_adm_top *)cal_block
->cal_info)->path == path) {
cal_info = (struct audio_cal_info_adm_top *)
cal_block->cal_info;
if ((cal_info->path == path) &&
(cal_info->app_type == app_type) &&
(cal_info->acdb_id == acdb_id)) {
return cal_block;
}
}
@ -1778,7 +1783,9 @@ static struct cal_block_data *msm_routing_find_topology(int path,
"acdb_id %d %s\n", __func__, path, app_type, acdb_id,
exact ? "fail" : "defaulting to search by path");
return exact ? NULL : msm_routing_find_topology_by_path(path,
cal_index);
cal_index,
app_type,
acdb_id);
}
static struct cal_block_data *msm_routing_find_topology_by_buf_number(int usecase, int path,

View file

@ -7582,6 +7582,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
#endif /* CONFIG_AUDIO_QGKI */
.dpcm_playback = 1,
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,

View file

@ -7208,7 +7208,7 @@ static struct snd_soc_dai_link msm_tasha_be_dai_links[] = {
static struct snd_soc_dai_link msm_wcn_be_dai_links[] = {
{
.name = LPASS_BE_SLIMBUS_TX_VI,
.name = LPASS_BE_SLIMBUS_7_RX,
.stream_name = "Slimbus7 Playback",
/* BT codec driver determines capabilities based on
* dai name, bt codecdai name should always contains

19
config/arauto.conf Executable file
View file

@ -0,0 +1,19 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2021, The Linux Foundation. All rights reserved.
ifeq ($(CONFIG_QGKI), y)
export CONFIG_SND_SOC_GVM_AUTO_SPF=m
export CONFIG_MSM_QDSP6_APRV2_VM=m
export CONFIG_MSM_QDSP6_SSR=m
export CONFIG_MSM_ADSP_LOADER=m
export CONFIG_MSM_QDSP6_NOTIFIER=m
export CONFIG_SND_SOC_MSM_QDSP6V2_VM=m
export CONFIG_SND_SOC_QDSP6V2=m
export CONFIG_QTI_PP=m
export CONFIG_SND_HWDEP_ROUTING=m
export CONFIG_SND_SOC_MSM_STUB=m
export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
export CONFIG_MSM_QDSP6V2_CODECS=m
export CONFIG_SND_EVENT=m
export CONFIG_SND_SOC_SA8155=m
endif

27
config/arautoconf.h Executable file
View file

@ -0,0 +1,27 @@
/* Copyright (c) 2018-2019, 2021 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define CONFIG_SND_SOC_GVM_AUTO_SPF 1
#define CONFIG_MSM_QDSP6_APRV2_VM 1
#define CONFIG_MSM_ADSP_LOADER 1
#define CONFIG_MSM_QDSP6_SSR 1
#define CONFIG_MSM_QDSP6_NOTIFIER 1
#define CONFIG_SND_SOC_MSM_QDSP6V2_VM 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_MSM_HDMI_CODEC_RX 1
#define CONFIG_MSM_QDSP6V2_CODECS 1
#define CONFIG_SND_EVENT 1
#define CONFIG_SND_SOC_SA8155 1

View file

@ -29,6 +29,11 @@ ifeq ($(CONFIG_SND_SOC_AUTO), y)
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h
endif
ifdef CONFIG_SND_SOC_AR
include $(AUDIO_ROOT)/config/arauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/arautoconf.h
endif
ifdef CONFIG_SND_SOC_GVM_SA8295
include $(AUDIO_ROOT)/config/sa8295gvmauto.conf
export

7
dsp/q6asm.c Executable file → Normal file
View file

@ -3367,7 +3367,12 @@ static int __q6asm_open_read(struct audio_client *ac,
if (ac->perf_mode == LOW_LATENCY_PCM_MODE) {
open.mode_flags |= ASM_LOW_LATENCY_TX_STREAM_SESSION <<
ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
} else {
}
else if (ac->perf_mode == LOW_LATENCY_PCM_NOPROC_MODE) {
open.mode_flags |= ASM_LOW_LATENCY_NPROC_TX_STREAM_SESSION <<
ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
}
else {
open.mode_flags |= ASM_LEGACY_STREAM_SESSION <<
ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
}

3
include/dsp/apr_audio-v2.h Executable file → Normal file
View file

@ -8281,6 +8281,9 @@ struct asm_stream_cmd_open_shared_io {
/* Bit value for Low Latency Tx stream subfield */
#define ASM_LOW_LATENCY_TX_STREAM_SESSION 1
/* Bit value for Low Latency No Post Processing Tx stream subfield */
#define ASM_LOW_LATENCY_NPROC_TX_STREAM_SESSION 3
/* Bit shift for the stream_perf_mode subfield. */
#define ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ 29

View file

@ -30,6 +30,11 @@ ifeq ($(CONFIG_SND_SOC_AUTO), y)
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h
endif
ifdef CONFIG_SND_SOC_AR
include $(AUDIO_ROOT)/config/arauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/arautoconf.h
endif
ifdef CONFIG_SND_SOC_GVM_SA8295
include $(AUDIO_ROOT)/config/sa8295gvmauto.conf
export

View file

@ -1214,10 +1214,12 @@ static int apr_probe(struct platform_device *pdev)
return -ENOMEM;
}
#ifdef CONFIG_IPC_LOGGING
apr_pkt_ctx = ipc_log_context_create(APR_PKT_IPC_LOG_PAGE_CNT,
"apr", 0);
if (!apr_pkt_ctx)
pr_err("%s: Unable to create ipc log context\n", __func__);
#endif /* CONFIG_IPC_LOGGING */
spin_lock(&apr_priv->apr_lock);
apr_priv->is_initial_boot = true;

View file

@ -1421,10 +1421,12 @@ static int apr_probe(struct platform_device *pdev)
return -ENOMEM;
}
#ifdef CONFIG_IPC_LOGGING
apr_pkt_ctx = ipc_log_context_create(APR_PKT_IPC_LOG_PAGE_CNT,
"apr", 0);
if (!apr_pkt_ctx)
pr_err("%s: Unable to create ipc log context\n", __func__);
#endif /* CONFIG_IPC_LOGGING */
ret = of_property_read_string(pdev->dev.of_node,
"qcom,subsys-name",

View file

@ -29,6 +29,11 @@ ifeq ($(CONFIG_SND_SOC_AUTO), y)
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h
endif
ifdef CONFIG_SND_SOC_AR
include $(AUDIO_ROOT)/config/arauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/arautoconf.h
endif
ifdef CONFIG_SND_SOC_GVM_SA8295
include $(AUDIO_ROOT)/config/sa8295gvmauto.conf
export