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;