summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
authorHelen Zeng <xiaoyunz@codeaurora.org>2015-07-16 15:52:13 -0700
committerKyle Yan <kyan@codeaurora.org>2016-06-27 19:53:05 -0700
commit4102eee9c4db1f7071fb1210c7ba8bebfb1edca3 (patch)
treeee7481d9f7d59048464df9e5eabd3ac02fb6c560 /sound/soc
parentaaf93b3e623faeb653f11c124e47cc458c8bb01f (diff)
ASoC: msm: qdsp6v2: Support host pcm feature based on new VSIDs
With single voice architecture, two new VSIDs are created to support multimode voice call. Update host pcm driver to support new VSIDs. Change-Id: I42e33db7f3dca47c30b7dc5af59848eb6beef330 Signed-off-by: Helen Zeng <xiaoyunz@codeaurora.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c160
-rw-r--r--sound/soc/msm/qdsp6v2/q6voice.h2
2 files changed, 155 insertions, 7 deletions
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c
index 48f4a2456c84..b02ab78684fb 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -45,6 +45,17 @@
#define VOLTE_RX_CAPTURE_DAI_ID "VOLTE HOST RX CAPTURE"
#define VOLTE_RX_PLAYBACK_DAI_ID "VOLTE HOST RX PLAYBACK"
+
+#define VoMMode1_TX_CAPTURE_DAI_ID "VoiceMMode1 HOST TX CAPTURE"
+#define VoMMode1_TX_PLAYBACK_DAI_ID "VoiceMMode1 HOST TX PLAYBACK"
+#define VoMMode1_RX_CAPTURE_DAI_ID "VoiceMMode1 HOST RX CAPTURE"
+#define VoMMode1_RX_PLAYBACK_DAI_ID "VoiceMMode1 HOST RX PLAYBACK"
+
+#define VoMMode2_TX_CAPTURE_DAI_ID "VoiceMMode2 HOST TX CAPTURE"
+#define VoMMode2_TX_PLAYBACK_DAI_ID "VoiceMMode2 HOST TX PLAYBACK"
+#define VoMMode2_RX_CAPTURE_DAI_ID "VoiceMMode2 HOST RX CAPTURE"
+#define VoMMode2_RX_PLAYBACK_DAI_ID "VoiceMMode2 HOST RX PLAYBACK"
+
enum {
RX = 1,
TX,
@@ -53,6 +64,8 @@ enum {
enum {
VOICE_INDEX = 0,
VOLTE_INDEX,
+ VOMMODE1_INDEX,
+ VOMMODE2_INDEX,
MAX_SESSION
};
@@ -166,6 +179,10 @@ static char *hpcm_get_sess_name(int sess_indx)
sess_name = VOICE_SESSION_NAME;
else if (sess_indx == VOLTE_INDEX)
sess_name = VOLTE_SESSION_NAME;
+ else if (sess_indx == VOMMODE1_INDEX)
+ sess_name = VOICEMMODE1_NAME;
+ else if (sess_indx == VOMMODE2_INDEX)
+ sess_name = VOICEMMODE2_NAME;
else
pr_err("%s:, Invalid sess_index\n", __func__);
@@ -188,7 +205,7 @@ static void hpcm_reset_mixer_config(struct hpcm_drv *prtd)
static bool hpcm_is_valid_config(int sess_indx, int tap_point,
uint16_t direction, uint16_t samplerate)
{
- if (sess_indx < VOICE_INDEX || sess_indx > VOLTE_INDEX) {
+ if (sess_indx < VOICE_INDEX || sess_indx > VOMMODE2_INDEX) {
pr_err("%s: invalid sess_indx :%d\n", __func__, sess_indx);
goto error;
}
@@ -251,6 +268,33 @@ static struct dai_data *hpcm_get_dai_data(char *pcm_id, struct hpcm_drv *prtd)
} else if (strnstr(pcm_id, VOLTE_RX_PLAYBACK_DAI_ID, size)) {
dai_data =
&prtd->session[VOLTE_INDEX].rx_tap_point.playback_dai_data;
+ /* check for VoiceMMode1 DAI */
+ } else if (strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, size)) {
+ dai_data =
+ &prtd->session[VOMMODE1_INDEX].tx_tap_point.capture_dai_data;
+ } else if (strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, size)) {
+ dai_data =
+ &prtd->session[VOMMODE1_INDEX].tx_tap_point.playback_dai_data;
+ } else if (strnstr(pcm_id, VoMMode1_RX_CAPTURE_DAI_ID, size)) {
+ dai_data =
+ &prtd->session[VOMMODE1_INDEX].rx_tap_point.capture_dai_data;
+ } else if (strnstr(pcm_id, VoMMode1_RX_PLAYBACK_DAI_ID, size)) {
+ dai_data =
+ &prtd->session[VOMMODE1_INDEX].rx_tap_point.playback_dai_data;
+ /* check for VOiceMMode2 DAI */
+ } else if (strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, size)) {
+ dai_data =
+ &prtd->session[VOMMODE2_INDEX].tx_tap_point.capture_dai_data;
+ } else if (strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, size)) {
+ dai_data =
+ &prtd->session[VOMMODE2_INDEX].tx_tap_point.playback_dai_data;
+ } else if (strnstr(pcm_id, VoMMode2_RX_CAPTURE_DAI_ID, size)) {
+ dai_data =
+ &prtd->session[VOMMODE2_INDEX].rx_tap_point.capture_dai_data;
+ } else if (strnstr(pcm_id, VoMMode2_RX_PLAYBACK_DAI_ID, size)) {
+ dai_data =
+ &prtd->session[VOMMODE2_INDEX].rx_tap_point.playback_dai_data;
+
} else {
pr_err("%s: Wrong dai id\n", __func__);
}
@@ -285,6 +329,24 @@ static struct tap_point *hpcm_get_tappoint_data(char *pcm_id,
tp = &prtd->session[VOLTE_INDEX].rx_tap_point;
} else if (strnstr(pcm_id, VOLTE_RX_PLAYBACK_DAI_ID, size)) {
tp = &prtd->session[VOLTE_INDEX].rx_tap_point;
+ /* check for VoiceMMode1 */
+ } else if (strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, size)) {
+ tp = &prtd->session[VOMMODE1_INDEX].tx_tap_point;
+ } else if (strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, size)) {
+ tp = &prtd->session[VOMMODE1_INDEX].tx_tap_point;
+ } else if (strnstr(pcm_id, VoMMode1_RX_CAPTURE_DAI_ID, size)) {
+ tp = &prtd->session[VOMMODE1_INDEX].rx_tap_point;
+ } else if (strnstr(pcm_id, VoMMode1_RX_PLAYBACK_DAI_ID, size)) {
+ tp = &prtd->session[VOMMODE1_INDEX].rx_tap_point;
+ /* check for VoiceMMode2 */
+ } else if (strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, size)) {
+ tp = &prtd->session[VOMMODE2_INDEX].tx_tap_point;
+ } else if (strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, size)) {
+ tp = &prtd->session[VOMMODE2_INDEX].tx_tap_point;
+ } else if (strnstr(pcm_id, VoMMode2_RX_CAPTURE_DAI_ID, size)) {
+ tp = &prtd->session[VOMMODE2_INDEX].rx_tap_point;
+ } else if (strnstr(pcm_id, VoMMode2_RX_PLAYBACK_DAI_ID, size)) {
+ tp = &prtd->session[VOMMODE2_INDEX].rx_tap_point;
} else {
pr_err("%s: wrong dai id\n", __func__);
}
@@ -300,7 +362,11 @@ static struct tappnt_mxr_data *hpcm_get_tappnt_mixer_data(char *pcm_id,
if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
- strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, strlen(pcm_id))) {
+ strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
+ strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
+ strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
+ strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
+ strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, strlen(pcm_id))) {
return &prtd->mixer_conf.tx;
} else {
return &prtd->mixer_conf.rx;
@@ -313,7 +379,11 @@ static int get_tappnt_value(char *pcm_id)
if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
- strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, strlen(pcm_id))) {
+ strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
+ strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
+ strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
+ strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
+ strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, strlen(pcm_id))) {
return TX;
} else {
return RX;
@@ -793,6 +863,78 @@ done:
return ret;
}
+static int msm_hpcm_configure_vmmode1_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ int tap_point = ucontrol->value.integer.value[0];
+ uint16_t direction = ucontrol->value.integer.value[1];
+ uint16_t sample_rate = ucontrol->value.integer.value[2];
+ struct tappnt_mxr_data *tmd = NULL;
+ int ret = 0;
+
+ mutex_lock(&hpcm_drv.lock);
+ pr_debug("%s: tap_point = %d direction = %d sample_rate = %d\n",
+ __func__, tap_point, direction, sample_rate);
+
+ if (!hpcm_is_valid_config(VOMMODE1_INDEX, tap_point, direction,
+ sample_rate)) {
+ pr_err("Invalid vpcm mixer control voice values\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (tap_point == RX)
+ tmd = &hpcm_drv.mixer_conf.rx;
+ else
+ tmd = &hpcm_drv.mixer_conf.tx;
+
+ tmd->enable = true;
+ tmd->direction = direction;
+ tmd->sample_rate = sample_rate;
+ hpcm_drv.mixer_conf.sess_indx = VOMMODE1_INDEX;
+
+done:
+ mutex_unlock(&hpcm_drv.lock);
+ return ret;
+}
+
+static int msm_hpcm_configure_vmmode2_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ int tap_point = ucontrol->value.integer.value[0];
+ uint16_t direction = ucontrol->value.integer.value[1];
+ uint16_t sample_rate = ucontrol->value.integer.value[2];
+ struct tappnt_mxr_data *tmd = NULL;
+ int ret = 0;
+
+ mutex_lock(&hpcm_drv.lock);
+ pr_debug("%s: tap_point = %d direction = %d sample_rate = %d\n",
+ __func__, tap_point, direction, sample_rate);
+
+ if (!hpcm_is_valid_config(VOMMODE2_INDEX, tap_point, direction,
+ sample_rate)) {
+ pr_err("Invalid vpcm mixer control voice values\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (tap_point == RX)
+ tmd = &hpcm_drv.mixer_conf.rx;
+ else
+ tmd = &hpcm_drv.mixer_conf.tx;
+
+ tmd->enable = true;
+ tmd->direction = direction;
+ tmd->sample_rate = sample_rate;
+ hpcm_drv.mixer_conf.sess_indx = VOMMODE2_INDEX;
+
+done:
+ mutex_unlock(&hpcm_drv.lock);
+ return ret;
+}
+
static int msm_hpcm_configure_volte_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -832,11 +974,17 @@ done:
static struct snd_kcontrol_new msm_hpcm_controls[] = {
SOC_SINGLE_MULTI_EXT("HPCM_Voice tappoint direction samplerate",
- SND_SOC_NOPM, 0, 16000 , 0, 3,
+ SND_SOC_NOPM, 0, 16000, 0, 3,
NULL, msm_hpcm_configure_voice_put),
SOC_SINGLE_MULTI_EXT("HPCM_VoLTE tappoint direction samplerate",
- SND_SOC_NOPM, 0, 16000 , 0, 3,
+ SND_SOC_NOPM, 0, 16000, 0, 3,
NULL, msm_hpcm_configure_volte_put),
+ SOC_SINGLE_MULTI_EXT("HPCM_VMMode1 tappoint direction samplerate",
+ SND_SOC_NOPM, 0, 16000, 0, 3,
+ NULL, msm_hpcm_configure_vmmode1_put),
+ SOC_SINGLE_MULTI_EXT("HPCM_VMMode2 tappoint direction samplerate",
+ SND_SOC_NOPM, 0, 16000, 0, 3,
+ NULL, msm_hpcm_configure_vmmode2_put),
};
/* Sample rates supported */
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index f6349be64942..d230bf097eb9 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -1280,7 +1280,7 @@ struct vss_ivocproc_cmd_topology_set_dev_channels_t {
#define VSS_IVPCM_SAMPLING_RATE_16K 16000
/* RX and TX */
-#define MAX_TAP_POINTS_SUPPORTED 1
+#define MAX_TAP_POINTS_SUPPORTED 2
struct vss_ivpcm_tap_point {
uint32_t tap_point;