summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-08-24 06:14:29 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-08-24 06:13:58 -0700
commitbbc14406b147934b1aee71a59d1416401aa91546 (patch)
treeca0ef3046597347cd2e6319f98c073ba0d4c60eb
parentaefbc13edee1b1ef31e8b7e8fd87c10375f81609 (diff)
parente453c121c5548519125967cdc1b49f67fe1168d7 (diff)
Merge "ASoC: msm: qdsp6v2: Implement downmix control support for compr driver"
-rw-r--r--sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 0a5ca576d344..c462f682e160 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -3743,6 +3743,119 @@ done:
return ret;
}
+static int msm_compr_playback_dnmix_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret = 0;
+ int len = 0;
+ int i = 0;
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ unsigned long fe_id = kcontrol->private_value;
+ struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
+ snd_soc_component_get_drvdata(comp);
+ struct snd_compr_stream *cstream = NULL;
+ struct msm_compr_audio *prtd;
+ struct asm_stream_pan_ctrl_params dnmix_param;
+ int be_id = ucontrol->value.integer.value[len++];
+ int stream_id = 0;
+ /*
+ * Max index for this mixer control includes below
+ * be_id (1)
+ * num_output_channels (1)
+ * num_input_channels (1)
+ * output ch map (max) (8)
+ * input ch map (max) (8)
+ * mix matrix coefficients (max)(64)
+ */
+ int max_index = 0;
+ int max_mixer_ctrl_value_size = 128;
+
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ pr_err("%s Received out of bounds invalid fe_id %lu\n",
+ __func__, fe_id);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ cstream = pdata->cstream[fe_id];
+ if (cstream == NULL) {
+ pr_err("%s cstream is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ prtd = cstream->runtime->private_data;
+ if (!prtd) {
+ pr_err("%s: prtd is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (prtd->audio_client == NULL) {
+ pr_err("%s: audio_client is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ stream_id = prtd->audio_client->session;
+ if (len >= max_mixer_ctrl_value_size) {
+ ret = -EINVAL;
+ goto done;
+ }
+ dnmix_param.num_output_channels =
+ ucontrol->value.integer.value[len++];
+ if (dnmix_param.num_output_channels >
+ PCM_FORMAT_MAX_NUM_CHANNEL) {
+ ret = -EINVAL;
+ goto done;
+ }
+ if (len >= max_mixer_ctrl_value_size) {
+ ret = -EINVAL;
+ goto done;
+ }
+ dnmix_param.num_input_channels =
+ ucontrol->value.integer.value[len++];
+ if (dnmix_param.num_input_channels >
+ PCM_FORMAT_MAX_NUM_CHANNEL) {
+ ret = -EINVAL;
+ goto done;
+ }
+ max_index = len + dnmix_param.num_output_channels +
+ dnmix_param.num_input_channels +
+ dnmix_param.num_output_channels *
+ dnmix_param.num_input_channels;
+ if (max_index >= max_mixer_ctrl_value_size) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (ucontrol->value.integer.value[len++]) {
+ for (i = 0; i < dnmix_param.num_output_channels; i++) {
+ dnmix_param.output_channel_map[i] =
+ ucontrol->value.integer.value[len++];
+ }
+ }
+ if (ucontrol->value.integer.value[len++]) {
+ for (i = 0; i < dnmix_param.num_input_channels; i++) {
+ dnmix_param.input_channel_map[i] =
+ ucontrol->value.integer.value[len++];
+ }
+ }
+ if (ucontrol->value.integer.value[len++]) {
+ for (i = 0; i < dnmix_param.num_output_channels *
+ dnmix_param.num_input_channels; i++) {
+ dnmix_param.gain[i] =
+ ucontrol->value.integer.value[len++];
+ }
+ }
+ msm_routing_set_downmix_control_data(be_id,
+ stream_id,
+ &dnmix_param);
+
+done:
+ return ret;
+}
+
static int msm_compr_shm_ion_fd_map_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -4014,6 +4127,16 @@ static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol,
return 0;
}
+static int msm_compr_device_downmix_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 128;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 0xFFFFFFFF;
+ return 0;
+}
+
static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd)
{
const char *mixer_ctl_name = "Compress Playback";
@@ -4312,6 +4435,53 @@ static int msm_compr_add_dec_runtime_params_control(
return 0;
}
+static int msm_compr_add_device_down_mix_controls(
+ struct snd_soc_pcm_runtime *rtd)
+{
+ const char *playback_mixer_ctl_name = "Audio Device";
+ const char *deviceNo = "NN";
+ const char *suffix = "Downmix Control";
+ char *mixer_str = NULL;
+ int ctl_len = 0, ret = 0;
+ struct snd_kcontrol_new device_downmix_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "?",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_compr_device_downmix_info,
+ .put = msm_compr_playback_dnmix_ctl_put,
+ .private_value = 0,
+ }
+ };
+
+ if (!rtd) {
+ pr_err("%s NULL rtd\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ ctl_len = strlen(playback_mixer_ctl_name) + 1 +
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+ if (!mixer_str) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ snprintf(mixer_str, ctl_len, "%s %d %s",
+ playback_mixer_ctl_name, rtd->pcm->device, suffix);
+ device_downmix_control[0].name = mixer_str;
+ device_downmix_control[0].private_value = rtd->dai_link->be_id;
+ ret = snd_soc_add_platform_controls(rtd->platform,
+ device_downmix_control,
+ ARRAY_SIZE(device_downmix_control));
+ if (ret < 0)
+ pr_err("%s: failed to add ctl %s\n", __func__, mixer_str);
+
+ kfree(mixer_str);
+done:
+ return ret;
+}
+
static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd)
{
const char *playback_mixer_ctl_name = "Audio Stream";
@@ -4615,6 +4785,11 @@ static int msm_compr_new(struct snd_soc_pcm_runtime *rtd)
pr_err("%s: Could not add Compr event ack Control\n",
__func__);
+ rc = msm_compr_add_device_down_mix_controls(rtd);
+ if (rc)
+ pr_err("%s: Could not add Compr downmix Control\n",
+ __func__);
+
rc = msm_compr_add_query_audio_effect_control(rtd);
if (rc)
pr_err("%s: Could not add Compr Query Audio Effect Control\n",