Merge "Revert "Revert "dsp: voice_mhi: use modified mhi sync/put api""" into audio-drivers.lnx.4.0
diff --git a/asoc/Kbuild b/asoc/Kbuild
index 2b0696b..5ff12c6 100644
--- a/asoc/Kbuild
+++ b/asoc/Kbuild
@@ -31,7 +31,6 @@
endif
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
- export
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild
index 1d7142a..df86578 100644
--- a/asoc/codecs/Kbuild
+++ b/asoc/codecs/Kbuild
@@ -31,7 +31,6 @@
endif
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
- export
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild
index 374b528..06883a3 100644
--- a/asoc/codecs/bolero/Kbuild
+++ b/asoc/codecs/bolero/Kbuild
@@ -28,7 +28,6 @@
endif
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
- export
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index d805126..45e9936 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -638,15 +638,14 @@
struct bolero_priv *priv = data;
int macro_idx;
- if (priv->rsc_clk_cb)
- priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_DOWN);
-
bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_OFF_PRE_SSR);
regcache_cache_only(priv->regmap, true);
mutex_lock(&priv->clk_lock);
priv->dev_up = false;
mutex_unlock(&priv->clk_lock);
+ if (priv->rsc_clk_cb)
+ priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_DOWN);
/* call ssr event for supported macros */
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
if (!priv->macro_params[macro_idx].event_handler)
diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c
index 03befde..6742562 100644
--- a/asoc/codecs/bolero/bolero-clk-rsc.c
+++ b/asoc/codecs/bolero/bolero-clk-rsc.c
@@ -326,6 +326,10 @@
return;
}
regmap = dev_get_regmap(priv->dev->parent, NULL);
+ if (!regmap) {
+ pr_err("%s: regmap is null\n", __func__);
+ return;
+ }
if (enable) {
if (priv->reg_seq_en_cnt++ == 0) {
for (i = 0; i < (priv->num_fs_reg * 2); i += 2) {
@@ -401,7 +405,7 @@
}
mutex_lock(&priv->rsc_clk_lock);
- if (!priv->dev_up) {
+ if (!priv->dev_up && enable) {
dev_err_ratelimited(priv->dev, "%s: SSR is in progress..\n",
__func__);
ret = -EINVAL;
@@ -495,6 +499,10 @@
}
clk_name_array = devm_kzalloc(&pdev->dev, clk_cnt * sizeof(char *),
GFP_KERNEL);
+ if (!clk_name_array) {
+ ret = -ENOMEM;
+ goto err;
+ }
ret = of_property_read_string_array(pdev->dev.of_node, "clock-names",
clk_name_array, clk_cnt);
diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c
index c8a5e1d..d1ba346 100644
--- a/asoc/codecs/bolero/wsa-macro.c
+++ b/asoc/codecs/bolero/wsa-macro.c
@@ -220,6 +220,7 @@
struct wsa_macro_bcl_pmic_params bcl_pmic_params;
char __iomem *mclk_mode_muxsel;
u16 default_clk_id;
+ int wsa_digital_mute_status[WSA_MACRO_RX_MAX];
};
static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
@@ -1775,6 +1776,72 @@
return 0;
}
+static int wsa_macro_get_rx_mute_status(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct device *wsa_dev = NULL;
+ struct wsa_macro_priv *wsa_priv = NULL;
+ int wsa_rx_shift = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+ return -EINVAL;
+
+ ucontrol->value.integer.value[0] =
+ wsa_priv->wsa_digital_mute_status[wsa_rx_shift];
+ return 0;
+}
+
+static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct device *wsa_dev = NULL;
+ struct wsa_macro_priv *wsa_priv = NULL;
+ int value = ucontrol->value.integer.value[0];
+ int wsa_rx_shift = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+ return -EINVAL;
+
+ switch (wsa_rx_shift) {
+ case 0:
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_WSA_RX0_RX_PATH_CTL,
+ 0x10, value << 4);
+ break;
+ case 1:
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_WSA_RX1_RX_PATH_CTL,
+ 0x10, value << 4);
+ break;
+ case 2:
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
+ 0x10, value << 4);
+ break;
+ case 3:
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
+ 0x10, value << 4);
+ break;
+ default:
+ pr_err("%s: invalid argument rx_shift = %d\n", __func__,
+ wsa_rx_shift);
+ return -EINVAL;
+ }
+
+ dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
+ __func__, wsa_rx_shift, value);
+ wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
+ return 0;
+}
+
static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -2102,6 +2169,18 @@
SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
0, -84, 40, digital_gain),
+ SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
+ 0, wsa_macro_get_rx_mute_status,
+ wsa_macro_set_rx_mute_status),
+ SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX1, 1,
+ 0, wsa_macro_get_rx_mute_status,
+ wsa_macro_set_rx_mute_status),
+ SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM,
+ WSA_MACRO_RX_MIX0, 1, 0, wsa_macro_get_rx_mute_status,
+ wsa_macro_set_rx_mute_status),
+ SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM,
+ WSA_MACRO_RX_MIX1, 1, 0, wsa_macro_get_rx_mute_status,
+ wsa_macro_set_rx_mute_status),
SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
wsa_macro_get_compander, wsa_macro_set_compander),
SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c
index 04fd2de..220da9d 100644
--- a/asoc/codecs/msm-cdc-supply.c
+++ b/asoc/codecs/msm-cdc-supply.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@@ -357,7 +357,7 @@
/*
* msm_cdc_init_supplies:
- * Initialize codec static supplies with regulator get
+ * Initialize codec static supplies
*
* @dev: pointer to codec device
* @supplies: pointer to regulator bulk data
@@ -371,6 +371,29 @@
struct cdc_regulator *cdc_vreg,
int num_supplies)
{
+ return msm_cdc_init_supplies_v2(dev, supplies, cdc_vreg,
+ num_supplies, false);
+}
+EXPORT_SYMBOL(msm_cdc_init_supplies);
+
+/*
+ * msm_cdc_init_supplies_v2:
+ * Initialize codec static supplies.
+ * Initialize codec dynamic supplies based on vote_regulator_on_demand
+ *
+ * @dev: pointer to codec device
+ * @supplies: pointer to regulator bulk data
+ * @cdc_vreg: pointer to platform regulator data
+ * @num_supplies: number of supplies
+ * @vote_regulator_on_demand: initialize codec dynamic supplies at runtime
+ *
+ * Return error code if supply init is failed
+ */
+int msm_cdc_init_supplies_v2(struct device *dev,
+ struct regulator_bulk_data **supplies,
+ struct cdc_regulator *cdc_vreg,
+ int num_supplies, u32 vote_regulator_on_demand)
+{
struct regulator_bulk_data *vsup;
int rc;
int i;
@@ -413,6 +436,9 @@
if (regulator_count_voltages(vsup[i].consumer) < 0)
continue;
+ if (cdc_vreg[i].ondemand && vote_regulator_on_demand)
+ continue;
+
rc = regulator_set_voltage(vsup[i].consumer,
cdc_vreg[i].min_uV,
cdc_vreg[i].max_uV);
@@ -437,7 +463,7 @@
err_supply:
return rc;
}
-EXPORT_SYMBOL(msm_cdc_init_supplies);
+EXPORT_SYMBOL(msm_cdc_init_supplies_v2);
/*
* msm_cdc_get_power_supplies:
diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c
index 4ab510c..4a2c928 100644
--- a/asoc/codecs/wcd-mbhc-adc.c
+++ b/asoc/codecs/wcd-mbhc-adc.c
@@ -343,14 +343,66 @@
return (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP) ? true : false;
}
+static int wcd_mbhc_adc_get_spl_hs_thres(struct wcd_mbhc *mbhc)
+{
+ int hs_threshold, micbias_mv;
+
+ micbias_mv = wcd_mbhc_get_micbias(mbhc);
+ if (mbhc->hs_thr && mbhc->micb_mv != WCD_MBHC_ADC_MICBIAS_MV) {
+ if (mbhc->micb_mv == micbias_mv)
+ hs_threshold = mbhc->hs_thr;
+ else
+ hs_threshold = (mbhc->hs_thr *
+ micbias_mv) / mbhc->micb_mv;
+ } else {
+ hs_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV *
+ micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV);
+ }
+ return hs_threshold;
+}
+
+static int wcd_mbhc_adc_get_hs_thres(struct wcd_mbhc *mbhc)
+{
+ int hs_threshold, micbias_mv;
+
+ micbias_mv = wcd_mbhc_get_micbias(mbhc);
+ if (mbhc->hs_thr) {
+ if (mbhc->micb_mv == micbias_mv)
+ hs_threshold = mbhc->hs_thr;
+ else
+ hs_threshold = (mbhc->hs_thr *
+ micbias_mv) / mbhc->micb_mv;
+ } else {
+ hs_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV *
+ micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV);
+ }
+ return hs_threshold;
+}
+
+static int wcd_mbhc_adc_get_hph_thres(struct wcd_mbhc *mbhc)
+{
+ int hph_threshold, micbias_mv;
+
+ micbias_mv = wcd_mbhc_get_micbias(mbhc);
+ if (mbhc->hph_thr) {
+ if (mbhc->micb_mv == micbias_mv)
+ hph_threshold = mbhc->hph_thr;
+ else
+ hph_threshold = (mbhc->hph_thr *
+ micbias_mv) / mbhc->micb_mv;
+ } else {
+ hph_threshold = ((WCD_MBHC_ADC_HPH_THRESHOLD_MV *
+ micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV);
+ }
+ return hph_threshold;
+}
+
static bool wcd_mbhc_adc_check_for_spl_headset(struct wcd_mbhc *mbhc,
int *spl_hs_cnt)
{
bool spl_hs = false;
int output_mv = 0;
int adc_threshold = 0, adc_hph_threshold = 0;
- struct snd_soc_component *component = mbhc->component;
- struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent);
pr_debug("%s: enter\n", __func__);
if (!mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic)
@@ -366,20 +418,8 @@
* btn press/relesae for HEADSET type during correct work.
*/
output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P);
-
- if (mbhc->hs_thr &&
- (pdata->micbias.micb2_mv != WCD_MBHC_ADC_MICBIAS_MV))
- adc_threshold = mbhc->hs_thr;
- else
- adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV *
- wcd_mbhc_get_micbias(mbhc))/WCD_MBHC_ADC_MICBIAS_MV);
-
- if (mbhc->hph_thr)
- adc_hph_threshold = mbhc->hph_thr;
- else
- adc_hph_threshold = ((WCD_MBHC_ADC_HPH_THRESHOLD_MV *
- wcd_mbhc_get_micbias(mbhc))/
- WCD_MBHC_ADC_MICBIAS_MV);
+ adc_threshold = wcd_mbhc_adc_get_spl_hs_thres(mbhc);
+ adc_hph_threshold = wcd_mbhc_adc_get_hph_thres(mbhc);
if (output_mv > adc_threshold || output_mv < adc_hph_threshold) {
spl_hs = false;
@@ -412,8 +452,6 @@
bool is_spl_hs = false;
int output_mv = 0;
int adc_threshold = 0;
- struct snd_soc_component *component = mbhc->component;
- struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent);
/*
* Increase micbias to 2.7V to detect headsets with
@@ -433,13 +471,7 @@
return false;
}
}
- if (mbhc->hs_thr &&
- (pdata->micbias.micb2_mv != WCD_MBHC_ADC_MICBIAS_MV))
- adc_threshold = mbhc->hs_thr;
- else
- adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV *
- wcd_mbhc_get_micbias(mbhc)) /
- WCD_MBHC_ADC_MICBIAS_MV);
+ adc_threshold = wcd_mbhc_adc_get_spl_hs_thres(mbhc);
while (!is_spl_hs) {
if (mbhc->hs_detect_work_stop) {
@@ -573,15 +605,8 @@
enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_INVALID;
u32 hph_thr = 0, hs_thr = 0;
- if (mbhc->hs_thr)
- hs_thr = mbhc->hs_thr;
- else
- hs_thr = WCD_MBHC_ADC_HS_THRESHOLD_MV;
-
- if (mbhc->hph_thr)
- hph_thr = mbhc->hph_thr;
- else
- hph_thr = WCD_MBHC_ADC_HPH_THRESHOLD_MV;
+ hs_thr = wcd_mbhc_adc_get_hs_thres(mbhc);
+ hph_thr = wcd_mbhc_adc_get_hph_thres(mbhc);
if (adc_result < hph_thr)
plug_type = MBHC_PLUG_TYPE_HEADPHONE;
@@ -609,12 +634,16 @@
int output_mv = 0;
int cross_conn;
int try = 0;
+ int hs_threshold, micbias_mv;
pr_debug("%s: enter\n", __func__);
mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch);
component = mbhc->component;
+ micbias_mv = wcd_mbhc_get_micbias(mbhc);
+ hs_threshold = wcd_mbhc_adc_get_hs_thres(mbhc);
+
WCD_MBHC_RSC_LOCK(mbhc);
/* Mask ADC COMPLETE interrupt */
wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false);
@@ -691,13 +720,15 @@
*/
plug_type = wcd_mbhc_get_plug_from_adc(mbhc, output_mv);
- if ((output_mv > WCD_MBHC_ADC_HS_THRESHOLD_MV) &&
+ if ((output_mv > hs_threshold) &&
(spl_hs_count < WCD_MBHC_SPL_HS_CNT)) {
spl_hs = wcd_mbhc_adc_check_for_spl_headset(mbhc,
&spl_hs_count);
+ output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P);
if (spl_hs_count == WCD_MBHC_SPL_HS_CNT) {
- output_mv = WCD_MBHC_ADC_HS_THRESHOLD_MV;
+ hs_threshold = (hs_threshold *
+ wcd_mbhc_get_micbias(mbhc)) / micbias_mv;
spl_hs = true;
mbhc->micbias_enable = true;
}
@@ -707,7 +738,7 @@
is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(
mbhc->component);
- if ((output_mv <= WCD_MBHC_ADC_HS_THRESHOLD_MV) &&
+ if ((output_mv <= hs_threshold) &&
(!is_pa_on)) {
/* Check for cross connection*/
ret = wcd_check_cross_conn(mbhc);
@@ -761,7 +792,7 @@
}
}
- if (output_mv > WCD_MBHC_ADC_HS_THRESHOLD_MV) {
+ if (output_mv > hs_threshold) {
pr_debug("%s: cable is extension cable\n", __func__);
plug_type = MBHC_PLUG_TYPE_HIGH_HPH;
wrk_complete = true;
@@ -926,9 +957,8 @@
timeout = jiffies +
msecs_to_jiffies(WCD_FAKE_REMOVAL_MIN_PERIOD_MS);
- adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV *
- wcd_mbhc_get_micbias(mbhc)) /
- WCD_MBHC_ADC_MICBIAS_MV);
+ adc_threshold = wcd_mbhc_adc_get_hs_thres(mbhc);
+
do {
retry++;
/*
diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c
index 22bc0e6..e501a35 100644
--- a/asoc/codecs/wcd9335.c
+++ b/asoc/codecs/wcd9335.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/init.h>
@@ -22,6 +22,7 @@
#include <linux/gpio.h>
#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
#include <soc/swr-wcd.h>
+#include <soc/snd_event.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
@@ -151,6 +152,8 @@
static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = {
"cdc-vdd-mic-bias",
+ "cdc-vdd-tx-h",
+ "cdc-vdd-rx-h"
};
enum {
@@ -5634,6 +5637,9 @@
snd_soc_dapm_to_component(w->dapm);
struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
struct on_demand_supply *supply;
+ struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
+ struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent);
+ const char *supply_name;
if (w->shift >= ON_DEMAND_SUPPLIES_MAX) {
dev_err(component->dev, "%s: error index > MAX Demand supplies",
@@ -5646,6 +5652,7 @@
__func__, on_demand_supply_name[w->shift], event);
supply = &tasha->on_demand_list[w->shift];
+ supply_name = on_demand_supply_name[w->shift];
WARN_ONCE(!supply->supply, "%s isn't defined\n",
on_demand_supply_name[w->shift]);
if (!supply->supply) {
@@ -5656,6 +5663,15 @@
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ if (pdata->vote_regulator_on_demand) {
+ ret = wcd9xxx_vote_ondemand_regulator(wcd9xxx, pdata,
+ supply_name,
+ true);
+ if (ret)
+ dev_err(component->dev, "%s: Failed to vote %s\n",
+ __func__,
+ on_demand_supply_name[w->shift]);
+ }
ret = regulator_enable(supply->supply);
if (ret)
dev_err(component->dev, "%s: Failed to enable %s\n",
@@ -5668,6 +5684,15 @@
dev_err(component->dev, "%s: Failed to disable %s\n",
__func__,
on_demand_supply_name[w->shift]);
+ if (pdata->vote_regulator_on_demand) {
+ ret = wcd9xxx_vote_ondemand_regulator(wcd9xxx, pdata,
+ supply_name,
+ false);
+ if (ret)
+ dev_err(component->dev, "%s: Failed to unvote %s\n",
+ __func__,
+ on_demand_supply_name[w->shift]);
+ }
break;
default:
break;
@@ -11130,7 +11155,14 @@
SND_SOC_DAPM_SUPPLY(DAPM_LDO_H_STANDALONE, SND_SOC_NOPM, 0, 0,
tasha_codec_force_enable_ldo_h,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
+ SND_SOC_DAPM_SUPPLY("tx regulator", SND_SOC_NOPM,
+ ON_DEMAND_TX_SUPPLY, 0,
+ tasha_codec_enable_on_demand_supply,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("rx regulator", SND_SOC_NOPM,
+ ON_DEMAND_RX_SUPPLY, 0,
+ tasha_codec_enable_on_demand_supply,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MUX("ANC0 FB MUX", SND_SOC_NOPM, 0, 0, &anc0_fb_mux),
SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
@@ -13708,11 +13740,23 @@
component = (struct snd_soc_component *)(wcd9xxx->ssr_priv);
priv = snd_soc_component_get_drvdata(component);
+ snd_event_notify(priv->dev->parent, SND_EVENT_DOWN);
wcd_cpe_ssr_event(priv->cpe_core, WCD_CPE_BUS_DOWN_EVENT);
- for (i = 0; i < priv->nr; i++)
+
+ if (!priv->swr_ctrl_data)
+ return -EINVAL;
+
+ for (i = 0; i < priv->nr; i++) {
+ if (is_snd_event_fwk_enabled())
+ swrm_wcd_notify(
+ priv->swr_ctrl_data[i].swr_pdev,
+ SWR_DEVICE_SSR_DOWN, NULL);
swrm_wcd_notify(priv->swr_ctrl_data[i].swr_pdev,
SWR_DEVICE_DOWN, NULL);
- snd_soc_card_change_online_state(component->card, 0);
+ }
+
+ if (!is_snd_event_fwk_enabled())
+ snd_soc_card_change_online_state(component->card, 0);
for (count = 0; count < NUM_CODEC_DAIS; count++)
priv->dai[count].bus_down_in_recovery = true;
@@ -13747,7 +13791,8 @@
if (tasha->machine_codec_event_cb)
tasha->machine_codec_event_cb(component,
WCD9335_CODEC_EVENT_CODEC_UP);
- snd_soc_card_change_online_state(component->card, 1);
+ if (!is_snd_event_fwk_enabled())
+ snd_soc_card_change_online_state(component->card, 1);
/* Class-H Init*/
wcd_clsh_init(&tasha->clsh_d);
@@ -13807,9 +13852,21 @@
goto err;
}
+ if (!tasha->swr_ctrl_data) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (is_snd_event_fwk_enabled()) {
+ for (i = 0; i < tasha->nr; i++)
+ swrm_wcd_notify(
+ tasha->swr_ctrl_data[i].swr_pdev,
+ SWR_DEVICE_SSR_UP, NULL);
+ }
+
tasha_set_spkr_mode(component, tasha->spkr_mode);
wcd_cpe_ssr_event(tasha->cpe_core, WCD_CPE_BUS_UP_EVENT);
-
+ snd_event_notify(tasha->dev->parent, SND_EVENT_UP);
err:
mutex_unlock(&tasha->codec_mutex);
return ret;
@@ -13835,6 +13892,28 @@
return NULL;
}
+static void tasha_ssr_disable(struct device *dev, void *data)
+{
+ struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev);
+ struct tasha_priv *tasha;
+ struct snd_soc_component *component;
+ int count = 0;
+
+ if (!wcd9xxx) {
+ dev_dbg(dev, "%s: wcd9xxx pointer NULL.\n", __func__);
+ return;
+ }
+ component = (struct snd_soc_component *)(wcd9xxx->ssr_priv);
+ tasha = snd_soc_component_get_drvdata(component);
+
+ for (count = 0; count < NUM_CODEC_DAIS; count++)
+ tasha->dai[count].bus_down_in_recovery = true;
+}
+
+static const struct snd_event_ops tasha_ssr_ops = {
+ .disable = tasha_ssr_disable,
+};
+
static int tasha_codec_probe(struct snd_soc_component *component)
{
struct wcd9xxx *control;
@@ -13899,12 +13978,14 @@
goto err;
}
- supply = tasha_codec_find_ondemand_regulator(component,
- on_demand_supply_name[ON_DEMAND_MICBIAS]);
- if (supply) {
- tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply;
- tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count =
- 0;
+ for (i = ON_DEMAND_MICBIAS; i < ON_DEMAND_SUPPLIES_MAX; i++) {
+ supply = tasha_codec_find_ondemand_regulator(component,
+ on_demand_supply_name[i]);
+ if (supply) {
+ tasha->on_demand_list[i].supply = supply;
+ tasha->on_demand_list[i].ondemand_supply_count =
+ 0;
+ }
}
tasha->fw_data = devm_kzalloc(component->dev,
@@ -14654,6 +14735,14 @@
tasha_update_reg_defaults(tasha);
schedule_work(&tasha->tasha_add_child_devices_work);
tasha_get_codec_ver(tasha);
+ ret = snd_event_client_register(pdev->dev.parent, &tasha_ssr_ops, NULL);
+ if (!ret) {
+ snd_event_notify(pdev->dev.parent, SND_EVENT_UP);
+ } else {
+ pr_err("%s: Registration with SND event fwk failed ret = %d\n",
+ __func__, ret);
+ ret = 0;
+ }
dev_info(&pdev->dev, "%s: Tasha driver probe done\n", __func__);
return ret;
@@ -14682,6 +14771,7 @@
if (!tasha)
return -EINVAL;
+ snd_event_client_deregister(pdev->dev.parent);
for (count = 0; count < tasha->child_count &&
count < WCD9335_CHILD_DEVICES_MAX; count++)
platform_device_unregister(tasha->pdev_child_devices[count]);
diff --git a/asoc/codecs/wcd9335.h b/asoc/codecs/wcd9335.h
index 969ac67..707f2e9 100644
--- a/asoc/codecs/wcd9335.h
+++ b/asoc/codecs/wcd9335.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#ifndef WCD9335_H
#define WCD9335_H
@@ -81,6 +81,8 @@
enum tasha_on_demand_supply {
ON_DEMAND_MICBIAS = 0,
+ ON_DEMAND_TX_SUPPLY,
+ ON_DEMAND_RX_SUPPLY,
ON_DEMAND_SUPPLIES_MAX,
};
diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c
index f00e4c0..d777d8d 100644
--- a/asoc/codecs/wcd934x/wcd934x-mbhc.c
+++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/init.h>
@@ -1102,6 +1102,7 @@
struct wcd934x_mbhc *wcd934x_mbhc;
struct wcd_mbhc *wcd_mbhc;
int ret;
+ struct wcd9xxx_pdata *pdata;
wcd934x_mbhc = devm_kzalloc(component->dev, sizeof(struct wcd934x_mbhc),
GFP_KERNEL);
@@ -1122,6 +1123,14 @@
/* Setting default mbhc detection logic to ADC for Tavil */
wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC;
+ pdata = dev_get_platdata(component->dev->parent);
+ if (!pdata) {
+ dev_err(component->dev, "%s: pdata pointer is NULL\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ wcd_mbhc->micb_mv = pdata->micbias.micb2_mv;
+
ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb,
&intr_ids, wcd_mbhc_registers,
TAVIL_ZDET_SUPPORTED);
diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c
index 07bbcb3..f1c3536 100644
--- a/asoc/codecs/wcd934x/wcd934x.c
+++ b/asoc/codecs/wcd934x/wcd934x.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/init.h>
@@ -4687,20 +4687,18 @@
tavil->tx_hpf_work[decimator].hpf_cut_off_freq =
hpf_cut_off_freq;
- if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
- snd_soc_component_update_bits(component, dec_cfg_reg,
- TX_HPF_CUT_OFF_FREQ_MASK,
- CF_MIN_3DB_150HZ << 5);
- snd_soc_component_update_bits(component, hpf_gate_reg,
+ snd_soc_component_update_bits(component, dec_cfg_reg,
+ TX_HPF_CUT_OFF_FREQ_MASK,
+ CF_MIN_3DB_150HZ << 5);
+ snd_soc_component_update_bits(component, hpf_gate_reg,
0x02, 0x02);
- /*
- * Minimum 1 clk cycle delay is required as per
- * HW spec.
- */
- usleep_range(1000, 1010);
- snd_soc_component_update_bits(component, hpf_gate_reg,
+ /*
+ * Minimum 1 clk cycle delay is required as per
+ * HW spec.
+ */
+ usleep_range(1000, 1010);
+ snd_soc_component_update_bits(component, hpf_gate_reg,
0x02, 0x00);
- }
/* schedule work queue to Remove Mute */
schedule_delayed_work(&tavil->tx_mute_dwork[decimator].dwork,
msecs_to_jiffies(tx_unmute_delay));
diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c
index fcc4e6f..bde3a7e 100644
--- a/asoc/codecs/wcd937x/wcd937x.c
+++ b/asoc/codecs/wcd937x/wcd937x.c
@@ -134,6 +134,12 @@
snd_soc_component_update_bits(component,
WCD937X_HPH_SURGE_HPHLR_SURGE_EN,
0xFF, 0xD9);
+ snd_soc_component_update_bits(component, WCD937X_MICB1_TEST_CTL_1,
+ 0xFF, 0xFA);
+ snd_soc_component_update_bits(component, WCD937X_MICB2_TEST_CTL_1,
+ 0xFF, 0xFA);
+ snd_soc_component_update_bits(component, WCD937X_MICB3_TEST_CTL_1,
+ 0xFF, 0xFA);
return 0;
}
diff --git a/asoc/codecs/wcd938x/Kbuild b/asoc/codecs/wcd938x/Kbuild
index e301bd5..3dfe142 100644
--- a/asoc/codecs/wcd938x/Kbuild
+++ b/asoc/codecs/wcd938x/Kbuild
@@ -16,7 +16,6 @@
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
- export
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index ca20bc4..6241cf2 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -1655,13 +1655,20 @@
snd_soc_dapm_kcontrol_widget(kcontrol);
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
- struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
- u32 path = 0;
+ struct wcd938x_priv *wcd938x = NULL;
+ int path = 0;
- if (!widget || !widget->name || !wcd938x || !component)
+ if (!component)
+ return -EINVAL;
+
+ wcd938x = snd_soc_component_get_drvdata(component);
+
+ if (!widget || !widget->name || !wcd938x)
return -EINVAL;
path = wcd938x_tx_path_get(widget->name);
+ if (path < 0 || path >= TX_ADC_MAX)
+ return -EINVAL;
ucontrol->value.integer.value[0] = wcd938x->tx_mode[path];
@@ -1675,14 +1682,22 @@
snd_soc_dapm_kcontrol_widget(kcontrol);
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
- struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+ struct wcd938x_priv *wcd938x = NULL;
u32 mode_val;
- u32 path = 0;
+ int path = 0;
- if (!widget || !widget->name || !wcd938x || !component)
+ if (!component)
+ return -EINVAL;
+
+ wcd938x = snd_soc_component_get_drvdata(component);
+
+ if (!widget || !widget->name || !wcd938x)
return -EINVAL;
path = wcd938x_tx_path_get(widget->name);
+ if (path < 0 || path >= TX_ADC_MAX)
+ return -EINVAL;
+
mode_val = ucontrol->value.enumerated.item[0];
dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val);
diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c
index b0cb9c7..fd2e933 100644
--- a/asoc/codecs/wcd9xxx-core.c
+++ b/asoc/codecs/wcd9xxx-core.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@@ -98,6 +98,65 @@
struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE];
+/*
+ * wcd9xxx_vote_ondemand_regulator: Initialize codec dynamic supplies
+ *
+ * @wcd9xxx: Pointer to wcd9xxx structure
+ * @wcd9xxx_pdata: Pointer to wcd9xxx_pdata structure
+ * @supply_name: supply parameter to initialize regulator
+ * @enable: flag to initialize/uninitialize supply
+ *
+ * Return error code if supply init is failed
+ */
+int wcd9xxx_vote_ondemand_regulator(struct wcd9xxx *wcd9xxx,
+ struct wcd9xxx_pdata *pdata,
+ const char *supply_name,
+ bool enable)
+{
+ int i, rc, index = -EINVAL;
+
+ pr_debug("%s: enable %d\n", __func__, enable);
+
+ for (i = 0; i < wcd9xxx->num_of_supplies; ++i) {
+ if (pdata->regulator[i].ondemand &&
+ wcd9xxx->supplies[i].supply &&
+ !strcmp(wcd9xxx->supplies[i].supply, supply_name)) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index < 0) {
+ pr_err("%s: no matching regulator found\n", __func__);
+ return -EINVAL;
+ }
+
+ if (enable) {
+ rc = regulator_set_voltage(wcd9xxx->supplies[index].consumer,
+ pdata->regulator[index].min_uV,
+ pdata->regulator[index].max_uV);
+ if (rc) {
+ pr_err("%s: set regulator voltage failed for %s, err:%d\n",
+ __func__, supply_name, rc);
+ return rc;
+ }
+ rc = regulator_set_load(wcd9xxx->supplies[index].consumer,
+ pdata->regulator[index].optimum_uA);
+ if (rc < 0) {
+ pr_err("%s: set regulator optimum mode failed for %s, err:%d\n",
+ __func__, supply_name, rc);
+ return rc;
+ }
+ } else {
+ regulator_set_voltage(wcd9xxx->supplies[index].consumer, 0,
+ pdata->regulator[index].max_uV);
+ regulator_set_load(wcd9xxx->supplies[index].consumer, 0);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(wcd9xxx_vote_ondemand_regulator);
+
static int wcd9xxx_slim_multi_reg_write(struct wcd9xxx *wcd9xxx,
const void *data, size_t count)
{
@@ -1069,9 +1128,10 @@
wcd9xxx->mclk_rate = pdata->mclk_rate;
wcd9xxx->num_of_supplies = pdata->num_supplies;
- ret = msm_cdc_init_supplies(wcd9xxx->dev, &wcd9xxx->supplies,
- pdata->regulator,
- pdata->num_supplies);
+ ret = msm_cdc_init_supplies_v2(wcd9xxx->dev, &wcd9xxx->supplies,
+ pdata->regulator,
+ pdata->num_supplies,
+ pdata->vote_regulator_on_demand);
if (!wcd9xxx->supplies) {
dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n",
__func__);
@@ -1327,9 +1387,10 @@
}
wcd9xxx->num_of_supplies = pdata->num_supplies;
- ret = msm_cdc_init_supplies(&slim->dev, &wcd9xxx->supplies,
- pdata->regulator,
- pdata->num_supplies);
+ ret = msm_cdc_init_supplies_v2(&slim->dev, &wcd9xxx->supplies,
+ pdata->regulator,
+ pdata->num_supplies,
+ pdata->vote_regulator_on_demand);
if (!wcd9xxx->supplies) {
dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n",
__func__);
diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c
index 06968dc..face711 100644
--- a/asoc/codecs/wcd9xxx-utils.c
+++ b/asoc/codecs/wcd9xxx-utils.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@@ -414,6 +414,14 @@
pdata->dmic_clk_drv = dmic_clk_drive;
+ rc = of_property_read_u32(dev->of_node,
+ "qcom,vote-dynamic-supply-on-demand",
+ &pdata->vote_regulator_on_demand);
+ if (rc)
+ dev_dbg(dev, "%s No entry for %s property in node %s\n",
+ __func__, "qcom,vote-dynamic-supply-on-demand",
+ dev->of_node->full_name);
+
return pdata;
err_parse_dt_prop:
diff --git a/asoc/sm8250-port-config.h b/asoc/kona-port-config.h
similarity index 95%
rename from asoc/sm8250-port-config.h
rename to asoc/kona-port-config.h
index 503d514..0f73791 100644
--- a/asoc/sm8250-port-config.h
+++ b/asoc/kona-port-config.h
@@ -3,8 +3,8 @@
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
-#ifndef _SM8250_PORT_CONFIG
-#define _SM8250_PORT_CONFIG
+#ifndef _KONA_PORT_CONFIG
+#define _KONA_PORT_CONFIG
#include <soc/swr-common.h>
@@ -57,4 +57,4 @@
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
};
-#endif /* _SM8250_PORT_CONFIG */
+#endif /* _KONA_PORT_CONFIG */
diff --git a/asoc/kona.c b/asoc/kona.c
index 574c652..50a25b1 100644
--- a/asoc/kona.c
+++ b/asoc/kona.c
@@ -35,7 +35,7 @@
#include "codecs/bolero/bolero-cdc.h"
#include <dt-bindings/sound/audio-codec-port-types.h>
#include "codecs/bolero/wsa-macro.h"
-#include "sm8250-port-config.h"
+#include "kona-port-config.h"
#define DRV_NAME "kona-asoc-snd"
#define __CHIPSET__ "KONA "
@@ -73,6 +73,7 @@
#define WSA8810_NAME_2 "wsa881x.20170212"
#define WCN_CDC_SLIM_RX_CH_MAX 2
#define WCN_CDC_SLIM_TX_CH_MAX 2
+#define WCN_CDC_SLIM_TX_CH_MAX_LITO 3
enum {
TDM_0 = 0,
@@ -137,6 +138,7 @@
};
enum {
SLIM_TX_7 = 0,
+ SLIM_TX_8,
SLIM_TX_MAX,
};
@@ -191,6 +193,7 @@
static struct dev_config slim_tx_cfg[] = {
[SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
};
/* Default configuration of external display BE */
@@ -3632,6 +3635,12 @@
slim_tx_cfg[SLIM_TX_7].channels;
break;
+ case MSM_BACKEND_DAI_SLIMBUS_8_TX:
+ rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate;
+ channels->min = channels->max =
+ slim_tx_cfg[SLIM_TX_8].channels;
+ break;
+
case MSM_BACKEND_DAI_AFE_LOOPBACK_TX:
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
afe_loopback_tx_cfg[idx].bit_format);
@@ -3991,6 +4000,41 @@
mutex_unlock(&mi2s_intf_conf[index].lock);
}
+static int msm_wcn_hw_params_lito(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX_LITO];
+ u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
+ int ret = 0;
+
+ dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__,
+ codec_dai->name, codec_dai->id);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret) {
+ dev_err(rtd->dev,
+ "%s: failed to get BTFM codec chan map\n, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+
+ dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n",
+ __func__, tx_ch_cnt, dai_link->id);
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch);
+ if (ret)
+ dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+
+err:
+ return ret;
+}
+
static int msm_wcn_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -4047,6 +4091,10 @@
.hw_params = msm_wcn_hw_params,
};
+static struct snd_soc_ops msm_wcn_ops_lito = {
+ .hw_params = msm_wcn_hw_params_lito,
+};
+
static int msm_dmic_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -4155,6 +4203,16 @@
tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
}
+static int msm_wcn_init_lito(struct snd_soc_pcm_runtime *rtd)
+{
+ unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158};
+ unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX_LITO] = {159, 160, 161};
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+
+ return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
+ tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
+}
+
static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
int ret = -EINVAL;
@@ -4897,6 +4955,22 @@
.ignore_pmdown_time = 1,
.id = MSM_FRONTEND_DAI_MULTIMEDIA17,
},
+ {/* hw:x,38 */
+ .name = "SLIMBUS_8 Hostless",
+ .stream_name = "SLIMBUS_8 Hostless",
+ .cpu_dai_name = "SLIMBUS8_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
};
static struct snd_soc_dai_link msm_common_be_dai_links[] = {
@@ -5141,6 +5215,58 @@
},
};
+static struct snd_soc_dai_link msm_wcn_btfm_be_dai_links[] = {
+ {
+ .name = LPASS_BE_SLIMBUS_7_RX,
+ .stream_name = "Slimbus7 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16398",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ /* BT codec driver determines capabilities based on
+ * dai name, bt codecdai name should always contains
+ * supported usecase information
+ */
+ .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_7_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .init = &msm_wcn_init_lito,
+ .ops = &msm_wcn_ops_lito,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_7_TX,
+ .stream_name = "Slimbus7 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16399",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ .codec_dai_name = "btfm_bt_sco_slim_tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_7_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_wcn_ops_lito,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_8_TX,
+ .stream_name = "Slimbus8 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16401",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ .codec_dai_name = "btfm_fm_slim_tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_8_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_wcn_ops_lito,
+ .ignore_suspend = 1,
+ },
+};
+
static struct snd_soc_dai_link ext_disp_be_dai_link[] = {
/* DISP PORT BACK END DAI Link */
{
@@ -5566,7 +5692,8 @@
ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) +
ARRAY_SIZE(ext_disp_be_dai_link) +
ARRAY_SIZE(msm_wcn_be_dai_links) +
- ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link)];
+ ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) +
+ ARRAY_SIZE(msm_wcn_btfm_be_dai_links)];
static int msm_populate_dai_link_component_of_node(
struct snd_soc_card *card)
@@ -5769,6 +5896,7 @@
u32 mi2s_audio_intf = 0;
u32 auxpcm_audio_intf = 0;
u32 val = 0;
+ u32 wcn_btfm_intf = 0;
const struct of_device_id *match;
match = of_match_node(kona_asoc_machine_of_match, dev->of_node);
@@ -5881,6 +6009,21 @@
total_links +=
ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link);
}
+
+ rc = of_property_read_u32(dev->of_node, "qcom,wcn-btfm",
+ &wcn_btfm_intf);
+ if (rc) {
+ dev_dbg(dev, "%s: No DT match wcn btfm interface\n",
+ __func__);
+ } else {
+ if (wcn_btfm_intf) {
+ memcpy(msm_kona_dai_links + total_links,
+ msm_wcn_btfm_be_dai_links,
+ sizeof(msm_wcn_btfm_be_dai_links));
+ total_links +=
+ ARRAY_SIZE(msm_wcn_btfm_be_dai_links);
+ }
+ }
dailink = msm_kona_dai_links;
} else if(!strcmp(match->data, "stub_codec")) {
card = &snd_soc_card_stub_msm;
diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c
index a7b9ff2..f358e45 100644
--- a/asoc/msm-compress-q6-v2.c
+++ b/asoc/msm-compress-q6-v2.c
@@ -76,6 +76,10 @@
#define SND_DEC_DDP_MAX_PARAMS 18
+#ifndef COMPRESSED_PERF_MODE_FLAG
+#define COMPRESSED_PERF_MODE_FLAG 0
+#endif
+
struct msm_compr_gapless_state {
bool set_next_stream_id;
int32_t stream_opened[MAX_NUMBER_OF_STREAMS];
@@ -2042,6 +2046,11 @@
}
}
+ if (params->codec.flags & COMPRESSED_PERF_MODE_FLAG) {
+ pr_debug("%s: setting perf mode = %d", __func__, LOW_LATENCY_PCM_MODE);
+ prtd->audio_client->perf_mode = LOW_LATENCY_PCM_MODE;
+ }
+
switch (params->codec.id) {
case SND_AUDIOCODEC_PCM: {
pr_debug("SND_AUDIOCODEC_PCM\n");
@@ -3741,7 +3750,7 @@
pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
- if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
pr_err("%s Received out of bounds fe_id %llu\n",
__func__, fe_id);
rc = -EINVAL;
@@ -3783,7 +3792,7 @@
int rc = 0, i;
pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
- if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
pr_err("%s: Received out of bounds fe_id %llu\n",
__func__, fe_id);
rc = -EINVAL;
@@ -4729,6 +4738,16 @@
chmixer_pspd->output_channel = ucontrol->value.integer.value[3];
chmixer_pspd->port_idx = ucontrol->value.integer.value[4];
+ if (chmixer_pspd->input_channel <= 0 ||
+ chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8 ||
+ chmixer_pspd->output_channel <= 0 ||
+ chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+ pr_err("%s: Invalid channels, in %d, out %d\n",
+ __func__, chmixer_pspd->input_channel,
+ chmixer_pspd->output_channel);
+ return -EINVAL;
+ }
+
if (chmixer_pspd->enable) {
if (session_type == SESSION_TYPE_RX &&
!chmixer_pspd->override_in_ch_map) {
@@ -4737,11 +4756,6 @@
chmixer_pspd->in_ch_map[i] =
pdata->ch_map[fe_id]->channel_map[i];
} else {
- if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
- pr_err("%s: Invalid channel count %d\n",
- __func__, chmixer_pspd->input_channel);
- return -EINVAL;
- }
q6asm_map_channels(asm_ch_map,
chmixer_pspd->input_channel, false);
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
@@ -4756,11 +4770,6 @@
chmixer_pspd->out_ch_map[i] =
pdata->ch_map[fe_id]->channel_map[i];
} else {
- if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
- pr_err("%s: Invalid channel count %d\n",
- __func__, chmixer_pspd->output_channel);
- return -EINVAL;
- }
q6asm_map_channels(asm_ch_map,
chmixer_pspd->output_channel, false);
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
@@ -4782,13 +4791,8 @@
cstream = pdata->cstream[fe_id];
if (chmixer_pspd->enable && cstream && cstream->runtime) {
prtd = cstream->runtime->private_data;
- if (!prtd) {
- pr_err("%s invalid prtd\n", __func__);
- ret = -EINVAL;
- goto done;
- }
- if (prtd->audio_client) {
+ if (prtd && prtd->audio_client) {
stream_id = prtd->audio_client->session;
be_id = chmixer_pspd->port_idx;
ret = msm_pcm_routing_set_channel_mixer_runtime(be_id,
@@ -4801,7 +4805,6 @@
if (reset_override_in_ch_map)
chmixer_pspd->override_in_ch_map = false;
-done:
return ret;
}
diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c
index d4f33c7..1a82d65 100644
--- a/asoc/msm-dai-q6-v2.c
+++ b/asoc/msm-dai-q6-v2.c
@@ -1091,17 +1091,6 @@
}
afe_open(aux_dai_data->rx_pid, &dai_data->port_config, dai_data->rate);
- if (q6core_get_avcs_api_version_per_service(
- APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
- /*
- * send island mode config
- * This should be the first configuration
- */
- rc = afe_send_port_island_mode(aux_dai_data->tx_pid);
- if (rc)
- dev_err(dai->dev, "%s: afe send island mode failed %d\n",
- __func__, rc);
- }
afe_open(aux_dai_data->tx_pid, &dai_data->port_config, dai_data->rate);
goto exit;
@@ -5029,18 +5018,6 @@
dai->id, port_id, dai_data->channels, dai_data->rate);
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
- if (q6core_get_avcs_api_version_per_service(
- APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
- /*
- * send island mode config.
- * This should be the first configuration
- */
- rc = afe_send_port_island_mode(port_id);
- if (rc)
- dev_err(dai->dev, "%s: afe send island mode failed %d\n",
- __func__, rc);
- }
-
/* PORT START should be set if prepare called
* in active state.
*/
@@ -8296,17 +8273,6 @@
group_ref = &tdm_group_ref[group_idx];
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
- if (q6core_get_avcs_api_version_per_service(
- APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
- /*
- * send island mode config.
- * This should be the first configuration
- */
- rc = afe_send_port_island_mode(dai->id);
- if (rc)
- dev_err(dai->dev, "%s: afe send island mode failed %d\n",
- __func__, rc);
- }
if (msm_dai_q6_get_tdm_clk_ref(group_idx) == 0) {
/* TX and RX share the same clk. So enable the clk
@@ -10573,17 +10539,6 @@
int rc = 0;
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
- if (q6core_get_avcs_api_version_per_service(
- APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
- /*
- * send island mode config.
- * This should be the first configuration
- */
- rc = afe_send_port_island_mode(dai->id);
- if (rc)
- pr_err("%s: afe send island mode failed %d\n",
- __func__, rc);
- }
if ((dai->id == AFE_PORT_ID_WSA_CODEC_DMA_TX_0) &&
(dai_data->port_config.cdc_dma.data_format == 1))
dai_data->port_config.cdc_dma.data_format =
diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c
index b010010..322bf66 100644
--- a/asoc/msm-pcm-q6-v2.c
+++ b/asoc/msm-pcm-q6-v2.c
@@ -1934,20 +1934,24 @@
chmixer_pspd->output_channel = ucontrol->value.integer.value[3];
chmixer_pspd->port_idx = ucontrol->value.integer.value[4];
- if (chmixer_pspd->enable) {
+ if (chmixer_pspd->input_channel <= 0 ||
+ chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8 ||
+ chmixer_pspd->output_channel <= 0 ||
+ chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+ pr_err("%s: Invalid channels, in %d, out %d\n",
+ __func__, chmixer_pspd->input_channel,
+ chmixer_pspd->output_channel);
+ return -EINVAL;
+ }
+
+ prtd = substream->runtime ? substream->runtime->private_data : NULL;
+ if (chmixer_pspd->enable && prtd) {
if (session_type == SESSION_TYPE_RX &&
!chmixer_pspd->override_in_ch_map) {
- if (pdata->ch_map[fe_id] &&
- pdata->ch_map[fe_id]->set_ch_map) {
+ if (prtd->set_channel_map) {
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
- chmixer_pspd->in_ch_map[i] =
- pdata->ch_map[fe_id]->channel_map[i];
+ chmixer_pspd->in_ch_map[i] = prtd->channel_map[i];
} else {
- if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
- pr_err("%s: Invalid channel count %d\n",
- __func__, chmixer_pspd->input_channel);
- return -EINVAL;
- }
q6asm_map_channels(asm_ch_map,
chmixer_pspd->input_channel, false);
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
@@ -1957,22 +1961,14 @@
reset_override_in_ch_map = true;
} else if (session_type == SESSION_TYPE_TX &&
!chmixer_pspd->override_out_ch_map) {
- if (pdata->ch_map[fe_id] &&
- pdata->ch_map[fe_id]->set_ch_map) {
- for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
- chmixer_pspd->out_ch_map[i] =
- pdata->ch_map[fe_id]->channel_map[i];
- } else {
- if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
- pr_err("%s: Invalid channel count %d\n",
- __func__, chmixer_pspd->output_channel);
- return -EINVAL;
- }
- q6asm_map_channels(asm_ch_map,
- chmixer_pspd->output_channel, false);
- for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
- chmixer_pspd->out_ch_map[i] = asm_ch_map[i];
- }
+ /*
+ * Channel map set in prtd is for plyback only,
+ * hence always use default for capture path.
+ */
+ q6asm_map_channels(asm_ch_map,
+ chmixer_pspd->output_channel, false);
+ for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
+ chmixer_pspd->out_ch_map[i] = asm_ch_map[i];
chmixer_pspd->override_out_ch_map = true;
reset_override_out_ch_map = true;
}
@@ -1986,22 +1982,13 @@
session_type,
chmixer_pspd);
- if (chmixer_pspd->enable && substream->runtime) {
- prtd = substream->runtime->private_data;
- if (!prtd) {
- pr_err("%s find invalid prtd fail\n", __func__);
- ret = -EINVAL;
- goto done;
- }
-
- if (prtd->audio_client) {
- stream_id = prtd->audio_client->session;
- be_id = chmixer_pspd->port_idx;
- msm_pcm_routing_set_channel_mixer_runtime(be_id,
- stream_id,
- session_type,
- chmixer_pspd);
- }
+ if (chmixer_pspd->enable && prtd && prtd->audio_client) {
+ stream_id = prtd->audio_client->session;
+ be_id = chmixer_pspd->port_idx;
+ msm_pcm_routing_set_channel_mixer_runtime(be_id,
+ stream_id,
+ session_type,
+ chmixer_pspd);
}
if (reset_override_out_ch_map)
@@ -2009,7 +1996,6 @@
if (reset_override_in_ch_map)
chmixer_pspd->override_in_ch_map = false;
-done:
return ret;
}
diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c
index e4d34d1..ea476c1 100644
--- a/asoc/msm-pcm-voice-v2.c
+++ b/asoc/msm-pcm-voice-v2.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/init.h>
@@ -24,6 +24,9 @@
#define DRV_NAME "msm-pcm-voice-v2"
+#define NUM_CHANNELS_MONO 1
+#define NUM_CHANNELS_STEREO 2
+
static struct msm_voice voice_info[VOICE_SESSION_INDEX_MAX];
static struct snd_pcm_hardware msm_pcm_hardware = {
@@ -616,6 +619,38 @@
return ret;
}
+static int msm_voice_rec_config_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret = 0;
+ int voc_rec_config_channels = ucontrol->value.integer.value[0];
+
+ if (voc_rec_config_channels < NUM_CHANNELS_MONO ||
+ voc_rec_config_channels > NUM_CHANNELS_STEREO) {
+ pr_err("%s: Invalid channel config (%d)\n", __func__,
+ voc_rec_config_channels);
+ ret = -EINVAL;
+ goto done;
+ }
+ voc_set_incall_capture_channel_config(voc_rec_config_channels);
+
+done:
+ pr_debug("%s: voc_rec_config_channels = %d, ret = %d\n", __func__,
+ voc_rec_config_channels, ret);
+ return ret;
+}
+
+static int msm_voice_rec_config_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ ucontrol->value.integer.value[0] =
+ voc_get_incall_capture_channel_config();
+ pr_debug("%s: rec_config_channels = %ld\n", __func__,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
static int msm_voice_cvd_version_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
@@ -678,6 +713,12 @@
msm_voice_mbd_put),
};
+static struct snd_kcontrol_new msm_voice_rec_config_controls[] = {
+ SOC_SINGLE_MULTI_EXT("Voc Rec Config", SND_SOC_NOPM, 0,
+ 2, 0, 1, msm_voice_rec_config_get,
+ msm_voice_rec_config_put),
+};
+
static const struct snd_pcm_ops msm_pcm_ops = {
.open = msm_pcm_open,
.hw_params = msm_pcm_hw_params,
@@ -703,7 +744,8 @@
{
snd_soc_add_component_controls(component, msm_voice_controls,
ARRAY_SIZE(msm_voice_controls));
-
+ snd_soc_add_component_controls(component, msm_voice_rec_config_controls,
+ ARRAY_SIZE(msm_voice_rec_config_controls));
return 0;
}
diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c
index a311cc1..dc41037 100644
--- a/asoc/msm-transcode-loopback-q6-v2.c
+++ b/asoc/msm-transcode-loopback-q6-v2.c
@@ -901,6 +901,67 @@
return ret;
}
+static int msm_transcode_capture_app_type_cfg_put(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u64 fe_id = kcontrol->private_value;
+ int session_type = SESSION_TYPE_TX;
+ int be_id = ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_BE_ID];
+ struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000};
+ int ret = 0;
+
+ cfg_data.app_type = ucontrol->value.integer.value[
+ APP_TYPE_CONFIG_IDX_APP_TYPE];
+ cfg_data.acdb_dev_id = ucontrol->value.integer.value[
+ APP_TYPE_CONFIG_IDX_ACDB_ID];
+ if (ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_SAMPLE_RATE] != 0)
+ cfg_data.sample_rate = ucontrol->value.integer.value[
+ APP_TYPE_CONFIG_IDX_SAMPLE_RATE];
+ pr_debug("%s: fe_id %llu session_type %d be_id %d app_type %d acdb_dev_id %d sample_rate- %d\n",
+ __func__, fe_id, session_type, be_id,
+ cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
+ ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
+ be_id, &cfg_data);
+ if (ret < 0)
+ pr_err("%s: register stream app type cfg failed, returned %d\n",
+ __func__, ret);
+
+ return ret;
+}
+
+static int msm_transcode_capture_app_type_cfg_get(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u64 fe_id = kcontrol->private_value;
+ int session_type = SESSION_TYPE_TX;
+ int be_id = 0;
+ struct msm_pcm_stream_app_type_cfg cfg_data = {0};
+ int ret = 0;
+
+ ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
+ &be_id, &cfg_data);
+ if (ret < 0) {
+ pr_err("%s: get stream app type cfg failed, returned %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_APP_TYPE] =
+ cfg_data.app_type;
+ ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_ACDB_ID] =
+ cfg_data.acdb_dev_id;
+ ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_SAMPLE_RATE] =
+ cfg_data.sample_rate;
+ ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_BE_ID] = be_id;
+ pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
+ __func__, fe_id, session_type, be_id,
+ cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
+done:
+ return ret;
+}
+
static int msm_transcode_set_volume(struct snd_compr_stream *cstream,
uint32_t master_gain)
{
@@ -1411,14 +1472,12 @@
struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_component *component = NULL;
- char mixer_str[32];
+ char mixer_str[128];
struct snd_kcontrol_new fe_app_type_cfg_control[1] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = msm_transcode_app_type_cfg_info,
- .put = msm_transcode_playback_app_type_cfg_put,
- .get = msm_transcode_playback_app_type_cfg_get,
.private_value = 0,
}
};
@@ -1451,10 +1510,28 @@
snd_soc_add_component_controls(component,
fe_app_type_cfg_control,
ARRAY_SIZE(fe_app_type_cfg_control));
+ } else if (rtd->compr->direction == SND_COMPRESS_CAPTURE) {
+ snprintf(mixer_str, sizeof(mixer_str),
+ "Audio Stream Capture %d App Type Cfg",
+ rtd->pcm->device);
+
+ fe_app_type_cfg_control[0].name = mixer_str;
+ fe_app_type_cfg_control[0].private_value = rtd->dai_link->id;
+
+ fe_app_type_cfg_control[0].put =
+ msm_transcode_capture_app_type_cfg_put;
+ fe_app_type_cfg_control[0].get =
+ msm_transcode_capture_app_type_cfg_get;
+
+ pr_debug("Registering new mixer ctl %s", mixer_str);
+ snd_soc_add_component_controls(component,
+ fe_app_type_cfg_control,
+ ARRAY_SIZE(fe_app_type_cfg_control));
}
return 0;
}
+
static int msm_transcode_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
diff --git a/asoc/qcs405.c b/asoc/qcs405.c
index 0bbe37b..0455748 100644
--- a/asoc/qcs405.c
+++ b/asoc/qcs405.c
@@ -678,6 +678,60 @@
static struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
+static int msm_island_vad_get_portid_from_beid(int32_t be_id, int *port_id)
+{
+ *port_id = 0xFFFF;
+
+ switch (be_id) {
+ case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0:
+ *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0;
+ break;
+ case MSM_BACKEND_DAI_QUINARY_MI2S_TX:
+ *port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
+ break;
+ case MSM_BACKEND_DAI_QUIN_TDM_TX_0:
+ *port_id = AFE_PORT_ID_QUINARY_TDM_TX;
+ break;
+ case MSM_BACKEND_DAI_QUIN_AUXPCM_TX:
+ *port_id = AFE_PORT_ID_QUINARY_PCM_TX;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int qcs405_send_island_vad_config(int32_t be_id)
+{
+ int rc = 0;
+ int port_id = 0xFFFF;
+
+ rc = msm_island_vad_get_portid_from_beid(be_id, &port_id);
+ if (rc) {
+ pr_debug("%s: Invalid island interface\n", __func__);
+ } else {
+ /*
+ * send island mode config
+ * This should be the first configuration
+ */
+ rc = afe_send_port_island_mode(port_id);
+ if (rc) {
+ pr_err("%s: afe send island mode failed %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ rc = afe_send_port_vad_cfg_params(port_id);
+ if (rc) {
+ pr_err("%s: afe send vad config failed %d\n",
+ __func__, rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
static int slim_get_sample_rate_val(int sample_rate)
{
int sample_rate_val = 0;
@@ -4048,29 +4102,6 @@
return ch_id;
}
-static int msm_vad_get_portid_from_beid(int32_t be_id, int *port_id)
-{
- *port_id = 0xFFFF;
-
- switch (be_id) {
- case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0:
- *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0;
- break;
- case MSM_BACKEND_DAI_QUINARY_MI2S_TX:
- *port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
- break;
- case MSM_BACKEND_DAI_QUIN_TDM_TX_0:
- *port_id = AFE_PORT_ID_QUINARY_TDM_TX;
- break;
- case MSM_BACKEND_DAI_QUIN_AUXPCM_TX:
- *port_id = AFE_PORT_ID_QUINARY_PCM_TX;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
static int msm_cdc_dma_get_idx_from_beid(int32_t be_id)
{
int idx = 0;
@@ -5073,6 +5104,34 @@
return ret;
}
+static int msm_snd_auxpcm_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+
+ ret = qcs405_send_island_vad_config(dai_link->id);
+ if (ret) {
+ pr_err("%s: send island/vad cfg failed, err = %d\n",
+ __func__, ret);
+ }
+ return ret;
+}
+
+static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+
+ ret = qcs405_send_island_vad_config(dai_link->id);
+ if (ret) {
+ pr_err("%s: send island/vad cfg failed, err = %d\n",
+ __func__, ret);
+ }
+ return ret;
+}
+
static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -5499,6 +5558,7 @@
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_card *card = rtd->card;
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
u32 tdm_mode = msm_get_tdm_mode(cpu_dai->id);
if (tdm_mode >= TDM_INTERFACE_MAX) {
@@ -5543,6 +5603,13 @@
}
}
+ ret = qcs405_send_island_vad_config(dai_link->id);
+ if (ret) {
+ pr_err("%s: send island/vad cfg failed, err = %d\n",
+ __func__, ret);
+ return ret;
+ }
+
return ret;
}
@@ -5612,7 +5679,7 @@
int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
int index = cpu_dai->id;
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
struct snd_soc_card *card = rtd->card;
@@ -5660,6 +5727,14 @@
msm_cdc_pinctrl_select_active_state(
pdata->mi2s_gpio_p[index]);
}
+
+ ret = qcs405_send_island_vad_config(dai_link->id);
+ if (ret) {
+ pr_err("%s: send island/vad cfg failed, err = %d\n",
+ __func__, ret);
+ return ret;
+ }
+
clk_off:
if (ret < 0)
msm_mi2s_set_sclk(substream, false);
@@ -5835,7 +5910,11 @@
.shutdown = msm_mi2s_snd_shutdown,
};
+static struct snd_soc_ops msm_auxpcm_be_ops = {
+ .startup = msm_snd_auxpcm_startup,
+};
static struct snd_soc_ops msm_cdc_dma_be_ops = {
+ .startup = msm_snd_cdc_dma_startup,
.hw_params = msm_snd_cdc_dma_hw_params,
};
@@ -7259,6 +7338,7 @@
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_AUXPCM_RX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
.ignore_pmdown_time = 1,
.ignore_suspend = 1,
},
@@ -7273,6 +7353,7 @@
.dpcm_capture = 1,
.id = MSM_BACKEND_DAI_AUXPCM_TX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
.ignore_suspend = 1,
},
/* Secondary AUX PCM Backend DAI Links */
@@ -7287,6 +7368,7 @@
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_SEC_AUXPCM_RX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
.ignore_pmdown_time = 1,
.ignore_suspend = 1,
},
@@ -7301,6 +7383,7 @@
.dpcm_capture = 1,
.id = MSM_BACKEND_DAI_SEC_AUXPCM_TX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
.ignore_suspend = 1,
},
/* Tertiary AUX PCM Backend DAI Links */
@@ -7315,6 +7398,7 @@
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_TERT_AUXPCM_RX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
.ignore_suspend = 1,
},
{
@@ -7328,6 +7412,7 @@
.dpcm_capture = 1,
.id = MSM_BACKEND_DAI_TERT_AUXPCM_TX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
.ignore_suspend = 1,
},
/* Quaternary AUX PCM Backend DAI Links */
@@ -7342,6 +7427,7 @@
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
.ignore_pmdown_time = 1,
.ignore_suspend = 1,
},
@@ -7356,6 +7442,7 @@
.dpcm_capture = 1,
.id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
.ignore_suspend = 1,
},
/* Quinary AUX PCM Backend DAI Links */
@@ -7370,6 +7457,7 @@
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
.ignore_pmdown_time = 1,
.ignore_suspend = 1,
},
@@ -7384,6 +7472,7 @@
.dpcm_capture = 1,
.id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
.ignore_suspend = 1,
},
};
@@ -7594,7 +7683,7 @@
pr_debug("%s: vad_enable=%d preroll_config=%d vad_intf=%d\n", __func__,
vad_enable, preroll_config, vad_intf);
- ret = msm_vad_get_portid_from_beid(vad_intf, &port_id);
+ ret = msm_island_vad_get_portid_from_beid(vad_intf, &port_id);
if (ret) {
pr_err("%s: Invalid vad interface\n", __func__);
goto done;
diff --git a/asoc/sa8155.c b/asoc/sa8155.c
index aef8a26..6dba206 100644
--- a/asoc/sa8155.c
+++ b/asoc/sa8155.c
@@ -691,6 +691,7 @@
static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text);
static bool is_initial_boot = true;
+static struct platform_device *spdev;
static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
{
@@ -7183,6 +7184,7 @@
goto err;
}
dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
+ spdev = pdev;
/* Parse pinctrl info from devicetree */
ret = msm_get_pinctrl(pdev);
@@ -7223,48 +7225,45 @@
.remove = msm_asoc_machine_remove,
};
-static int dummy_asoc_machine_probe(struct platform_device *pdev)
-{
- return 0;
-}
-
-static int dummy_asoc_machine_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
-static struct platform_device sa8155_dummy_asoc_machine_device = {
- .name = "sa8155-asoc-snd-dummy",
-};
-
-static struct platform_driver sa8155_dummy_asoc_machine_driver = {
- .driver = {
- .name = "sa8155-asoc-snd-dummy",
- .owner = THIS_MODULE,
- },
- .probe = dummy_asoc_machine_probe,
- .remove = dummy_asoc_machine_remove,
-};
-
static int sa8155_notifier_service_cb(struct notifier_block *this,
unsigned long opcode, void *ptr)
{
+ struct snd_soc_card *card = NULL;
+
pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
switch (opcode) {
case AUDIO_NOTIFIER_SERVICE_DOWN:
+ if (!spdev)
+ return -EINVAL;
+ card = platform_get_drvdata(spdev);
+ if (card == NULL){
+ pr_err("%s: card is NULL\n",__func__);
+ return -EINVAL;
+ } else {
+ pr_debug("%s: setting snd_card to OFFLINE\n", __func__);
+ snd_soc_card_change_online_state(card, 0);
+ }
break;
case AUDIO_NOTIFIER_SERVICE_UP:
if (is_initial_boot) {
- platform_driver_register(&sa8155_dummy_asoc_machine_driver);
- platform_device_register(&sa8155_dummy_asoc_machine_device);
is_initial_boot = false;
+ break;
+ }
+ if (!spdev)
+ return -EINVAL;
+ card = platform_get_drvdata(spdev);
+ if (card == NULL){
+ pr_err("%s: card is NULL\n",__func__);
+ return -EINVAL;
+ } else {
+ pr_debug("%s: setting snd_card to ONLINE\n", __func__);
+ snd_soc_card_change_online_state(card, 1);
}
break;
default:
break;
}
-
return NOTIFY_OK;
}
diff --git a/config/konaauto.conf b/config/konaauto.conf
index 7b03dea..03e0541 100644
--- a/config/konaauto.conf
+++ b/config/konaauto.conf
@@ -1,38 +1,38 @@
-CONFIG_PINCTRL_LPI=m
-CONFIG_PINCTRL_WCD=m
-CONFIG_AUDIO_EXT_CLK=m
-CONFIG_SND_SOC_WCD9XXX_V2=m
-CONFIG_SND_SOC_WCD_MBHC=m
-CONFIG_SND_SOC_WSA881X=m
-CONFIG_WCD9XXX_CODEC_CORE_V2=m
-CONFIG_MSM_CDC_PINCTRL=m
-CONFIG_MSM_QDSP6V2_CODECS=m
-CONFIG_MSM_ULTRASOUND=m
-CONFIG_MSM_QDSP6_APRV2_RPMSG=m
-CONFIG_MSM_ADSP_LOADER=m
-CONFIG_REGMAP_SWR=m
-CONFIG_MSM_QDSP6_SSR=m
-CONFIG_MSM_QDSP6_PDR=m
-CONFIG_MSM_QDSP6_NOTIFIER=m
-CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m
-CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m
-CONFIG_SOUNDWIRE=m
-CONFIG_SOUNDWIRE_MSTR_CTRL=m
-CONFIG_SND_SOC_QDSP6V2=m
-CONFIG_SND_SOC_WCD_MBHC_ADC=m
-CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
-CONFIG_QTI_PP=m
-CONFIG_SND_HWDEP_ROUTING=m
-CONFIG_SND_SOC_MSM_STUB=m
-CONFIG_MSM_AVTIMER=m
-CONFIG_SND_SOC_BOLERO=m
-CONFIG_WSA_MACRO=m
-CONFIG_VA_MACRO=m
-CONFIG_RX_MACRO=m
-CONFIG_TX_MACRO=m
-CONFIG_SND_SOC_WCD_IRQ=m
-CONFIG_SND_SOC_WCD938X=m
-CONFIG_SND_SOC_WCD938X_SLAVE=m
-CONFIG_SND_SOC_KONA=m
-CONFIG_SND_EVENT=m
-CONFIG_VOICE_MHI=m
+export CONFIG_PINCTRL_LPI=m
+export CONFIG_PINCTRL_WCD=m
+export CONFIG_AUDIO_EXT_CLK=m
+export CONFIG_SND_SOC_WCD9XXX_V2=m
+export CONFIG_SND_SOC_WCD_MBHC=m
+export CONFIG_SND_SOC_WSA881X=m
+export CONFIG_WCD9XXX_CODEC_CORE_V2=m
+export CONFIG_MSM_CDC_PINCTRL=m
+export CONFIG_MSM_QDSP6V2_CODECS=m
+export CONFIG_MSM_ULTRASOUND=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_HOSTLESS_PCM=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_SND_SOC_MSM_HDMI_CODEC_RX=m
+export CONFIG_QTI_PP=m
+export CONFIG_SND_HWDEP_ROUTING=m
+export CONFIG_SND_SOC_MSM_STUB=m
+export CONFIG_MSM_AVTIMER=m
+export CONFIG_SND_SOC_BOLERO=m
+export CONFIG_WSA_MACRO=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_KONA=m
+export CONFIG_SND_EVENT=m
+export CONFIG_VOICE_MHI=m
diff --git a/dsp/Kbuild b/dsp/Kbuild
index cf9de15..086924f 100644
--- a/dsp/Kbuild
+++ b/dsp/Kbuild
@@ -26,7 +26,6 @@
endif
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
- export
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild
index b4be485..d78675f 100644
--- a/dsp/codecs/Kbuild
+++ b/dsp/codecs/Kbuild
@@ -26,7 +26,6 @@
endif
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
- export
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index 8848b22..345123f 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -128,6 +128,8 @@
}
};
+static struct adm_multi_ch_map port_channel_map[AFE_MAX_PORTS];
+
static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH];
static int adm_module_topo_list[MAX_COPPS_PER_PORT *
ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH];
@@ -146,7 +148,8 @@
static int adm_arrange_mch_map_v8(
struct adm_device_endpoint_payload *ep_payload,
int path,
- int channel_mode);
+ int channel_mode,
+ int port_idx);
/**
* adm_validate_and_get_port_index -
@@ -578,7 +581,8 @@
index += ch_mixer->output_channel;
} else {
ep_params.dev_num_channel = ch_mixer->output_channel;
- adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel);
+ adm_arrange_mch_map_v8(&ep_params, path_type,
+ ep_params.dev_num_channel, port_idx);
for (i = 0; i < ch_mixer->output_channel; i++)
adm_pspd_params[index++] = ep_params.dev_channel_mapping[i];
}
@@ -589,7 +593,8 @@
index += ch_mixer->input_channel;
} else {
ep_params.dev_num_channel = ch_mixer->input_channels[channel_index];
- adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel);
+ adm_arrange_mch_map_v8(&ep_params, path_type,
+ ep_params.dev_num_channel, port_idx);
for (i = 0; i < ch_mixer->input_channels[channel_index]; i++)
adm_pspd_params[index++] = ep_params.dev_channel_mapping[i];
}
@@ -1302,6 +1307,31 @@
}
EXPORT_SYMBOL(adm_get_multi_ch_map);
+/**
+ * adm_set_port_multi_ch_map -
+ * Update port specific channel map info
+ *
+ * @channel_map: pointer with channel map info
+ * @port_id: port for which chmap is set
+ */
+void adm_set_port_multi_ch_map(char *channel_map, int port_id)
+{
+ int port_idx;
+
+ port_id = q6audio_convert_virtual_to_portid(port_id);
+ port_idx = adm_validate_and_get_port_index(port_id);
+
+ if (port_idx < 0) {
+ pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
+ return;
+ }
+
+ memcpy(port_channel_map[port_idx].channel_mapping, channel_map,
+ PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+ port_channel_map[port_idx].set_channel_map = true;
+}
+EXPORT_SYMBOL(adm_set_port_multi_ch_map);
+
static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload,
u32 payload_size)
{
@@ -2380,7 +2410,7 @@
EXPORT_SYMBOL(adm_connect_afe_port);
int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path,
- int channel_mode)
+ int channel_mode, int port_idx)
{
int rc = 0, idx;
@@ -2398,10 +2428,18 @@
default:
goto non_mch_path;
};
- if ((open->dev_num_channel > 2) && multi_ch_maps[idx].set_channel_map) {
- memcpy(open->dev_channel_mapping,
- multi_ch_maps[idx].channel_mapping,
- PCM_FORMAT_MAX_NUM_CHANNEL);
+
+ if ((open->dev_num_channel > 2) &&
+ (port_channel_map[port_idx].set_channel_map ||
+ multi_ch_maps[idx].set_channel_map)) {
+ if (port_channel_map[port_idx].set_channel_map)
+ memcpy(open->dev_channel_mapping,
+ port_channel_map[port_idx].channel_mapping,
+ PCM_FORMAT_MAX_NUM_CHANNEL);
+ else
+ memcpy(open->dev_channel_mapping,
+ multi_ch_maps[idx].channel_mapping,
+ PCM_FORMAT_MAX_NUM_CHANNEL);
} else {
if (channel_mode == 1) {
open->dev_channel_mapping[0] = PCM_CHANNEL_FC;
@@ -2515,8 +2553,7 @@
static int adm_arrange_mch_map_v8(
struct adm_device_endpoint_payload *ep_payload,
- int path,
- int channel_mode)
+ int path, int channel_mode, int port_idx)
{
int rc = 0, idx;
@@ -2535,10 +2572,16 @@
};
if ((ep_payload->dev_num_channel > 2) &&
- multi_ch_maps[idx].set_channel_map) {
- memcpy(ep_payload->dev_channel_mapping,
- multi_ch_maps[idx].channel_mapping,
- PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+ (port_channel_map[port_idx].set_channel_map ||
+ multi_ch_maps[idx].set_channel_map)) {
+ if (port_channel_map[port_idx].set_channel_map)
+ memcpy(ep_payload->dev_channel_mapping,
+ port_channel_map[port_idx].channel_mapping,
+ PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+ else
+ memcpy(ep_payload->dev_channel_mapping,
+ multi_ch_maps[idx].channel_mapping,
+ PCM_FORMAT_MAX_NUM_CHANNEL_V8);
} else {
if (channel_mode == 1) {
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC;
@@ -2754,6 +2797,11 @@
__func__, port_id, copp_idx, sample_rate,
bps, in_channels, out_channels);
+ if (out_channels <= 0 || out_channels > AUDPROC_MFC_OUT_CHANNELS_MAX) {
+ pr_err("%s: unsupported out channels=%d\n", __func__, out_channels);
+ return -EINVAL;
+ }
+
/* 1. Update Media Format */
param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
param_hdr.param_size = sizeof(mfc_cfg);
@@ -3052,7 +3100,7 @@
ep1_payload.bit_width = bit_width;
ep1_payload.sample_rate = rate;
ret = adm_arrange_mch_map_v8(&ep1_payload, path,
- channel_mode);
+ channel_mode, port_idx);
if (ret)
return ret;
@@ -3165,8 +3213,8 @@
(rate != ULL_SUPPORTED_SAMPLE_RATE));
open.sample_rate = rate;
- ret = adm_arrange_mch_map(&open, path, channel_mode);
-
+ ret = adm_arrange_mch_map(&open, path, channel_mode,
+ port_idx);
if (ret)
return ret;
@@ -3314,7 +3362,7 @@
atomic_read(&this_adm.copp.channels[port_idx][copp_idx]);
rc = adm_arrange_mch_map(&open, ADM_PATH_PLAYBACK,
- mfc_cfg.num_channels);
+ mfc_cfg.num_channels, port_idx);
if (rc < 0) {
pr_err("%s: unable to get channal map\n", __func__);
goto fail_cmd;
@@ -3671,6 +3719,7 @@
return -EINVAL;
}
+ port_channel_map[port_idx].set_channel_map = false;
if (this_adm.copp.adm_delay[port_idx][copp_idx] && perf_mode
== LEGACY_PCM_MODE) {
atomic_set(&this_adm.copp.adm_delay_stat[port_idx][copp_idx],
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 6c188d7..7a510be 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -1466,7 +1466,8 @@
}
static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr,
- u8 *packed_param_data, u32 packed_data_size)
+ u8 *packed_param_data, u32 packed_data_size,
+ bool is_iid_supported)
{
int ret;
@@ -1476,7 +1477,7 @@
return ret;
}
- if (q6common_is_instance_id_supported())
+ if (is_iid_supported)
return q6afe_svc_set_params_v2(index, mem_hdr,
packed_param_data,
packed_data_size);
@@ -1494,13 +1495,15 @@
u32 packed_data_size =
sizeof(struct param_hdr_v3) + param_hdr.param_size;
int ret = 0;
+ bool is_iid_supported = q6common_is_instance_id_supported();
packed_param_data = kzalloc(packed_data_size, GFP_KERNEL);
if (!packed_param_data)
return -ENOMEM;
- ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data,
- &packed_data_size);
+ ret = q6common_pack_pp_params_v2(packed_param_data, ¶m_hdr,
+ param_data, &packed_data_size,
+ is_iid_supported);
if (ret) {
pr_err("%s: Failed to pack parameter header and data, error %d\n",
__func__, ret);
@@ -1508,7 +1511,7 @@
}
ret = q6afe_svc_set_params(index, NULL, packed_param_data,
- packed_data_size);
+ packed_data_size, is_iid_supported);
done:
kfree(packed_param_data);
@@ -2255,6 +2258,13 @@
u32 island_mode = 0;
int ret = 0;
+ if (!(q6core_get_avcs_api_version_per_service(
+ APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4)) {
+ pr_debug("%s: AFE port[%d] API version is invalid!\n",
+ __func__, port_id);
+ return 0;
+ }
+
memset(&island_cfg, 0, sizeof(island_cfg));
memset(¶m_info, 0, sizeof(param_info));
@@ -2303,66 +2313,105 @@
return ret;
}
-static int afe_send_port_vad_cfg_params(u16 port_id)
+int afe_send_port_vad_cfg_params(u16 port_id)
{
struct afe_param_id_vad_cfg_t vad_cfg;
+ struct afe_mod_enable_param vad_enable;
struct param_hdr_v3 param_info;
u32 pre_roll_cfg = 0;
struct firmware_cal *hwdep_cal = NULL;
int ret = 0;
+ uint16_t port_index = 0;
- memset(&vad_cfg, 0, sizeof(vad_cfg));
- memset(¶m_info, 0, sizeof(param_info));
-
- ret = afe_get_vad_preroll_cfg(port_id, &pre_roll_cfg);
- if (ret) {
- pr_err("%s: AFE port[%d] get preroll cfg is invalid!\n",
- __func__, port_id);
- return ret;
- }
- param_info.module_id = AFE_MODULE_VAD;
- param_info.instance_id = INSTANCE_ID_0;
- param_info.param_id = AFE_PARAM_ID_VAD_CFG;
- param_info.param_size = sizeof(vad_cfg);
-
- vad_cfg.vad_cfg_minor_version = AFE_API_VERSION_VAD_CFG;
- vad_cfg.pre_roll_in_ms = pre_roll_cfg;
-
- ret = q6afe_pack_and_set_param_in_band(port_id,
- q6audio_get_port_index(port_id),
- param_info, (u8 *) &vad_cfg);
- if (ret) {
- pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
- __func__, port_id, ret);
- return ret;
+ if (!(q6core_get_avcs_api_version_per_service(
+ APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4)) {
+ pr_err("%s: AFE port[%d]: AFE API version doesn't support VAD config\n",
+ __func__, port_id);
+ return 0;
}
- memset(¶m_info, 0, sizeof(param_info));
+ port_index = afe_get_port_index(port_id);
- hwdep_cal = q6afecal_get_fw_cal(this_afe.fw_data, Q6AFE_VAD_CORE_CAL);
- if (!hwdep_cal) {
- pr_err("%s: error in retrieving vad core calibration",
- __func__);
- return -EINVAL;
+ if (this_afe.vad_cfg[port_index].is_enable) {
+ memset(&vad_cfg, 0, sizeof(vad_cfg));
+ memset(¶m_info, 0, sizeof(param_info));
+
+ ret = afe_get_vad_preroll_cfg(port_id, &pre_roll_cfg);
+ if (ret) {
+ pr_err("%s: AFE port[%d] get preroll cfg is invalid!\n",
+ __func__, port_id);
+ return ret;
+ }
+ param_info.module_id = AFE_MODULE_VAD;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = AFE_PARAM_ID_VAD_CFG;
+ param_info.param_size = sizeof(vad_cfg);
+
+ vad_cfg.vad_cfg_minor_version = AFE_API_VERSION_VAD_CFG;
+ vad_cfg.pre_roll_in_ms = pre_roll_cfg;
+
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_info, (u8 *) &vad_cfg);
+ if (ret) {
+ pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
+ __func__, port_id, ret);
+ return ret;
+ }
+
+ memset(¶m_info, 0, sizeof(param_info));
+
+ hwdep_cal = q6afecal_get_fw_cal(this_afe.fw_data,
+ Q6AFE_VAD_CORE_CAL);
+ if (!hwdep_cal) {
+ pr_err("%s: error in retrieving vad core calibration",
+ __func__);
+ return -EINVAL;
+ }
+
+ param_info.module_id = AFE_MODULE_VAD;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = AFE_PARAM_ID_VAD_CORE_CFG;
+ param_info.param_size = hwdep_cal->size;
+
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_info,
+ (u8 *) hwdep_cal->data);
+ if (ret) {
+ pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
+ __func__, port_id, ret);
+ return ret;
+ }
}
- param_info.module_id = AFE_MODULE_VAD;
- param_info.instance_id = INSTANCE_ID_0;
- param_info.param_id = AFE_PARAM_ID_VAD_CORE_CFG;
- param_info.param_size = hwdep_cal->size;
+ if (q6core_get_avcs_api_version_per_service(
+ APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V6) {
+ memset(&vad_enable, 0, sizeof(vad_enable));
+ memset(¶m_info, 0, sizeof(param_info));
+ param_info.module_id = AFE_MODULE_VAD;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = AFE_PARAM_ID_ENABLE;
+ param_info.param_size = sizeof(vad_enable);
- ret = q6afe_pack_and_set_param_in_band(port_id,
- q6audio_get_port_index(port_id),
- param_info, (u8 *) hwdep_cal->data);
- if (ret) {
- pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
- __func__, port_id, ret);
- return ret;
+ port_index = afe_get_port_index(port_id);
+ vad_enable.enable = this_afe.vad_cfg[port_index].is_enable;
+
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_info, (u8 *) &vad_enable);
+ if (ret) {
+ pr_err("%s: AFE set vad enable for port 0x%x failed %d\n",
+ __func__, port_id, ret);
+ return ret;
+ }
}
+
pr_debug("%s: AFE set preroll cfg %d vad core cfg port 0x%x ret %d\n",
__func__, pre_roll_cfg, port_id, ret);
return ret;
}
+EXPORT_SYMBOL(afe_send_port_vad_cfg_params);
static int remap_cal_data(struct cal_block_data *cal_block, int cal_index)
{
@@ -2595,6 +2644,7 @@
struct param_hdr_v3 param_hdr;
int idx = 0;
int ret = -EINVAL;
+ bool is_iid_supported = q6common_is_instance_id_supported();
memset(¶m_hdr, 0, sizeof(param_hdr));
max_single_param = sizeof(struct param_hdr_v3) +
@@ -2617,10 +2667,10 @@
while (packed_data_size + max_single_param < max_data_size &&
idx < cdc_reg_cfg->num_registers) {
- ret = q6common_pack_pp_params(
+ ret = q6common_pack_pp_params_v2(
packed_param_data + packed_data_size,
¶m_hdr, (u8 *) &cdc_reg_cfg->reg_data[idx],
- &single_param_size);
+ &single_param_size, is_iid_supported);
if (ret) {
pr_err("%s: Failed to pack parameters with error %d\n",
__func__, ret);
@@ -2631,7 +2681,8 @@
}
ret = q6afe_svc_set_params(IDX_GLOBAL_CFG, NULL,
- packed_param_data, packed_data_size);
+ packed_param_data, packed_data_size,
+ is_iid_supported);
if (ret) {
pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n",
__func__, ret);
@@ -3397,19 +3448,6 @@
port_index = afe_get_port_index(port_id);
- if (q6core_get_avcs_api_version_per_service(
- APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
- /* send VAD configuration if enabled */
- if (this_afe.vad_cfg[port_index].is_enable) {
- ret = afe_send_port_vad_cfg_params(port_id);
- if (ret) {
- pr_err("%s: afe send VAD config failed %d\n",
- __func__, ret);
- goto fail_cmd;
- }
- }
- }
-
/* Also send the topology id here: */
if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) {
/* One time call: only for first time */
@@ -4360,19 +4398,6 @@
mutex_lock(&this_afe.afe_cmd_lock);
port_index = afe_get_port_index(port_id);
- if (q6core_get_avcs_api_version_per_service(
- APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
- /* send VAD configuration if is enabled */
- if (this_afe.vad_cfg[port_index].is_enable) {
- ret = afe_send_port_vad_cfg_params(port_id);
- if (ret) {
- pr_err("%s: afe send VAD config failed %d\n",
- __func__, ret);
- goto fail_cmd;
- }
- }
- }
-
/* Also send the topology id here: */
if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) {
/* One time call: only for first time */
diff --git a/dsp/q6common.c b/dsp/q6common.c
index 8270054..b5444b1 100644
--- a/dsp/q6common.c
+++ b/dsp/q6common.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*/
#include <dsp/q6common.h>
@@ -104,3 +104,74 @@
return 0;
}
EXPORT_SYMBOL(q6common_pack_pp_params);
+
+/**
+ * q6common_pack_pp_params_v2
+ *
+ * Populate params header based on instance ID support and pack
+ * it with payload.
+ * Instance ID support -
+ * yes - param_hdr_v3 + payload
+ * no - param_hdr_v1 + payload
+ *
+ * @dest: destination data pointer to be packed into
+ * @v3_hdr: param header v3
+ * @param_data: param payload
+ * @total_size: total size of packed data (hdr + payload)
+ * @iid_supported: Instance ID supported or not
+ *
+ * Returns 0 on success or error on failure
+ */
+int q6common_pack_pp_params_v2(u8 *dest, struct param_hdr_v3 *v3_hdr,
+ u8 *param_data, u32 *total_size,
+ bool iid_supported)
+{
+ struct param_hdr_v1 *v1_hdr = NULL;
+ u32 packed_size = 0;
+ u32 param_size = 0;
+
+ if (dest == NULL) {
+ pr_err("%s: Received NULL pointer for destination\n", __func__);
+ return -EINVAL;
+ } else if (v3_hdr == NULL) {
+ pr_err("%s: Received NULL pointer for header\n", __func__);
+ return -EINVAL;
+ } else if (total_size == NULL) {
+ pr_err("%s: Received NULL pointer for total size\n", __func__);
+ return -EINVAL;
+ }
+
+ param_size = v3_hdr->param_size;
+ packed_size = iid_supported ? sizeof(struct param_hdr_v3) :
+ sizeof(struct param_hdr_v1);
+
+ if (iid_supported) {
+ memcpy(dest, v3_hdr, packed_size);
+ } else {
+ v1_hdr = (struct param_hdr_v1 *) dest;
+ v1_hdr->module_id = v3_hdr->module_id;
+ v1_hdr->param_id = v3_hdr->param_id;
+
+ if (param_size > U16_MAX) {
+ pr_err("%s: Invalid param size for V1 %d\n", __func__,
+ param_size);
+ return -EINVAL;
+ }
+ v1_hdr->param_size = param_size;
+ v1_hdr->reserved = 0;
+ }
+
+ /*
+ * Make param_data optional for cases when there is no data
+ * present as in some set cases and all get cases.
+ */
+ if (param_data != NULL) {
+ memcpy(dest + packed_size, param_data, param_size);
+ packed_size += param_size;
+ }
+
+ *total_size = packed_size;
+
+ return 0;
+}
+EXPORT_SYMBOL(q6common_pack_pp_params_v2);
diff --git a/dsp/q6voice.c b/dsp/q6voice.c
index e36e18b..131da55 100644
--- a/dsp/q6voice.c
+++ b/dsp/q6voice.c
@@ -98,7 +98,8 @@
static int voice_cvs_stop_playback(struct voice_data *v);
static int voice_cvs_start_playback(struct voice_data *v);
-static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode);
+static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode,
+ uint32_t port_id);
static int voice_cvs_stop_record(struct voice_data *v);
static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
@@ -4411,7 +4412,8 @@
/* Start in-call recording if this feature is enabled */
if (v->rec_info.rec_enable)
- voice_cvs_start_record(v, v->rec_info.rec_mode);
+ voice_cvs_start_record(v, v->rec_info.rec_mode,
+ v->rec_info.port_id);
if (v->dtmf_rx_detect_en)
voice_send_dtmf_rx_detection_cmd(v, v->dtmf_rx_detect_en);
@@ -5056,7 +5058,8 @@
if (v->rec_info.rec_enable) {
voice_cvs_start_record(
&common.voice[VOC_PATH_PASSIVE],
- v->rec_info.rec_mode);
+ v->rec_info.rec_mode,
+ v->rec_info.port_id);
common.srvcc_rec_flag = true;
pr_debug("%s: switch recording, srvcc_rec_flag %d\n",
@@ -5565,7 +5568,8 @@
return 0;
}
-static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
+static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode,
+ uint32_t port_id)
{
int ret = 0;
void *apr_cvs;
@@ -5616,6 +5620,18 @@
VSS_IRECORD_TAP_POINT_STREAM_END;
cvs_start_record.rec_mode.tx_tap_point =
VSS_IRECORD_TAP_POINT_STREAM_END;
+ if (common.rec_channel_count ==
+ NUM_CHANNELS_STEREO) {
+ /*
+ * if channel count is not stereo,
+ * then default port_id and mode
+ * (mono) will be used
+ */
+ cvs_start_record.rec_mode.mode =
+ VSS_IRECORD_MODE_TX_RX_STEREO;
+ cvs_start_record.rec_mode.port_id =
+ port_id;
+ }
} else {
pr_err("%s: Invalid in-call rec_mode %d\n", __func__,
rec_mode);
@@ -5774,6 +5790,7 @@
mutex_lock(&v->lock);
rec_mode = v->rec_info.rec_mode;
+ v->rec_info.port_id = port_id;
rec_set = set;
if (set) {
if ((v->rec_route_state.ul_flag != 0) &&
@@ -5850,7 +5867,8 @@
if (cvs_handle != 0) {
if (rec_set)
- ret = voice_cvs_start_record(v, rec_mode);
+ ret = voice_cvs_start_record(v, rec_mode,
+ port_id);
else
ret = voice_cvs_stop_record(v);
}
@@ -6148,6 +6166,31 @@
}
EXPORT_SYMBOL(voc_disable_topology);
+/**
+ * voc_set_incall_capture_channel_config -
+ * command to set channel count for record
+ *
+ * @channel_count: number of channels
+ *
+ */
+void voc_set_incall_capture_channel_config(int channel_count)
+{
+ common.rec_channel_count = channel_count;
+}
+EXPORT_SYMBOL(voc_set_incall_capture_channel_config);
+
+/**
+ * voc_get_incall_capture_channel_config -
+ * command to get channel count for record
+ *
+ * Returns number of channels configured for record
+ */
+int voc_get_incall_capture_channel_config(void)
+{
+ return common.rec_channel_count;
+}
+EXPORT_SYMBOL(voc_get_incall_capture_channel_config);
+
static int voice_set_packet_exchange_mode_and_config(uint32_t session_id,
uint32_t mode)
{
@@ -9907,6 +9950,12 @@
/* Initialize Per-Vocoder Calibration flag */
common.is_per_vocoder_cal_enabled = false;
+ /*
+ * Initialize in call record channel config
+ * to mono
+ */
+ common.rec_channel_count = NUM_CHANNELS_MONO;
+
mutex_init(&common.common_lock);
common.uevent_data = kzalloc(sizeof(*(common.uevent_data)), GFP_KERNEL);
diff --git a/include/asoc/core.h b/include/asoc/core.h
index e4f0413..c6e544e 100644
--- a/include/asoc/core.h
+++ b/include/asoc/core.h
@@ -10,6 +10,7 @@
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/pm_qos.h>
+#include "pdata.h"
#define WCD9XXX_MAX_IRQ_REGS 4
#define WCD9XXX_MAX_NUM_IRQS (WCD9XXX_MAX_IRQ_REGS * 8)
@@ -394,6 +395,11 @@
struct wcd9xxx_reg_val *bulk_reg,
unsigned int size, bool interface);
+int wcd9xxx_vote_ondemand_regulator(struct wcd9xxx *wcd9xxx,
+ struct wcd9xxx_pdata *pdata,
+ const char *supply_name,
+ bool enable);
+
extern int wcd9xxx_core_res_init(
struct wcd9xxx_core_resource *wcd9xxx_core_res,
int num_irqs, int num_irq_regs, struct regmap *wcd_regmap);
diff --git a/include/asoc/msm-cdc-supply.h b/include/asoc/msm-cdc-supply.h
index 9801115..c6aacf6 100644
--- a/include/asoc/msm-cdc-supply.h
+++ b/include/asoc/msm-cdc-supply.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016, 2018-2019 The Linux Foundation. All rights reserved.
*/
#ifndef __CODEC_POWER_SUPPLY_H__
@@ -45,4 +45,9 @@
struct regulator_bulk_data **supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies);
+extern int msm_cdc_init_supplies_v2(struct device *dev,
+ struct regulator_bulk_data **supplies,
+ struct cdc_regulator *cdc_vreg,
+ int num_supplies,
+ u32 vote_regulator_on_demand);
#endif
diff --git a/include/asoc/pdata.h b/include/asoc/pdata.h
index d24d56a..41862d4 100644
--- a/include/asoc/pdata.h
+++ b/include/asoc/pdata.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __MFD_WCD9XXX_PDATA_H__
@@ -193,6 +193,7 @@
u32 ecpp_dmic_sample_rate;
u32 dmic_clk_drv;
u16 use_pinctrl;
+ u32 vote_regulator_on_demand;
};
#endif
diff --git a/include/asoc/wcd-mbhc-v2.h b/include/asoc/wcd-mbhc-v2.h
index c98cdda..9341e3d 100644
--- a/include/asoc/wcd-mbhc-v2.h
+++ b/include/asoc/wcd-mbhc-v2.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __WCD_MBHC_V2_H__
#define __WCD_MBHC_V2_H__
@@ -540,6 +540,7 @@
bool gnd_swh; /*track GND switch NC / NO */
u32 hs_thr;
u32 hph_thr;
+ u32 micb_mv;
u32 swap_thr;
u32 moist_vref;
u32 moist_iref;
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index e7c132a..8bff499 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -874,11 +874,14 @@
*/
} __packed;
+/* Maximum number of channels supported by MFC media fmt params */
+#define AUDPROC_MFC_OUT_CHANNELS_MAX 8
+
struct audproc_mfc_param_media_fmt {
uint32_t sampling_rate;
uint16_t bits_per_sample;
uint16_t num_channels;
- uint16_t channel_type[8];
+ uint16_t channel_type[AUDPROC_MFC_OUT_CHANNELS_MAX];
} __packed;
struct audproc_volume_ctrl_master_gain {
diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h
index 70dc2d0..a48082b 100644
--- a/include/dsp/q6adm-v2.h
+++ b/include/dsp/q6adm-v2.h
@@ -145,6 +145,8 @@
int adm_get_multi_ch_map(char *channel_map, int path);
+void adm_set_port_multi_ch_map(char *channel_map, int port_id);
+
int adm_validate_and_get_port_index(int port_id);
int adm_get_default_copp_idx(int port_id);
diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h
index 1efcb50..4a5f39a 100644
--- a/include/dsp/q6afe-v2.h
+++ b/include/dsp/q6afe-v2.h
@@ -43,6 +43,9 @@
#define AFE_API_VERSION_V3 3
/* for VAD and Island mode */
#define AFE_API_VERSION_V4 4
+/* for VAD enable */
+#define AFE_API_VERSION_V6 6
+
typedef int (*routing_cb)(int port);
@@ -452,6 +455,7 @@
u16 port_id);
int afe_cal_init_hwdep(void *card);
int afe_send_port_island_mode(u16 port_id);
+int afe_send_port_vad_cfg_params(u16 port_id);
int afe_send_cmd_wakeup_register(void *handle, bool enable);
void afe_register_wakeup_irq_callback(
void (*afe_cb_wakeup_irq)(void *handle));
diff --git a/include/dsp/q6common.h b/include/dsp/q6common.h
index c21ac5c..7250a13 100644
--- a/include/dsp/q6common.h
+++ b/include/dsp/q6common.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __Q6COMMON_H__
@@ -12,5 +12,7 @@
bool q6common_is_instance_id_supported(void);
int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr,
u8 *param_data, u32 *total_size);
-
+int q6common_pack_pp_params_v2(u8 *dest, struct param_hdr_v3 *v3_hdr,
+ u8 *param_data, u32 *total_size,
+ bool iid_supported);
#endif /* __Q6COMMON_H__ */
diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h
index 1e62124..06f4dfe 100644
--- a/include/dsp/q6voice.h
+++ b/include/dsp/q6voice.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __QDSP6VOICE_H__
#define __QDSP6VOICE_H__
@@ -1768,6 +1768,7 @@
uint32_t rec_enable;
uint32_t rec_mode;
uint32_t recording;
+ uint32_t port_id;
};
struct incall_music_info {
@@ -1946,6 +1947,7 @@
bool sidetone_enable;
bool mic_break_enable;
struct audio_uevent_data *uevent_data;
+ int32_t rec_channel_count;
};
struct voice_session_itr {
@@ -2079,6 +2081,8 @@
int voc_set_device_config(uint32_t session_id, uint8_t path_dir,
struct media_format_info *finfo);
uint32_t voice_get_topology(uint32_t topology_idx);
+void voc_set_incall_capture_channel_config(int channel_count);
+int voc_get_incall_capture_channel_config(void);
int voice_set_topology_specific_info(struct voice_data *v,
uint32_t topology_idx);
int voc_set_sound_focus(struct sound_focus_param sound_focus_param);
diff --git a/ipc/Kbuild b/ipc/Kbuild
index 2da5fbd..fb0974e 100644
--- a/ipc/Kbuild
+++ b/ipc/Kbuild
@@ -27,7 +27,6 @@
endif
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
- export
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/soc/Android.mk b/soc/Android.mk
index 0698221..0bd7403 100644
--- a/soc/Android.mk
+++ b/soc/Android.mk
@@ -58,6 +58,7 @@
include $(DLKM_DIR)/AndroidKernelModule.mk
endif
###########################################################
+ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona), true)
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_wcd.ko
LOCAL_MODULE_KBUILD_NAME := pinctrl_wcd_dlkm.ko
@@ -65,6 +66,7 @@
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
+endif
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_swr.ko
diff --git a/soc/Kbuild b/soc/Kbuild
index f5f5c8b..a1944a1 100644
--- a/soc/Kbuild
+++ b/soc/Kbuild
@@ -21,7 +21,6 @@
endif
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
- export
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c
index 3db2210..4eee086 100644
--- a/soc/pinctrl-lpi.c
+++ b/soc/pinctrl-lpi.c
@@ -110,6 +110,7 @@
char __iomem *base;
struct clk *lpass_core_hw_vote;
struct mutex slew_access_lock;
+ bool core_hw_vote_status;
};
static const char *const lpi_gpio_groups[] = {
@@ -710,6 +711,7 @@
}
state->lpass_core_hw_vote = lpass_core_hw_vote;
+ state->core_hw_vote_status = false;
pm_runtime_set_autosuspend_delay(&pdev->dev, LPI_AUTO_SUSPEND_DELAY);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
@@ -760,10 +762,12 @@
}
ret = clk_prepare_enable(state->lpass_core_hw_vote);
- if (ret < 0) {
+ if (ret < 0)
dev_err(dev, "%s:lpass core hw island enable failed\n",
__func__);
- }
+ else
+ state->core_hw_vote_status = true;
+
pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY);
return 0;
}
@@ -776,7 +780,11 @@
dev_dbg(dev, "%s: Invalid core hw node\n", __func__);
return 0;
}
- clk_disable_unprepare(state->lpass_core_hw_vote);
+
+ if (state->core_hw_vote_status) {
+ clk_disable_unprepare(state->lpass_core_hw_vote);
+ state->core_hw_vote_status = false;
+ }
return 0;
}
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index bddf30a..c9cccf6 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -241,8 +241,10 @@
mutex_lock(&swrm->clklock);
if (enable) {
- if (!swrm->dev_up)
+ if (!swrm->dev_up) {
+ ret = -ENODEV;
goto exit;
+ }
swrm->clk_ref_count++;
if (swrm->clk_ref_count == 1) {
ret = swrm->clk(swrm->handle, true);
@@ -1274,7 +1276,10 @@
}
mutex_lock(&swrm->reslock);
- swrm_clk_request(swrm, true);
+ if (swrm_clk_request(swrm, true)) {
+ mutex_unlock(&swrm->reslock);
+ goto exit;
+ }
mutex_unlock(&swrm->reslock);
intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS);
@@ -1420,6 +1425,7 @@
mutex_lock(&swrm->reslock);
swrm_clk_request(swrm, false);
mutex_unlock(&swrm->reslock);
+exit:
swrm_unlock_sleep(swrm);
return ret;
}
@@ -2293,7 +2299,12 @@
enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL);
list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
ret = swr_device_up(swr_dev);
- if (ret) {
+ if (ret == -ENODEV) {
+ dev_dbg(dev,
+ "%s slave device up not implemented\n",
+ __func__);
+ ret = 0;
+ } else if (ret) {
dev_err(dev,
"%s: failed to wakeup swr dev %d\n",
__func__, swr_dev->dev_num);
@@ -2358,7 +2369,12 @@
swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00);
list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
ret = swr_device_down(swr_dev);
- if (ret) {
+ if (ret == -ENODEV) {
+ dev_dbg_ratelimited(dev,
+ "%s slave device down not implemented\n",
+ __func__);
+ ret = 0;
+ } else if (ret) {
dev_err(dev,
"%s: failed to shutdown swr dev %d\n",
__func__, swr_dev->dev_num);