ASoC: msm: Add slowtalk support
Signed-off-by: Helen Zeng <xiaoyunz@codeaurora.org>
diff --git a/sound/soc/msm/msm-pcm-voice.c b/sound/soc/msm/msm-pcm-voice.c
index c22266e..5b50509 100644
--- a/sound/soc/msm/msm-pcm-voice.c
+++ b/sound/soc/msm/msm-pcm-voice.c
@@ -262,6 +262,28 @@
return 0;
}
+
+static int msm_voice_slowtalk_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int st_enable = ucontrol->value.integer.value[0];
+
+ pr_debug("%s: st enable=%d\n", __func__, st_enable);
+
+ voc_set_slowtalk_enable(voc_get_session_id(VOICE_SESSION_NAME),
+ st_enable);
+
+ return 0;
+}
+
+static int msm_voice_slowtalk_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] =
+ voc_get_slowtalk_enable(voc_get_session_id(VOICE_SESSION_NAME));
+ return 0;
+}
+
static struct snd_kcontrol_new msm_voice_controls[] = {
SOC_SINGLE_EXT("Voice Tx Mute", SND_SOC_NOPM, 0, 1, 0,
msm_voice_mute_get, msm_voice_mute_put),
@@ -271,6 +293,8 @@
msm_voice_tty_mode_put),
SOC_SINGLE_EXT("Widevoice Enable", SND_SOC_NOPM, 0, 1, 0,
msm_voice_widevoice_get, msm_voice_widevoice_put),
+ SOC_SINGLE_EXT("Slowtalk Enable", SND_SOC_NOPM, 0, 1, 0,
+ msm_voice_slowtalk_get, msm_voice_slowtalk_put),
};
static struct snd_pcm_ops msm_pcm_ops = {
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index 2a5afcc..d81e5fa 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -52,6 +52,7 @@
static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v);
static int voice_send_cvp_deregister_vol_cal_table_cmd(struct voice_data *v);
static int voice_send_set_widevoice_enable_cmd(struct voice_data *v);
+static int voice_send_set_slowtalk_enable_cmd(struct voice_data *v);
static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
@@ -1754,6 +1755,60 @@
return -EINVAL;
}
+static int voice_send_set_slowtalk_enable_cmd(struct voice_data *v)
+{
+ struct cvs_set_slowtalk_enable_cmd cvs_set_st_cmd;
+ int ret = 0;
+ void *apr_cvs;
+ u16 cvs_handle;
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+ return -EINVAL;
+ }
+ apr_cvs = common.apr_q6_cvs;
+
+ if (!apr_cvs) {
+ pr_err("%s: apr_cvs is NULL.\n", __func__);
+ return -EINVAL;
+ }
+ cvs_handle = voice_get_cvs_handle(v);
+
+ /* fill in the header */
+ cvs_set_st_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ cvs_set_st_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvs_set_st_cmd) - APR_HDR_SIZE);
+ cvs_set_st_cmd.hdr.src_port = v->session_id;
+ cvs_set_st_cmd.hdr.dest_port = cvs_handle;
+ cvs_set_st_cmd.hdr.token = 0;
+ cvs_set_st_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
+
+ cvs_set_st_cmd.vss_set_st.module_id = MODULE_ID_VOICE_MODULE_ST;
+ cvs_set_st_cmd.vss_set_st.param_id = VOICE_PARAM_MOD_ENABLE;
+ cvs_set_st_cmd.vss_set_st.param_size = MOD_ENABLE_PARAM_LEN;
+ cvs_set_st_cmd.vss_set_st.reserved = 0;
+ cvs_set_st_cmd.vss_set_st.enable = v->st_enable;
+ cvs_set_st_cmd.vss_set_st.reserved_field = 0;
+
+ v->cvs_state = CMD_STATUS_FAIL;
+ ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_st_cmd);
+ if (ret < 0) {
+ pr_err("Fail: sending cvs set slowtalk enable,\n");
+ goto fail;
+ }
+ ret = wait_event_timeout(v->cvs_wait,
+ (v->cvs_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ goto fail;
+ }
+ return 0;
+fail:
+ return -EINVAL;
+}
+
static int voice_setup_vocproc(struct voice_data *v)
{
struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
@@ -1852,6 +1907,10 @@
if (v->wv_enable)
voice_send_set_widevoice_enable_cmd(v);
+ /* enable slowtalk if st_enable is set */
+ if (v->st_enable)
+ voice_send_set_slowtalk_enable_cmd(v);
+
if (is_voip_session(v->session_id))
voice_send_netid_timing_cmd(v);
@@ -2333,6 +2392,10 @@
if (v->wv_enable)
voice_send_set_widevoice_enable_cmd(v);
+ /* enable slowtalk */
+ if (v->st_enable)
+ voice_send_set_slowtalk_enable_cmd(v);
+
get_sidetone_cal(&sidetone_cal_data);
ret = afe_sidetone(v->dev_tx.port_id, v->dev_rx.port_id,
sidetone_cal_data.enable,
@@ -2456,6 +2519,49 @@
return ret;
}
+int voc_set_slowtalk_enable(uint16_t session_id, uint32_t st_enable)
+{
+ struct voice_data *v = voice_get_session(session_id);
+ int ret = 0;
+
+ if (v == NULL) {
+ pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+ return -EINVAL;
+ }
+
+ mutex_lock(&v->lock);
+
+ v->st_enable = st_enable;
+
+ if (v->voc_state == VOC_RUN)
+ ret = voice_send_set_slowtalk_enable_cmd(v);
+
+ mutex_unlock(&v->lock);
+
+ return ret;
+}
+
+uint32_t voc_get_slowtalk_enable(uint16_t session_id)
+{
+ struct voice_data *v = voice_get_session(session_id);
+ int ret = 0;
+
+ if (v == NULL) {
+ pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+ return -EINVAL;
+ }
+
+ mutex_lock(&v->lock);
+
+ ret = v->st_enable;
+
+ mutex_unlock(&v->lock);
+
+ return ret;
+}
+
int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
{
struct voice_data *v = voice_get_session(session_id);
@@ -2803,6 +2909,7 @@
case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
case VSS_ICOMMON_CMD_MAP_MEMORY:
case VSS_ICOMMON_CMD_UNMAP_MEMORY:
+ case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]);
v->cvs_state = CMD_STATUS_SUCCESS;
wake_up(&v->cvs_wait);
diff --git a/sound/soc/msm/qdsp6/q6voice.h b/sound/soc/msm/qdsp6/q6voice.h
index c98b53b..edde0aa 100644
--- a/sound/soc/msm/qdsp6/q6voice.h
+++ b/sound/soc/msm/qdsp6/q6voice.h
@@ -51,6 +51,8 @@
};
/* Common */
+#define VSS_ICOMMON_CMD_SET_UI_PROPERTY 0x00011103
+/* Set a UI property */
#define VSS_ICOMMON_CMD_MAP_MEMORY 0x00011025
#define VSS_ICOMMON_CMD_UNMAP_MEMORY 0x00011026
/* General shared memory; byte-accessible, 4 kB-aligned. */
@@ -312,6 +314,10 @@
#define VSS_ISTREAM_CMD_SET_ENC_DTX_MODE 0x0001101D
/* Set encoder DTX mode. */
+#define MODULE_ID_VOICE_MODULE_ST 0x00010EE3
+#define VOICE_PARAM_MOD_ENABLE 0x00010E00
+#define MOD_ENABLE_PARAM_LEN 4
+
struct vss_istream_cmd_create_passive_control_session_t {
char name[SESSION_NAME_LEN];
/**<
@@ -456,6 +462,20 @@
/* Size of the calibration data in bytes. */
};
+struct vss_icommon_cmd_set_ui_property_st_enable_t {
+ uint32_t module_id;
+ /* Unique ID of the module. */
+ uint32_t param_id;
+ /* Unique ID of the parameter. */
+ uint16_t param_size;
+ /* Size of the parameter in bytes: MOD_ENABLE_PARAM_LEN */
+ uint16_t reserved;
+ /* Reserved; set to 0. */
+ uint16_t enable;
+ uint16_t reserved_field;
+ /* Reserved, set to 0. */
+};
+
struct cvs_create_passive_ctl_session_cmd {
struct apr_hdr hdr;
struct vss_istream_cmd_create_passive_control_session_t cvs_session;
@@ -514,6 +534,11 @@
struct apr_hdr hdr;
} __packed;
+struct cvs_set_slowtalk_enable_cmd {
+ struct apr_hdr hdr;
+ struct vss_icommon_cmd_set_ui_property_st_enable_t vss_set_st;
+} __packed;
+
/* TO CVP commands */
#define VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION 0x000100C3
@@ -759,6 +784,8 @@
uint8_t tty_mode;
/* widevoice enable value */
uint8_t wv_enable;
+ /* slowtalk enable value */
+ uint32_t st_enable;
struct voice_dev_route_state voc_route_state;
@@ -807,6 +834,8 @@
};
/* called by alsa driver */
+int voc_set_slowtalk_enable(uint16_t session_id, uint32_t st_enable);
+uint32_t voc_get_slowtalk_enable(uint16_t session_id);
int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable);
uint32_t voc_get_widevoice_enable(uint16_t session_id);
uint8_t voc_get_tty_mode(uint16_t session_id);