summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;