summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-12-20 14:04:49 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-12-20 14:04:49 -0800
commit314122fcd05fe0f710edb9368247c732cc840d78 (patch)
tree0a97e368f777a372824d9df056d3646b62ed9316 /sound
parentb0ba6bde9d794e09bde7372a314a52ec9020eaab (diff)
parentdd764997fa84cf5e42beb3cb9f3e5cceee5058ea (diff)
Merge "msm: qdsp6v2: extend media format provided to voice driver"
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c62
-rw-r--r--sound/soc/msm/qdsp6v2/q6voice.c315
-rw-r--r--sound/soc/msm/qdsp6v2/q6voice.h123
-rw-r--r--sound/soc/msm/qdsp6v2/rtac.c24
4 files changed, 459 insertions, 65 deletions
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 01902f7f571d..8c545560cf10 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1481,6 +1481,7 @@ static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
{
u32 session_id = 0;
u16 path_type;
+ struct media_format_info voc_be_media_format;
pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
@@ -1513,8 +1514,22 @@ static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
if (set) {
if (msm_bedais[reg].active) {
voc_set_route_flag(session_id, path_type, 1);
+
+ memset(&voc_be_media_format, 0,
+ sizeof(struct media_format_info));
+
+ voc_be_media_format.port_id = msm_bedais[reg].port_id;
+ voc_be_media_format.num_channels =
+ msm_bedais[reg].channel;
+ voc_be_media_format.sample_rate =
+ msm_bedais[reg].sample_rate;
+ voc_be_media_format.bits_per_sample =
+ msm_bedais[reg].format;
+ /* Defaulting this to 1 for voice call usecases */
+ voc_be_media_format.channel_mapping[0] = 1;
+
voc_set_device_config(session_id, path_type,
- msm_bedais[reg].channel, msm_bedais[reg].port_id);
+ &voc_be_media_format);
if (voc_get_route_flag(session_id, TX_PATH) &&
voc_get_route_flag(session_id, RX_PATH))
@@ -2381,9 +2396,9 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol,
}
pr_debug("%s: val = %d ext_ec_ref_port_id = 0x%0x state = %d\n",
- __func__, msm_route_ext_ec_ref, ext_ec_ref_port_id, state);
+ __func__, msm_route_ext_ec_ref, ext_ec_ref_port_id, state);
- if (!voc_set_ext_ec_ref(ext_ec_ref_port_id, state)) {
+ if (!voc_set_ext_ec_ref_port_id(ext_ec_ref_port_id, state)) {
mutex_unlock(&routing_lock);
snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e, update);
} else {
@@ -11433,6 +11448,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
uint16_t bits_per_sample = 16, voc_path_type;
struct msm_pcm_routing_fdai_data *fdai;
u32 session_id;
+ struct media_format_info voc_be_media_format;
pr_debug("%s: substream->pcm->id:%s\n",
__func__, substream->pcm->id);
@@ -11545,8 +11561,8 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MAX) {
session_id = msm_pcm_routing_get_voc_sessionid(i);
if (session_id) {
- pr_debug("%s voice session_id: 0x%x",
- __func__, session_id);
+ pr_debug("%s voice session_id: 0x%x\n", __func__,
+ session_id);
if (session_type == SESSION_TYPE_TX)
voc_path_type = TX_PATH;
@@ -11554,8 +11570,19 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
voc_path_type = RX_PATH;
voc_set_route_flag(session_id, voc_path_type, 1);
- voc_set_device_config(session_id, voc_path_type,
- bedai->channel, bedai->port_id);
+
+ memset(&voc_be_media_format, 0,
+ sizeof(struct media_format_info));
+
+ voc_be_media_format.port_id = bedai->port_id;
+ voc_be_media_format.num_channels = bedai->channel;
+ voc_be_media_format.sample_rate = bedai->sample_rate;
+ voc_be_media_format.bits_per_sample = bedai->format;
+ /* Defaulting this to 1 for voice call usecases */
+ voc_be_media_format.channel_mapping[0] = 1;
+
+ voc_set_device_config(session_id, voc_path_type,
+ &voc_be_media_format);
if (voc_get_route_flag(session_id, RX_PATH) &&
voc_get_route_flag(session_id, TX_PATH))
@@ -11563,6 +11590,27 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
}
}
+ /* Check if backend is an external ec ref port and set as needed */
+ if (unlikely(bedai->port_id == voc_get_ext_ec_ref_port_id())) {
+
+ memset(&voc_be_media_format, 0,
+ sizeof(struct media_format_info));
+
+ /* Get format info for ec ref port from msm_bedais[] */
+ voc_be_media_format.port_id = bedai->port_id;
+ voc_be_media_format.num_channels = bedai->channel;
+ voc_be_media_format.bits_per_sample = bedai->format;
+ voc_be_media_format.sample_rate = bedai->sample_rate;
+ /* Defaulting this to 1 for voice call usecases */
+ voc_be_media_format.channel_mapping[0] = 1;
+ voc_set_ext_ec_ref_media_fmt_info(&voc_be_media_format);
+ pr_debug("%s: EC Ref media format info set to port_id=%d, num_channels=%d, bits_per_sample=%d, sample_rate=%d\n",
+ __func__, voc_be_media_format.port_id,
+ voc_be_media_format.num_channels,
+ voc_be_media_format.bits_per_sample,
+ voc_be_media_format.sample_rate);
+ }
+
done:
mutex_unlock(&routing_lock);
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index b242a8fe6017..5cff3dd1ed4f 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -78,7 +78,10 @@ static int voice_send_cvp_register_cal_cmd(struct voice_data *v);
static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v);
static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v);
static int voice_send_cvp_deregister_vol_cal_cmd(struct voice_data *v);
+static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v);
static int voice_send_cvp_device_channels_cmd(struct voice_data *v);
+static int voice_send_cvp_media_format_cmd(struct voice_data *v,
+ uint32_t param_type);
static int voice_send_cvp_topology_commit_cmd(struct voice_data *v);
static int voice_cvs_stop_playback(struct voice_data *v);
@@ -2398,7 +2401,7 @@ static int voice_send_set_device_cmd(struct voice_data *v)
cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
- common.ec_port_id;
+ common.ec_media_fmt_info.port_id;
} else {
cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
@@ -2752,7 +2755,7 @@ static int voice_send_cvp_create_cmd(struct voice_data *v)
cvp_session_cmd.cvp_session.vocproc_mode =
VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
cvp_session_cmd.cvp_session.ec_ref_port_id =
- common.ec_port_id;
+ common.ec_media_fmt_info.port_id;
} else {
cvp_session_cmd.cvp_session.vocproc_mode =
VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
@@ -3826,10 +3829,10 @@ static int voice_setup_vocproc(struct voice_data *v)
goto fail;
}
- ret = voice_send_cvp_device_channels_cmd(v);
+ ret = voice_send_cvp_media_fmt_info_cmd(v);
if (ret < 0) {
- pr_err("%s: Set device channels failed err:%d\n",
- __func__, ret);
+ pr_err("%s: Set media format info failed err:%d\n", __func__,
+ ret);
goto fail;
}
@@ -3983,6 +3986,158 @@ done:
return ret;
}
+static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v)
+{
+ int ret;
+
+ if (voice_get_cvd_int_version(common.cvd_version) >=
+ CVD_INT_VERSION_2_3) {
+ ret = voice_send_cvp_media_format_cmd(v, RX_PATH);
+ if (ret < 0)
+ goto done;
+
+ ret = voice_send_cvp_media_format_cmd(v, TX_PATH);
+ if (ret < 0)
+ goto done;
+
+ if (common.ec_ref_ext)
+ ret = voice_send_cvp_media_format_cmd(v, EC_REF_PATH);
+ } else {
+ ret = voice_send_cvp_device_channels_cmd(v);
+ }
+
+done:
+ return ret;
+}
+
+static int voice_send_cvp_media_format_cmd(struct voice_data *v,
+ uint32_t param_type)
+{
+ int ret = 0;
+ struct cvp_set_media_format_cmd cvp_set_media_format_cmd;
+ void *apr_cvp;
+ u16 cvp_handle;
+ struct vss_icommon_param_data_t *media_fmt_param_data =
+ &cvp_set_media_format_cmd.cvp_set_param_v2.param_data;
+ struct vss_param_endpoint_media_format_info_t *media_fmt_info =
+ &media_fmt_param_data->media_format_info;
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ apr_cvp = common.apr_q6_cvp;
+ if (!apr_cvp) {
+ pr_err("%s: apr_cvp is NULL.\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ cvp_handle = voice_get_cvp_handle(v);
+ memset(&cvp_set_media_format_cmd, 0, sizeof(cvp_set_media_format_cmd));
+
+ /* Fill header data */
+ cvp_set_media_format_cmd.hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ cvp_set_media_format_cmd.hdr.pkt_size =
+ APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvp_set_media_format_cmd) - APR_HDR_SIZE);
+ cvp_set_media_format_cmd.hdr.src_svc = 0;
+ cvp_set_media_format_cmd.hdr.src_domain = APR_DOMAIN_APPS;
+ cvp_set_media_format_cmd.hdr.src_port =
+ voice_get_idx_for_session(v->session_id);
+ cvp_set_media_format_cmd.hdr.dest_svc = 0;
+ cvp_set_media_format_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
+ cvp_set_media_format_cmd.hdr.dest_port = cvp_handle;
+ cvp_set_media_format_cmd.hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN;
+ cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
+
+ /* Fill param data */
+ cvp_set_media_format_cmd.cvp_set_param_v2.mem_size =
+ sizeof(struct vss_icommon_param_data_t);
+ media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC;
+ media_fmt_param_data->param_size =
+ sizeof(struct vss_param_endpoint_media_format_info_t);
+
+ /* Fill device specific data */
+ switch (param_type) {
+ case RX_PATH:
+ media_fmt_param_data->param_id =
+ VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO;
+ media_fmt_info->port_id = v->dev_rx.port_id;
+ media_fmt_info->num_channels = v->dev_rx.no_of_channels;
+ media_fmt_info->bits_per_sample = v->dev_rx.bits_per_sample;
+ media_fmt_info->sample_rate = v->dev_rx.sample_rate;
+ memcpy(&media_fmt_info->channel_mapping,
+ &v->dev_rx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
+ break;
+
+ case TX_PATH:
+ media_fmt_param_data->param_id =
+ VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO;
+ media_fmt_info->port_id = v->dev_tx.port_id;
+ media_fmt_info->num_channels = v->dev_tx.no_of_channels;
+ media_fmt_info->bits_per_sample = v->dev_tx.bits_per_sample;
+ media_fmt_info->sample_rate = v->dev_tx.sample_rate;
+ memcpy(&media_fmt_info->channel_mapping,
+ &v->dev_tx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
+ break;
+
+ case EC_REF_PATH:
+ media_fmt_param_data->param_id =
+ VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO;
+ media_fmt_info->port_id = common.ec_media_fmt_info.port_id;
+ media_fmt_info->num_channels =
+ common.ec_media_fmt_info.num_channels;
+ media_fmt_info->bits_per_sample =
+ common.ec_media_fmt_info.bits_per_sample;
+ media_fmt_info->sample_rate =
+ common.ec_media_fmt_info.sample_rate;
+ memcpy(&media_fmt_info->channel_mapping,
+ &common.ec_media_fmt_info.channel_mapping,
+ VSS_CHANNEL_MAPPING_SIZE);
+ break;
+
+ default:
+ pr_err("%s: Invalid param type %d\n", __func__, param_type);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /* Send command */
+ v->cvp_state = CMD_STATUS_FAIL;
+ v->async_err = 0;
+ ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_media_format_cmd);
+ if (ret < 0) {
+ pr_err("%s: Fail in sending VSS_ICOMMON_CMD_SET_PARAM_V2\n",
+ __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = wait_event_timeout(v->cvp_wait,
+ (v->cvp_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (v->async_err > 0) {
+ pr_err("%s: DSP returned error[%s] handle = %d\n", __func__,
+ adsp_err_get_err_str(v->async_err), cvp_handle);
+ ret = adsp_err_get_lnx_err_code(v->async_err);
+ goto done;
+ }
+
+done:
+ return ret;
+}
+
static int voice_send_cvp_topology_commit_cmd(struct voice_data *v)
{
int ret = 0;
@@ -5743,7 +5898,7 @@ int voc_set_rx_vol_step(uint32_t session_id, uint32_t dir, uint32_t vol_step,
}
int voc_set_device_config(uint32_t session_id, uint8_t path_dir,
- uint8_t no_of_channels, uint32_t port_id)
+ struct media_format_info *finfo)
{
struct voice_data *v = voice_get_session(session_id);
@@ -5753,22 +5908,55 @@ int voc_set_device_config(uint32_t session_id, uint8_t path_dir,
return -EINVAL;
}
- pr_debug("%s: path_dir=%d port_id=%x, channels=%d\n",
- __func__, path_dir, port_id, no_of_channels);
+ pr_debug("%s: path_dir=%d port_id=%x, channels=%d, sample_rate=%d, bits_per_sample=%d\n",
+ __func__, path_dir, finfo->port_id, finfo->num_channels,
+ finfo->sample_rate, finfo->bits_per_sample);
mutex_lock(&v->lock);
- if (path_dir == RX_PATH) {
- v->dev_rx.port_id = q6audio_get_port_id(port_id);
- v->dev_rx.no_of_channels = no_of_channels;
- } else {
- v->dev_tx.port_id = q6audio_get_port_id(port_id);
- v->dev_tx.no_of_channels = no_of_channels;
+ switch (path_dir) {
+ case RX_PATH:
+ v->dev_rx.port_id = q6audio_get_port_id(finfo->port_id);
+ v->dev_rx.no_of_channels = finfo->num_channels;
+ v->dev_rx.sample_rate = finfo->sample_rate;
+ v->dev_rx.bits_per_sample = finfo->bits_per_sample;
+ memcpy(&v->dev_rx.channel_mapping, &finfo->channel_mapping,
+ VSS_CHANNEL_MAPPING_SIZE);
+ break;
+ case TX_PATH:
+ v->dev_tx.port_id = q6audio_get_port_id(finfo->port_id);
+ v->dev_tx.no_of_channels = finfo->num_channels;
+ v->dev_tx.sample_rate = finfo->sample_rate;
+ v->dev_tx.bits_per_sample = finfo->bits_per_sample;
+ memcpy(&v->dev_tx.channel_mapping, &finfo->channel_mapping,
+ VSS_CHANNEL_MAPPING_SIZE);
+ break;
+ default:
+ pr_err("%s: Invalid path_dir %d\n", __func__, path_dir);
+ return -EINVAL;
}
+
mutex_unlock(&v->lock);
return 0;
}
+int voc_set_ext_ec_ref_media_fmt_info(struct media_format_info *finfo)
+{
+ mutex_lock(&common.common_lock);
+ if (common.ec_ref_ext) {
+ common.ec_media_fmt_info.num_channels = finfo->num_channels;
+ common.ec_media_fmt_info.bits_per_sample =
+ finfo->bits_per_sample;
+ common.ec_media_fmt_info.sample_rate = finfo->sample_rate;
+ memcpy(&common.ec_media_fmt_info.channel_mapping,
+ &finfo->channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
+ } else {
+ pr_debug("%s: Ext Ec Ref not active, returning", __func__);
+ }
+ mutex_unlock(&common.common_lock);
+ return 0;
+}
+
int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set)
{
struct voice_data *v = voice_get_session(session_id);
@@ -5982,9 +6170,9 @@ int voc_enable_device(uint32_t session_id)
goto done;
}
- ret = voice_send_cvp_device_channels_cmd(v);
+ ret = voice_send_cvp_media_fmt_info_cmd(v);
if (ret < 0) {
- pr_err("%s: Set device channels failed\n", __func__);
+ pr_err("%s: Set format failed err:%d\n", __func__, ret);
goto done;
}
@@ -6179,7 +6367,7 @@ fail:
return ret;
}
-int voc_set_ext_ec_ref(uint16_t port_id, bool state)
+int voc_set_ext_ec_ref_port_id(uint16_t port_id, bool state)
{
int ret = 0;
@@ -6190,17 +6378,25 @@ int voc_set_ext_ec_ref(uint16_t port_id, bool state)
ret = -EINVAL;
goto exit;
}
- common.ec_port_id = port_id;
common.ec_ref_ext = true;
} else {
common.ec_ref_ext = false;
- common.ec_port_id = port_id;
}
+ /* Cache EC Fromat Info in common */
+ common.ec_media_fmt_info.port_id = port_id;
exit:
mutex_unlock(&common.common_lock);
return ret;
}
+int voc_get_ext_ec_ref_port_id(void)
+{
+ if (common.ec_ref_ext)
+ return common.ec_media_fmt_info.port_id;
+ else
+ return AFE_PORT_INVALID;
+}
+
void voc_register_mvs_cb(ul_cb_fn ul_cb,
dl_cb_fn dl_cb,
voip_ssr_cb ssr_cb,
@@ -6557,18 +6753,19 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
v->async_err = ptr[1];
wake_up(&v->cvs_wait);
break;
- case VOICE_CMD_SET_PARAM:
- pr_debug("%s: VOICE_CMD_SET_PARAM\n", __func__);
+ case VSS_ICOMMON_CMD_SET_PARAM_V2:
+ pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2\n",
+ __func__);
rtac_make_voice_callback(RTAC_CVS, ptr,
data->payload_size);
break;
- case VOICE_CMD_GET_PARAM:
- pr_debug("%s: VOICE_CMD_GET_PARAM\n",
- __func__);
+ case VSS_ICOMMON_CMD_GET_PARAM_V2:
+ pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n",
+ __func__);
/* Should only come here if there is an APR */
/* error or malformed APR packet. Otherwise */
/* response will be returned as */
- /* VOICE_EVT_GET_PARAM_ACK */
+ /* VSS_ICOMMON_RSP_GET_PARAM */
if (ptr[1] != 0) {
pr_err("%s: CVP get param error = %d, resuming\n",
__func__, ptr[1]);
@@ -6695,12 +6892,12 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
pr_debug("Recd VSS_ISTREAM_EVT_NOT_READY\n");
} else if (data->opcode == VSS_ISTREAM_EVT_READY) {
pr_debug("Recd VSS_ISTREAM_EVT_READY\n");
- } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
- pr_debug("%s: VOICE_EVT_GET_PARAM_ACK\n", __func__);
+ } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) {
+ pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__);
ptr = data->payload;
if (ptr[0] != 0) {
- pr_err("%s: VOICE_EVT_GET_PARAM_ACK returned error = 0x%x\n",
- __func__, ptr[0]);
+ pr_err("%s: VSS_ICOMMON_RSP_GET_PARAM returned error = 0x%x\n",
+ __func__, ptr[0]);
}
rtac_make_voice_callback(RTAC_CVS, data->payload,
data->payload_size);
@@ -6837,18 +7034,35 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
break;
case VSS_IVPCM_EVT_PUSH_BUFFER_V2:
break;
- case VOICE_CMD_SET_PARAM:
- pr_debug("%s: VOICE_CMD_SET_PARAM\n", __func__);
- rtac_make_voice_callback(RTAC_CVP, ptr,
- data->payload_size);
+ case VSS_ICOMMON_CMD_SET_PARAM_V2:
+ switch (data->token) {
+ case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN:
+ pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by voice_send_cvp_media_format_cmd\n",
+ __func__);
+ v->cvp_state = CMD_STATUS_SUCCESS;
+ v->async_err = ptr[1];
+ wake_up(&v->cvp_wait);
+ break;
+ case VOC_RTAC_SET_PARAM_TOKEN:
+ pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by rtac\n",
+ __func__);
+ rtac_make_voice_callback(
+ RTAC_CVP, ptr,
+ data->payload_size);
+ break;
+ default:
+ pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM_V2: %d\n",
+ __func__, data->token);
+ break;
+ }
break;
- case VOICE_CMD_GET_PARAM:
- pr_debug("%s: VOICE_CMD_GET_PARAM\n",
- __func__);
+ case VSS_ICOMMON_CMD_GET_PARAM_V2:
+ pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n",
+ __func__);
/* Should only come here if there is an APR */
/* error or malformed APR packet. Otherwise */
/* response will be returned as */
- /* VOICE_EVT_GET_PARAM_ACK */
+ /* VSS_ICOMMON_RSP_GET_PARAM */
if (ptr[1] != 0) {
pr_err("%s: CVP get param error = %d, resuming\n",
__func__, ptr[1]);
@@ -6909,12 +7123,12 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
break;
}
}
- } else if (data->opcode == VOICE_EVT_GET_PARAM_ACK) {
- pr_debug("%s: VOICE_EVT_GET_PARAM_ACK\n", __func__);
+ } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) {
+ pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__);
ptr = data->payload;
if (ptr[0] != 0) {
- pr_err("%s: VOICE_EVT_GET_PARAM_ACK returned error = 0x%x\n",
- __func__, ptr[0]);
+ pr_err("%s: VSS_ICOMMON_RSP_GET_PARAM returned error = 0x%x\n",
+ __func__, ptr[0]);
}
rtac_make_voice_callback(RTAC_CVP, data->payload,
data->payload_size);
@@ -8335,7 +8549,16 @@ static int __init voice_init(void)
common.default_vol_step_val = 0;
common.default_vol_ramp_duration_ms = DEFAULT_VOLUME_RAMP_DURATION;
common.default_mute_ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
+
+ /* Initialize EC Ref media format info */
common.ec_ref_ext = false;
+ common.ec_media_fmt_info.port_id = AFE_PORT_INVALID;
+ common.ec_media_fmt_info.num_channels = 0;
+ common.ec_media_fmt_info.bits_per_sample = 16;
+ common.ec_media_fmt_info.sample_rate = 8000;
+ memset(&common.ec_media_fmt_info.channel_mapping, 0,
+ VSS_CHANNEL_MAPPING_SIZE);
+
/* Initialize MVS info. */
common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
@@ -8373,8 +8596,16 @@ static int __init voice_init(void)
common.voice[i].dev_rx.port_id = 0x100A;
common.voice[i].dev_tx.dev_id = 0;
common.voice[i].dev_rx.dev_id = 0;
- common.voice[i].dev_rx.no_of_channels = 0;
common.voice[i].dev_tx.no_of_channels = 0;
+ common.voice[i].dev_rx.no_of_channels = 0;
+ common.voice[i].dev_tx.sample_rate = 8000;
+ common.voice[i].dev_rx.sample_rate = 8000;
+ common.voice[i].dev_tx.bits_per_sample = 16;
+ common.voice[i].dev_rx.bits_per_sample = 16;
+ memset(&common.voice[i].dev_tx.channel_mapping, 0,
+ VSS_CHANNEL_MAPPING_SIZE);
+ memset(&common.voice[i].dev_rx.channel_mapping, 0,
+ VSS_CHANNEL_MAPPING_SIZE);
common.voice[i].sidetone_gain = 0x512;
common.voice[i].dtmf_rx_detect_en = 0;
common.voice[i].lch_mode = 0;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 834fe7c05306..9c3ec62a980d 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -22,6 +22,8 @@
#define SESSION_NAME_LEN 20
#define NUM_OF_MEMORY_BLOCKS 1
#define NUM_OF_BUFFERS 2
+#define VSS_NUM_CHANNELS_MAX 8
+#define VSS_CHANNEL_MAPPING_SIZE (sizeof(uint8_t) * VSS_NUM_CHANNELS_MAX)
/*
* BUFFER BLOCK SIZE based on
* the supported page size
@@ -98,7 +100,9 @@ struct stream_data {
/* Device information payload structure */
struct device_data {
uint32_t dev_mute;
- uint32_t sample;
+ uint32_t sample_rate;
+ uint16_t bits_per_sample;
+ uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX];
uint32_t enabled;
uint32_t dev_id;
uint32_t port_id;
@@ -108,6 +112,25 @@ struct device_data {
uint32_t no_of_channels;
};
+/*
+ * Format information structure to match
+ * vss_param_endpoint_media_format_info_t
+ */
+struct media_format_info {
+ uint32_t port_id;
+ uint16_t num_channels;
+ uint16_t bits_per_sample;
+ uint32_t sample_rate;
+ uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX];
+};
+
+enum {
+ VOC_NO_SET_PARAM_TOKEN = 0,
+ VOC_RTAC_SET_PARAM_TOKEN,
+ VOC_SET_MEDIA_FORMAT_PARAM_TOKEN,
+ VOC_SET_PARAM_TOKEN_MAX
+};
+
struct voice_dev_route_state {
u16 rx_route_flag;
u16 tx_route_flag;
@@ -190,6 +213,81 @@ struct vss_unmap_memory_cmd {
struct vss_icommon_cmd_unmap_memory_t vss_unmap_mem;
} __packed;
+struct vss_param_endpoint_media_format_info_t {
+ /* AFE port ID to which this media format corresponds to. */
+ uint32_t port_id;
+ /*
+ * Number of channels of data.
+ * Supported values: 1 to 8
+ */
+ uint16_t num_channels;
+ /*
+ * Bits per sample of data.
+ * Supported values: 16 and 24
+ */
+ uint16_t bits_per_sample;
+ /*
+ * Sampling rate in Hz.
+ * Supported values: 8000, 11025, 16000, 22050, 24000, 32000,
+ * 44100, 48000, 88200, 96000, 176400, and 192000
+ */
+ uint32_t sample_rate;
+ /*
+ * The channel[i] mapping describes channel i. Each element i
+ * of the array describes channel i inside the data buffer. An
+ * unused or unknown channel is set to 0.
+ */
+ uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX];
+} __packed;
+
+struct vss_icommon_param_data_t {
+ /* Valid ID of the module. */
+ uint32_t module_id;
+ /* Valid ID of the parameter. */
+ uint32_t param_id;
+ /*
+ * Data size of the structure relating to the param_id/module_id
+ * combination in uint8_t bytes.
+ */
+ uint16_t param_size;
+ /* This field must be set to zero. */
+ uint16_t reserved;
+ /*
+ * Parameter data payload when inband. Should have size param_size.
+ * Bit size of payload must be a multiple of 4.
+ */
+ union {
+ struct vss_param_endpoint_media_format_info_t media_format_info;
+ };
+} __packed;
+
+/* Payload structure for the VSS_ICOMMON_CMD_SET_PARAM_V2 command. */
+struct vss_icommon_cmd_set_param_v2_t {
+ /*
+ * Pointer to the unique identifier for an address (physical/virtual).
+ *
+ * If the parameter data payload is within the message payload
+ * (in-band), set this field to 0. The parameter data begins at the
+ * specified data payload address.
+ *
+ * If the parameter data is out-of-band, this field is the handle to
+ * the physical address in the shared memory that holds the parameter
+ * data.
+ */
+ uint32_t mem_handle;
+ /*
+ * Location of the parameter data payload.
+ *
+ * The payload is an array of vss_icommon_param_data_t. If the
+ * mem_handle is 0, this field is ignored.
+ */
+ uint64_t mem_address;
+ /* Size of the parameter data payload in bytes. */
+ uint32_t mem_size;
+ /* Parameter data payload when the data is inband. */
+ struct vss_icommon_param_data_t param_data;
+} __packed;
+
/* TO MVM commands */
#define VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION 0x000110FF
/**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */
@@ -577,6 +675,14 @@ struct vss_imemory_cmd_unmap_t {
#define VSS_IRECORD_MODE_TX_RX_MIXING 0x00010F7B
/* Select mixed Tx and Rx paths. */
+#define VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO 0x00013253
+
+#define VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO 0x00013254
+
+#define VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO 0x00013255
+
+#define VSS_MODULE_CVD_GENERIC 0x0001316E
+
#define VSS_ISTREAM_EVT_NOT_READY 0x000110FD
#define VSS_ISTREAM_EVT_READY 0x000110FC
@@ -1378,6 +1484,11 @@ struct cvp_set_dev_channels_cmd {
struct vss_ivocproc_cmd_topology_set_dev_channels_t cvp_set_channels;
} __packed;
+struct cvp_set_media_format_cmd {
+ struct apr_hdr hdr;
+ struct vss_icommon_cmd_set_param_v2_t cvp_set_param_v2;
+} __packed;
+
struct cvp_set_vp3_data_cmd {
struct apr_hdr hdr;
} __packed;
@@ -1613,7 +1724,7 @@ struct common_data {
uint32_t default_vol_ramp_duration_ms;
uint32_t default_mute_ramp_duration_ms;
bool ec_ref_ext;
- uint16_t ec_port_id;
+ struct media_format_info ec_media_fmt_info;
/* APR to MVM in the Q6 */
void *apr_q6_mvm;
@@ -1685,9 +1796,9 @@ enum {
enum {
RX_PATH = 0,
TX_PATH,
+ EC_REF_PATH,
};
-
#define VOC_PATH_PASSIVE 0
#define VOC_PATH_FULL 1
#define VOC_PATH_VOLTE_PASSIVE 2
@@ -1773,7 +1884,9 @@ uint32_t voc_get_session_id(char *name);
int voc_start_playback(uint32_t set, uint16_t port_id);
int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id);
int voice_get_idx_for_session(u32 session_id);
-int voc_set_ext_ec_ref(uint16_t port_id, bool state);
+int voc_set_ext_ec_ref_port_id(uint16_t port_id, bool state);
+int voc_get_ext_ec_ref_port_id(void);
+int voc_set_ext_ec_ref_media_fmt_info(struct media_format_info *finfo);
int voc_update_amr_vocoder_rate(uint32_t session_id);
int voc_disable_device(uint32_t session_id);
int voc_enable_device(uint32_t session_id);
@@ -1781,7 +1894,7 @@ void voc_set_destroy_cvd_flag(bool is_destroy_cvd);
void voc_set_vote_bms_flag(bool is_vote_bms);
int voc_disable_topology(uint32_t session_id, uint32_t disable);
int voc_set_device_config(uint32_t session_id, uint8_t path_dir,
- uint8_t no_of_channels, uint32_t dev_port_id);
+ struct media_format_info *finfo);
uint32_t voice_get_topology(uint32_t topology_idx);
int voc_set_sound_focus(struct sound_focus_param sound_focus_param);
int voc_get_sound_focus(struct sound_focus_param *soundFocusData);
diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c
index 188f0d3e8c5d..82551fb8ed71 100644
--- a/sound/soc/msm/qdsp6v2/rtac.c
+++ b/sound/soc/msm/qdsp6v2/rtac.c
@@ -1484,7 +1484,7 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode)
goto err;
}
- if (opcode == VOICE_CMD_SET_PARAM) {
+ if (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) {
/* set payload size to in-band payload */
/* set data size to actual out of band payload size */
data_size = payload_size - 4 * sizeof(u32);
@@ -1537,7 +1537,9 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode)
voice_params.dest_svc = 0;
voice_params.dest_domain = APR_DOMAIN_MODEM;
voice_params.dest_port = (u16)dest_port;
- voice_params.token = 0;
+ voice_params.token = (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) ?
+ VOC_RTAC_SET_PARAM_TOKEN :
+ 0;
voice_params.opcode = opcode;
/* fill for out-of-band */
@@ -1582,7 +1584,7 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode)
goto err;
}
- if (opcode == VOICE_CMD_GET_PARAM) {
+ if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V2) {
bytes_returned = ((u32 *)rtac_cal[VOICE_RTAC_CAL].cal_data.
kvaddr)[2] + 3 * sizeof(u32);
@@ -1675,20 +1677,20 @@ static long rtac_ioctl_shared(struct file *f,
ASM_STREAM_CMD_SET_PP_PARAMS_V2);
break;
case AUDIO_GET_RTAC_CVS_CAL:
- result = send_voice_apr(RTAC_CVS, (void *)arg,
- VOICE_CMD_GET_PARAM);
+ result = send_voice_apr(RTAC_CVS, (void *) arg,
+ VSS_ICOMMON_CMD_GET_PARAM_V2);
break;
case AUDIO_SET_RTAC_CVS_CAL:
- result = send_voice_apr(RTAC_CVS, (void *)arg,
- VOICE_CMD_SET_PARAM);
+ result = send_voice_apr(RTAC_CVS, (void *) arg,
+ VSS_ICOMMON_CMD_SET_PARAM_V2);
break;
case AUDIO_GET_RTAC_CVP_CAL:
- result = send_voice_apr(RTAC_CVP, (void *)arg,
- VOICE_CMD_GET_PARAM);
+ result = send_voice_apr(RTAC_CVP, (void *) arg,
+ VSS_ICOMMON_CMD_GET_PARAM_V2);
break;
case AUDIO_SET_RTAC_CVP_CAL:
- result = send_voice_apr(RTAC_CVP, (void *)arg,
- VOICE_CMD_SET_PARAM);
+ result = send_voice_apr(RTAC_CVP, (void *) arg,
+ VSS_ICOMMON_CMD_SET_PARAM_V2);
break;
case AUDIO_GET_RTAC_AFE_CAL:
result = send_rtac_afe_apr((void *)arg,