ASoC: msm: Support mixer controls for Pan/scale & downmix

Add changes to register and receive parameters for pan/scale
and downmix operations.

Change-Id: If0e747304595f9ed3bd19b25e3f4eab2db382a67
Signed-off-by: Varun Balaraj <varunb@codeaurora.org>
This commit is contained in:
Varun Balaraj 2017-07-13 13:42:12 +05:30 committed by Gerrit - the friendly Code Review server
parent 701ac49eb7
commit a48f734c3b
5 changed files with 561 additions and 2 deletions

View file

@ -625,11 +625,30 @@ struct audproc_softvolume_params {
*/
#define AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT 0x00010913
/* ID of the Channel Mixer module, which is used to configure
* channel-mixer related parameters.
* This module supports the AUDPROC_CHMIXER_PARAM_ID_COEFF parameter ID.
*/
#define AUDPROC_MODULE_ID_CHMIXER 0x00010341
/* ID of the Coefficient parameter used by AUDPROC_MODULE_ID_CHMIXER to
*configure the channel mixer weighting coefficients.
*/
#define AUDPROC_CHMIXER_PARAM_ID_COEFF 0x00010342
/* Payload of the per-session, per-device parameter data of the
* #ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V5 command or
* #ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V6 command.
* Immediately following this structure are param_size bytes of parameter
* data. The structure and size depend on the module_id/param_id pair.
*/
struct adm_pspd_param_data_t {
uint32_t module_id;
uint32_t param_id;
uint16_t param_size;
uint16_t reserved;
} __packed;
struct audproc_mfc_output_media_fmt {
struct adm_cmd_set_pp_params_v5 params;
struct adm_param_data_v5 data;

View file

@ -2641,6 +2641,101 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.name = "MultiMedia20",
.probe = fe_dai_probe,
},
{
.playback = {
.stream_name = "MultiMedia21 Playback",
.aif_name = "MM_DL21",
.rates = (SNDRV_PCM_RATE_8000_384000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
.rate_max = 384000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia21",
.probe = fe_dai_probe,
},
{
.playback = {
.stream_name = "MultiMedia22 Playback",
.aif_name = "MM_DL22",
.rates = (SNDRV_PCM_RATE_8000_384000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
.rate_max = 384000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia22",
.probe = fe_dai_probe,
},
{
.playback = {
.stream_name = "MultiMedia23 Playback",
.aif_name = "MM_DL23",
.rates = (SNDRV_PCM_RATE_8000_384000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
.rate_max = 384000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia23",
.probe = fe_dai_probe,
},
{
.playback = {
.stream_name = "MultiMedia24 Playback",
.aif_name = "MM_DL24",
.rates = (SNDRV_PCM_RATE_8000_384000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
.rate_max = 384000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia24",
.probe = fe_dai_probe,
},
{
.playback = {
.stream_name = "MultiMedia25 Playback",
.aif_name = "MM_DL25",
.rates = (SNDRV_PCM_RATE_8000_384000 |
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
.rate_max = 384000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia25",
.probe = fe_dai_probe,
},
};
static int msm_fe_dai_dev_probe(struct platform_device *pdev)

View file

@ -1603,6 +1603,262 @@ done:
return ret;
}
static int msm_pcm_playback_pan_scale_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int ret = 0;
int len = 0;
int i = 0;
struct snd_pcm_usr *usr_info = snd_kcontrol_chip(kcontrol);
struct snd_pcm_substream *substream;
struct msm_audio *prtd;
struct asm_stream_pan_ctrl_params pan_param;
if (!usr_info) {
pr_err("%s: usr_info is null\n", __func__);
ret = -EINVAL;
goto done;
}
substream = usr_info->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
if (!substream) {
pr_err("%s substream not found\n", __func__);
ret = -EINVAL;
goto done;
}
if (!substream->runtime) {
pr_err("%s substream runtime not found\n", __func__);
ret = -EINVAL;
goto done;
}
prtd = substream->runtime->private_data;
if (!prtd) {
ret = -EINVAL;
goto done;
}
pan_param.num_output_channels =
ucontrol->value.integer.value[len++];
if (pan_param.num_output_channels >
PCM_FORMAT_MAX_NUM_CHANNEL) {
ret = -EINVAL;
goto done;
}
pan_param.num_input_channels =
ucontrol->value.integer.value[len++];
if (pan_param.num_input_channels >
PCM_FORMAT_MAX_NUM_CHANNEL) {
ret = -EINVAL;
goto done;
}
if (ucontrol->value.integer.value[len++]) {
for (i = 0; i < pan_param.num_output_channels; i++) {
pan_param.output_channel_map[i] =
ucontrol->value.integer.value[len++];
}
}
if (ucontrol->value.integer.value[len++]) {
for (i = 0; i < pan_param.num_input_channels; i++) {
pan_param.input_channel_map[i] =
ucontrol->value.integer.value[len++];
}
}
if (ucontrol->value.integer.value[len++]) {
for (i = 0; i < pan_param.num_output_channels *
pan_param.num_input_channels; i++) {
pan_param.gain[i] =
!(ucontrol->value.integer.value[len++] > 0) ?
0 : 2 << 13;
}
}
ret = q6asm_set_mfc_panning_params(prtd->audio_client,
&pan_param);
len -= pan_param.num_output_channels *
pan_param.num_input_channels;
for (i = 0; i < pan_param.num_output_channels *
pan_param.num_input_channels; i++) {
pan_param.gain[i] =
ucontrol->value.integer.value[len++];
}
ret = q6asm_set_vol_ctrl_gain_pair(prtd->audio_client,
&pan_param);
done:
return ret;
}
static int msm_pcm_playback_pan_scale_ctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
return 0;
}
static int msm_add_stream_pan_scale_controls(struct snd_soc_pcm_runtime *rtd)
{
struct snd_pcm *pcm;
struct snd_pcm_usr *pan_ctl_info;
struct snd_kcontrol *kctl;
const char *playback_mixer_ctl_name = "Audio Stream";
const char *deviceNo = "NN";
const char *suffix = "Pan Scale Control";
int ctl_len, ret = 0;
if (!rtd) {
pr_err("%s: rtd is NULL\n", __func__);
ret = -EINVAL;
goto done;
}
pcm = rtd->pcm;
ctl_len = strlen(playback_mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
strlen(suffix) + 1;
ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
NULL, 1, ctl_len, rtd->dai_link->be_id,
&pan_ctl_info);
if (ret < 0) {
pr_err("%s: failed add ctl %s. err = %d\n",
__func__, suffix, ret);
goto done;
}
kctl = pan_ctl_info->kctl;
snprintf(kctl->id.name, ctl_len, "%s %d %s", playback_mixer_ctl_name,
rtd->pcm->device, suffix);
kctl->put = msm_pcm_playback_pan_scale_ctl_put;
kctl->get = msm_pcm_playback_pan_scale_ctl_get;
pr_debug("%s: Registering new mixer ctl = %s\n", __func__,
kctl->id.name);
done:
return ret;
}
static int msm_pcm_playback_dnmix_ctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
return 0;
}
static int msm_pcm_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_pcm_usr *usr_info = snd_kcontrol_chip(kcontrol);
struct snd_pcm_substream *substream;
struct msm_audio *prtd;
struct asm_stream_pan_ctrl_params dnmix_param;
int be_id = ucontrol->value.integer.value[len];
int stream_id = 0;
if (!usr_info) {
pr_err("%s usr_info is null\n", __func__);
ret = -EINVAL;
goto done;
}
substream = usr_info->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
if (!substream) {
pr_err("%s substream not found\n", __func__);
ret = -EINVAL;
goto done;
}
if (!substream->runtime) {
pr_err("%s substream runtime not found\n", __func__);
ret = -EINVAL;
goto done;
}
prtd = substream->runtime->private_data;
if (!prtd) {
ret = -EINVAL;
goto done;
}
stream_id = prtd->audio_client->session;
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;
}
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;
}
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_add_device_down_mix_controls(struct snd_soc_pcm_runtime *rtd)
{
struct snd_pcm *pcm;
struct snd_pcm_usr *usr_info;
struct snd_kcontrol *kctl;
const char *playback_mixer_ctl_name = "Audio Device";
const char *deviceNo = "NN";
const char *suffix = "Downmix Control";
int ctl_len, ret = 0;
if (!rtd) {
pr_err("%s: rtd is NULL\n", __func__);
ret = -EINVAL;
goto done;
}
pcm = rtd->pcm;
ctl_len = strlen(playback_mixer_ctl_name) + 1 +
strlen(deviceNo) + 1 + strlen(suffix) + 1;
ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
NULL, 1, ctl_len, rtd->dai_link->be_id,
&usr_info);
if (ret < 0) {
pr_err("%s: downmix control add failed: %d\n",
__func__, ret);
goto done;
}
kctl = usr_info->kctl;
snprintf(kctl->id.name, ctl_len, "%s %d %s",
playback_mixer_ctl_name, rtd->pcm->device, suffix);
kctl->put = msm_pcm_playback_dnmix_ctl_put;
kctl->get = msm_pcm_playback_dnmix_ctl_get;
pr_debug("%s: downmix control name = %s\n",
__func__, playback_mixer_ctl_name);
done:
return ret;
}
static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@ -1719,6 +1975,14 @@ static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
if (ret)
pr_err("%s: pcm add app type controls failed:%d\n",
__func__, ret);
ret = msm_add_stream_pan_scale_controls(rtd);
if (ret)
pr_err("%s: pcm add pan scale controls failed:%d\n",
__func__, ret);
ret = msm_add_device_down_mix_controls(rtd);
if (ret)
pr_err("%s: pcm add dnmix controls failed:%d\n",
__func__, ret);
return ret;
}

View file

@ -35,6 +35,8 @@
#include <sound/audio_cal_utils.h>
#include <sound/audio_effects.h>
#include <sound/hwdep.h>
#include <sound/q6adm-v2.h>
#include <sound/apr_audio-v2.h>
#include "msm-pcm-routing-v2.h"
#include "msm-pcm-routing-devdep.h"
@ -4090,6 +4092,21 @@ static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia22", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia23", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia24", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia25", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = {
@ -4612,6 +4629,21 @@ static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia22", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia23", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia24", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia25", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new display_port_mixer_controls[] = {
@ -4760,6 +4792,21 @@ static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_6_RX,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SLIMBUS_6_RX,
MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia22", MSM_BACKEND_DAI_SLIMBUS_6_RX,
MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia23", MSM_BACKEND_DAI_SLIMBUS_6_RX,
MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia24", MSM_BACKEND_DAI_SLIMBUS_6_RX,
MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia25", MSM_BACKEND_DAI_SLIMBUS_6_RX,
MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = {
@ -4811,6 +4858,21 @@ static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_7_RX,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SLIMBUS_7_RX,
MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia22", MSM_BACKEND_DAI_SLIMBUS_7_RX,
MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia23", MSM_BACKEND_DAI_SLIMBUS_7_RX,
MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia24", MSM_BACKEND_DAI_SLIMBUS_7_RX,
MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia25", MSM_BACKEND_DAI_SLIMBUS_7_RX,
MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = {
@ -11314,6 +11376,11 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_AIF_IN("MM_DL15", "MultiMedia15 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL16", "MultiMedia16 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL22", "MultiMedia22 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL23", "MultiMedia23 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL24", "MultiMedia24 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL25", "MultiMedia25 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
@ -12450,6 +12517,11 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia21", "MM_DL21"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia22", "MM_DL22"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia23", "MM_DL23"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia24", "MM_DL24"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia25", "MM_DL25"},
{"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
{"SLIMBUS_2_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@ -12504,6 +12576,11 @@ static const struct snd_soc_dapm_route intercon[] = {
{"HDMI Mixer", "MultiMedia14", "MM_DL14"},
{"HDMI Mixer", "MultiMedia15", "MM_DL15"},
{"HDMI Mixer", "MultiMedia16", "MM_DL16"},
{"HDMI Mixer", "MultiMedia21", "MM_DL21"},
{"HDMI Mixer", "MultiMedia22", "MM_DL22"},
{"HDMI Mixer", "MultiMedia23", "MM_DL23"},
{"HDMI Mixer", "MultiMedia24", "MM_DL24"},
{"HDMI Mixer", "MultiMedia25", "MM_DL25"},
{"HDMI", NULL, "HDMI Mixer"},
{"DISPLAY_PORT Mixer", "MultiMedia1", "MM_DL1"},
@ -12575,6 +12652,11 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia21", "MM_DL21"},
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia22", "MM_DL22"},
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia23", "MM_DL23"},
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia24", "MM_DL24"},
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia25", "MM_DL25"},
{"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Audio Mixer"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@ -12593,6 +12675,11 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia21", "MM_DL21"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia22", "MM_DL22"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia23", "MM_DL23"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia24", "MM_DL24"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia25", "MM_DL25"},
{"SLIMBUS_7_RX", NULL, "SLIMBUS_7_RX Audio Mixer"},
{"USB_AUDIO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@ -15486,6 +15573,93 @@ static struct snd_pcm_ops msm_routing_pcm_ops = {
.prepare = msm_pcm_routing_prepare,
};
int msm_routing_set_downmix_control_data(int be_id, int session_id,
struct asm_stream_pan_ctrl_params *dnmix_param)
{
int i, rc = 0;
struct adm_pspd_param_data_t data;
struct audproc_chmixer_param_coeff dnmix_cfg;
uint16_t variable_payload = 0;
char *adm_params = NULL;
int port_id, copp_idx = 0;
uint32_t params_length = 0;
if (be_id >= MSM_BACKEND_DAI_MAX) {
rc = -EINVAL;
return rc;
}
port_id = msm_bedais[be_id].port_id;
copp_idx = adm_get_default_copp_idx(port_id);
pr_debug("%s: port_id - %d, copp_idx %d session id - %d\n",
__func__, port_id, copp_idx, session_id);
variable_payload = dnmix_param->num_output_channels * sizeof(uint16_t)+
dnmix_param->num_input_channels * sizeof(uint16_t) +
dnmix_param->num_output_channels * sizeof(uint16_t) *
dnmix_param->num_input_channels * sizeof(uint16_t);
i = (variable_payload % sizeof(uint32_t));
variable_payload += (i == 0) ? 0 : sizeof(uint32_t) - i;
params_length = variable_payload +
sizeof(struct adm_pspd_param_data_t) +
sizeof(struct audproc_chmixer_param_coeff);
adm_params = kzalloc(params_length, GFP_KERNEL);
if (!adm_params) {
rc = -ENOMEM;
goto end;
}
data.module_id = AUDPROC_MODULE_ID_CHMIXER;
data.param_id = AUDPROC_CHMIXER_PARAM_ID_COEFF;
data.param_size = sizeof(struct audproc_chmixer_param_coeff) +
variable_payload;
data.reserved = 0;
memcpy((u8 *)adm_params, &data, sizeof(struct adm_pspd_param_data_t));
dnmix_cfg.index = 0;
dnmix_cfg.num_output_channels = dnmix_param->num_output_channels;
dnmix_cfg.num_input_channels = dnmix_param->num_input_channels;
memcpy(((u8 *)adm_params +
sizeof(struct adm_pspd_param_data_t)),
&dnmix_cfg, sizeof(struct audproc_chmixer_param_coeff));
memcpy(((u8 *)adm_params +
sizeof(struct adm_pspd_param_data_t) +
sizeof(struct audproc_chmixer_param_coeff)),
dnmix_param->output_channel_map,
dnmix_param->num_output_channels * sizeof(uint16_t));
memcpy(((u8 *)adm_params +
sizeof(struct adm_pspd_param_data_t) +
sizeof(struct audproc_chmixer_param_coeff) +
dnmix_param->num_output_channels * sizeof(uint16_t)),
dnmix_param->input_channel_map,
dnmix_param->num_input_channels * sizeof(uint16_t));
memcpy(((u8 *)adm_params +
sizeof(struct adm_pspd_param_data_t) +
sizeof(struct audproc_chmixer_param_coeff) +
(dnmix_param->num_output_channels * sizeof(uint16_t)) +
(dnmix_param->num_input_channels * sizeof(uint16_t))),
dnmix_param->gain,
(dnmix_param->num_output_channels * sizeof(uint16_t)) *
(dnmix_param->num_input_channels * sizeof(uint16_t)));
if (params_length) {
rc = adm_set_pspd_matrix_params(port_id,
copp_idx,
session_id,
adm_params,
params_length);
if (rc) {
pr_err("%s: send params failed rc=%d\n", __func__, rc);
rc = -EINVAL;
}
}
end:
kfree(adm_params);
return rc;
}
/* Not used but frame seems to require it */
static int msm_routing_probe(struct snd_soc_platform *platform)
{

View file

@ -193,6 +193,11 @@ enum {
MSM_FRONTEND_DAI_MULTIMEDIA18,
MSM_FRONTEND_DAI_MULTIMEDIA19,
MSM_FRONTEND_DAI_MULTIMEDIA20,
MSM_FRONTEND_DAI_MULTIMEDIA21,
MSM_FRONTEND_DAI_MULTIMEDIA22,
MSM_FRONTEND_DAI_MULTIMEDIA23,
MSM_FRONTEND_DAI_MULTIMEDIA24,
MSM_FRONTEND_DAI_MULTIMEDIA25,
MSM_FRONTEND_DAI_CS_VOICE,
MSM_FRONTEND_DAI_VOIP,
MSM_FRONTEND_DAI_AFE_RX,
@ -218,8 +223,8 @@ enum {
MSM_FRONTEND_DAI_MAX,
};
#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA20 + 1)
#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA20
#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA25 + 1)
#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA25
enum {
MSM_BACKEND_DAI_PRI_I2S_RX = 0,
@ -483,4 +488,6 @@ int msm_pcm_routing_reg_stream_app_type_cfg(
int msm_pcm_routing_get_stream_app_type_cfg(
int fedai_id, int session_type, int *be_id,
struct msm_pcm_stream_app_type_cfg *cfg_data);
int msm_routing_set_downmix_control_data(int be_id, int session_id,
struct asm_stream_pan_ctrl_params *pan_param);
#endif /*_MSM_PCM_H*/