summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkata Narendra Kumar Gutta <vgutta@codeaurora.org>2015-12-14 12:33:19 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:23:30 -0700
commit8e51c8ce31f462c5c28bff61c8dfe3ea169c0eac (patch)
tree57631d15aa8e20b6777d5f6e0bc8ef7aa7abc9f1
parente066a36f4152c801113f8ed28e3ba6c894cdb693 (diff)
ASoC: msm: Add support for HW MAD bypass feature for listen
HW MAD bypass feature is to facilitate input to CPE by avoiding MAD in codec. This is done by routing DEC1 data to CPE. Add the required changes to support this feature. CRs-fixed: 938514 Change-Id: I7788b1475cd22bdea291bcae47f048131b220ce3 Signed-off-by: Venkata Narendra Kumar Gutta <vgutta@codeaurora.org>
-rw-r--r--include/sound/cpe_core.h3
-rwxr-xr-xsound/soc/codecs/wcd9335.c55
-rw-r--r--sound/soc/codecs/wcd_cpe_core.c4
-rw-r--r--sound/soc/msm/msm-cpe-lsm.c29
4 files changed, 87 insertions, 4 deletions
diff --git a/include/sound/cpe_core.h b/include/sound/cpe_core.h
index 3e38a27212a5..289ed1df34f5 100644
--- a/include/sound/cpe_core.h
+++ b/include/sound/cpe_core.h
@@ -81,7 +81,8 @@ struct cpe_lsm_session {
struct wcd_cpe_afe_ops {
int (*afe_set_params) (void *core_handle,
- struct wcd_cpe_afe_port_cfg *cfg);
+ struct wcd_cpe_afe_port_cfg *cfg,
+ bool afe_mad_ctl);
int (*afe_port_start) (void *core_handle,
struct wcd_cpe_afe_port_cfg *cfg);
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index 82540aa647fa..ed4e2612e793 100755
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -2565,6 +2565,9 @@ static const struct snd_kcontrol_new aif4_mad_mixer[] = {
slim_tx_mixer_get, slim_tx_mixer_put),
SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, 0, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+
};
static const struct snd_kcontrol_new rx_int1_spline_mix_switch[] = {
@@ -2619,6 +2622,11 @@ static const struct snd_kcontrol_new rx_int8_vbat_mix_switch[] = {
SOC_DAPM_SINGLE("SPKRR VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
};
+static const struct snd_kcontrol_new cpe_in_mix_switch[] = {
+ SOC_DAPM_SINGLE("MAD_BYPASS", SND_SOC_NOPM, 0, 1, 0)
+};
+
+
static int tasha_put_iir_enable_audio_mixer(
struct snd_kcontrol *kcontrol,
@@ -5811,6 +5819,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"MAD_BROADCAST", "Switch", "MAD_SEL MUX"},
{"TX13 INP MUX", "CPE_TX_PP", "MADONOFF"},
+ /* CPE HW MAD bypass */
+ {"CPE IN Mixer", "MAD_BYPASS", "SLIM TX1 MUX"},
+
+ {"AIF4_MAD Mixer", "SLIM TX1", "CPE IN Mixer"},
{"AIF4_MAD Mixer", "SLIM TX12", "MADONOFF"},
{"AIF4_MAD Mixer", "SLIM TX13", "TX13 INP MUX"},
{"AIF4 MAD", NULL, "AIF4_MAD Mixer"},
@@ -8244,6 +8256,11 @@ static int tasha_codec_enable_mad(struct snd_soc_dapm_widget *w,
dev_dbg(codec->dev,
"%s: event = %d\n", __func__, event);
+
+ /* Return if CPE INPUT is DEC1 */
+ if (snd_soc_read(codec, WCD9335_CPE_SS_SVA_CFG) & 0x01)
+ return ret;
+
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -8273,6 +8290,39 @@ static int tasha_codec_enable_mad(struct snd_soc_dapm_widget *w,
return ret;
}
+static int tasha_codec_configure_cpe_input(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ dev_dbg(codec->dev,
+ "%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Configure CPE input as DEC1 */
+ snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG,
+ 0x01, 0x01);
+
+ /* Configure DEC1 Tx out with sample rate as 16K */
+ snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL,
+ 0x0F, 0x01);
+
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* Reset DEC1 Tx out sample rate */
+ snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL,
+ 0x0F, 0x04);
+ snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG,
+ 0x01, 0x00);
+
+ break;
+ }
+
+ return 0;
+}
+
+
static int tasha_codec_aif4_mixer_switch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -10063,6 +10113,11 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
4, 0, NULL, 0),
SND_SOC_DAPM_MIXER("SRC1", WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL,
4, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER_E("CPE IN Mixer", SND_SOC_NOPM, 0, 0,
+ cpe_in_mix_switch,
+ ARRAY_SIZE(cpe_in_mix_switch),
+ tasha_codec_configure_cpe_input,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MUX("RX MIX TX0 MUX", SND_SOC_NOPM, 0, 0,
&rx_mix_tx0_mux),
diff --git a/sound/soc/codecs/wcd_cpe_core.c b/sound/soc/codecs/wcd_cpe_core.c
index ac1b613248fd..7b41afc2bdae 100644
--- a/sound/soc/codecs/wcd_cpe_core.c
+++ b/sound/soc/codecs/wcd_cpe_core.c
@@ -4319,7 +4319,7 @@ done:
* parameters are to be set
*/
static int wcd_cpe_afe_set_params(void *core_handle,
- struct wcd_cpe_afe_port_cfg *afe_cfg)
+ struct wcd_cpe_afe_port_cfg *afe_cfg, bool afe_mad_ctl)
{
struct cpe_afe_params afe_params;
struct cpe_afe_hw_mad_ctrl *hw_mad_ctrl = &afe_params.hw_mad_ctrl;
@@ -4362,7 +4362,7 @@ static int wcd_cpe_afe_set_params(void *core_handle,
hw_mad_ctrl->param.p_size.sr.reserved = 0;
hw_mad_ctrl->minor_version = 1;
hw_mad_ctrl->mad_type = MAD_TYPE_AUDIO;
- hw_mad_ctrl->mad_enable = 1;
+ hw_mad_ctrl->mad_enable = afe_mad_ctl;
port_cfg->param.module_id = CPE_AFE_MODULE_AUDIO_DEV_INTERFACE;
port_cfg->param.param_id = CPE_AFE_PARAM_ID_GENERIC_PORT_CONFIG;
diff --git a/sound/soc/msm/msm-cpe-lsm.c b/sound/soc/msm/msm-cpe-lsm.c
index 8548841674da..a509107ea9f2 100644
--- a/sound/soc/msm/msm-cpe-lsm.c
+++ b/sound/soc/msm/msm-cpe-lsm.c
@@ -134,6 +134,7 @@ struct cpe_priv {
struct snd_soc_codec *codec;
struct wcd_cpe_lsm_ops lsm_ops;
struct wcd_cpe_afe_ops afe_ops;
+ bool afe_mad_ctl;
};
struct cpe_lsm_data {
@@ -155,6 +156,29 @@ struct cpe_lsm_data {
bool cpe_prepared;
};
+static int msm_cpe_afe_mad_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct cpe_priv *cpe = kcontrol->private_data;
+
+ ucontrol->value.integer.value[0] = cpe->afe_mad_ctl;
+ return 0;
+}
+
+static int msm_cpe_afe_mad_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct cpe_priv *cpe = kcontrol->private_data;
+
+ cpe->afe_mad_ctl = ucontrol->value.integer.value[0];
+ return 0;
+}
+
+static struct snd_kcontrol_new msm_cpe_kcontrols[] = {
+ SOC_SINGLE_EXT("CPE AFE MAD Enable", SND_SOC_NOPM, 0, 1, 0,
+ msm_cpe_afe_mad_ctl_get, msm_cpe_afe_mad_ctl_put),
+};
+
/*
* cpe_get_private_data: obtain ASoC platform driver private data
* @substream: ASoC substream for which private data to be obtained
@@ -2697,7 +2721,7 @@ static int msm_cpe_lsm_prepare(struct snd_pcm_substream *substream)
afe_cfg->sample_rate = 16000;
rc = afe_ops->afe_set_params(cpe->core_handle,
- afe_cfg);
+ afe_cfg, cpe->afe_mad_ctl);
if (rc != 0) {
dev_err(rtd->dev,
"%s: cpe afe params failed, err = %d\n",
@@ -2952,6 +2976,7 @@ static int msm_asoc_cpe_lsm_probe(struct snd_soc_platform *platform)
struct snd_soc_pcm_runtime *rtd;
struct snd_soc_codec *codec;
struct cpe_priv *cpe_priv;
+ const struct snd_kcontrol_new *kcontrol;
bool found_runtime = false;
int i;
@@ -2998,6 +3023,8 @@ static int msm_asoc_cpe_lsm_probe(struct snd_soc_platform *platform)
wcd_cpe_get_afe_ops(&cpe_priv->afe_ops);
snd_soc_platform_set_drvdata(platform, cpe_priv);
+ kcontrol = &msm_cpe_kcontrols[0];
+ snd_ctl_add(card->snd_card, snd_ctl_new1(kcontrol, cpe_priv));
return 0;
}