mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 04:12:04 -04:00
msm-audio: adding mixer control for soft step volume params
adding new mixer control for set/get soft step volume module params values. This command is attached to FE DAI. Change-Id: I2572d6abe48dcb4d1fb685b5e9c0695fe83cc88a Signed-off-by: Krishna Kishor Jha <quic_kkishorj@quicinc.com>
This commit is contained in:
parent
dd9977f073
commit
91c556699a
4 changed files with 284 additions and 0 deletions
187
asoc/msm-pcm-q6-v2.c
Normal file → Executable file
187
asoc/msm-pcm-q6-v2.c
Normal file → Executable file
|
|
@ -129,6 +129,8 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
|
|||
.mask = 0,
|
||||
};
|
||||
|
||||
static struct asm_softvolume_params soft_params = {0,0,0};
|
||||
|
||||
struct msm_pcm_channel_map *chmap_pspd[MSM_FRONTEND_DAI_MM_SIZE][2];
|
||||
|
||||
static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
|
||||
|
|
@ -151,6 +153,181 @@ static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
|
|||
}
|
||||
}
|
||||
|
||||
static int msm_pcm_set_soft_volume_params(struct msm_audio *prtd,struct asm_softvolume_params *soft_vol_params)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
switch (prtd->audio_client->topology) {
|
||||
default:
|
||||
rc = q6asm_set_softvolume_v2(prtd->audio_client, soft_vol_params,
|
||||
SOFT_VOLUME_INSTANCE_1);
|
||||
if (rc < 0)
|
||||
pr_err("%s: Send SoftVolume Param failed ret=%d\n",
|
||||
__func__, rc);
|
||||
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_pcm_soft_volume_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
||||
struct snd_pcm_soft_volume *soft_vol = (struct snd_pcm_soft_volume *) snd_kcontrol_chip(kcontrol);
|
||||
struct msm_plat_data *pdata = NULL;
|
||||
struct snd_pcm_substream *substream = NULL;
|
||||
struct snd_soc_pcm_runtime *soc_prtd = NULL;
|
||||
struct snd_soc_component *component = NULL;
|
||||
|
||||
pr_debug("%s\n", __func__);
|
||||
|
||||
if (!soft_vol || !soft_vol->pcm) {
|
||||
pr_err("%s: soft vol is NULL\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
substream = soft_vol->pcm->streams[soft_vol->stream].substream;
|
||||
if (!substream) {
|
||||
pr_err("%s substream not found\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
soc_prtd = substream->private_data;
|
||||
if (!soc_prtd) {
|
||||
pr_err("%s substream runtime or private_data not found\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME);
|
||||
if (!component || !component->dev) {
|
||||
pr_err("%s: component is NULL\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev);
|
||||
if (!pdata) {
|
||||
pr_err("%s: pdata not found\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
|
||||
ucontrol->value.integer.value[0] = soft_params.period;
|
||||
ucontrol->value.integer.value[1] = soft_params.step;
|
||||
ucontrol->value.integer.value[2] = soft_params.rampingcurve;
|
||||
pr_debug("%s: period = %d, step = %d , ramping curve: %d",__func__,
|
||||
ucontrol->value.integer.value[0],
|
||||
ucontrol->value.integer.value[1],
|
||||
ucontrol->value.integer.value[2]);
|
||||
|
||||
mutex_unlock(&pdata->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_pcm_soft_volume_ctl_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
int rc = 0;
|
||||
struct snd_pcm_soft_volume *soft_vol = (struct snd_pcm_soft_volume *) snd_kcontrol_chip(kcontrol);
|
||||
struct msm_plat_data *pdata = NULL;
|
||||
struct snd_soc_pcm_runtime *soc_prtd = NULL;
|
||||
struct snd_soc_component *component = NULL;
|
||||
struct snd_pcm_substream *substream = NULL;
|
||||
|
||||
struct msm_audio *prtd;
|
||||
|
||||
if (!soft_vol || !soft_vol->pcm) {
|
||||
pr_err("%s: soft vol is NULL\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
substream = soft_vol->pcm->streams[soft_vol->stream].substream;
|
||||
if (!substream) {
|
||||
pr_err("%s: substream not found\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
soc_prtd = substream->private_data;
|
||||
if (!substream->runtime || !soc_prtd) {
|
||||
pr_err("%s: substream runtime or private_data not found\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME);
|
||||
if (!component || !component->dev) {
|
||||
pr_err("%s: component is NULL\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev);
|
||||
if (!pdata) {
|
||||
pr_err("%s: pdata not found\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
|
||||
if (substream->ref_count > 0) {
|
||||
prtd = substream->runtime->private_data;
|
||||
|
||||
if ( prtd) {
|
||||
if ((ucontrol->value.integer.value[0] < 0) || (ucontrol->value.integer.value[0] > 15000)) {
|
||||
pr_err("%s : Ramp period range (0 to 15000), input value is out of range: %d",__func__,soft_params.period);
|
||||
goto exit;
|
||||
} else {
|
||||
soft_params.period = ucontrol->value.integer.value[0];
|
||||
}
|
||||
if ((ucontrol->value.integer.value[1] < 0) || (ucontrol->value.integer.value[1] > 15000000)) {
|
||||
pr_err("%s : Ramp step range (0 to 15000000), input value is out of range: %d",__func__,soft_params.step);
|
||||
goto exit;
|
||||
} else {
|
||||
soft_params.step = ucontrol->value.integer.value[1];
|
||||
}
|
||||
if ((ucontrol->value.integer.value[2] < 0) || (ucontrol->value.integer.value[2] >= SOFT_VOLUME_CURVE_ENUM_MAX)) {
|
||||
pr_err("%s : Ramping curve range (0 to 2), input value is out of range: %d",__func__,soft_params.rampingcurve);
|
||||
goto exit;
|
||||
} else {
|
||||
soft_params.rampingcurve = ucontrol->value.integer.value[2];
|
||||
}
|
||||
|
||||
pr_debug("%s : soft vol params, period: %d, step: %d, ramp curve: %d",__func__,soft_params.period,
|
||||
soft_params.step,soft_params.rampingcurve);
|
||||
rc = msm_pcm_set_soft_volume_params(prtd, &soft_params);
|
||||
} else {
|
||||
pr_err("%s: prtd not found\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
} else {
|
||||
pr_err("%s: substream ref count is invalid\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
exit:
|
||||
mutex_unlock(&pdata->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_pcm_add_soft_volume_params_control(struct snd_soc_pcm_runtime *rtd, int stream)
|
||||
{
|
||||
int ret = 0;
|
||||
struct snd_pcm *pcm = rtd->pcm;
|
||||
struct snd_pcm_soft_volume *soft_vol = NULL;
|
||||
struct snd_kcontrol *kctl = NULL;
|
||||
|
||||
dev_dbg(rtd->dev, "%s, volume control add\n", __func__);
|
||||
ret = snd_pcm_add_soft_volume_ctls(pcm, stream,
|
||||
NULL,/* 1,*/ rtd->dai_link->id,
|
||||
&soft_vol);
|
||||
if (ret < 0) {
|
||||
pr_err("%s volume control failed ret %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
kctl = soft_vol->kctl;
|
||||
kctl->put = msm_pcm_soft_volume_ctl_put;
|
||||
kctl->get = msm_pcm_soft_volume_ctl_get;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void event_handler(uint32_t opcode,
|
||||
uint32_t token, uint32_t *payload, void *priv)
|
||||
{
|
||||
|
|
@ -3497,6 +3674,16 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
|||
pr_err("%s: Could not add pcm Volume Control %d\n",
|
||||
__func__, ret);
|
||||
ret = msm_pcm_add_volume_control(rtd, SNDRV_PCM_STREAM_CAPTURE);
|
||||
if (ret)
|
||||
pr_err("%s: Could not add pcm Volume Control %d\n",
|
||||
__func__, ret);
|
||||
/* adding soft vol module params mixer control command*/
|
||||
ret = msm_pcm_add_soft_volume_params_control(rtd, SNDRV_PCM_STREAM_PLAYBACK);
|
||||
if (ret)
|
||||
pr_err("%s: Could not add pcm Volume Control %d\n",
|
||||
__func__, ret);
|
||||
|
||||
ret = msm_pcm_add_soft_volume_params_control(rtd, SNDRV_PCM_STREAM_CAPTURE);
|
||||
if (ret)
|
||||
pr_err("%s: Could not add pcm Volume Control %d\n",
|
||||
__func__, ret);
|
||||
|
|
|
|||
|
|
@ -182,6 +182,81 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
|
|||
static void msm_routing_load_topology(size_t data_size, void *data);
|
||||
static void msm_routing_unload_topology(uint32_t topology_id);
|
||||
|
||||
static int pcm_soft_volume_ctl_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = SOFT_VOLUME_CURVE_ENUM_MAX;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = INT_MAX;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcm_soft_volume_ctl_private_free(struct snd_kcontrol *kcontrol)
|
||||
{
|
||||
struct snd_pcm_volume *info = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
int snd_pcm_add_soft_volume_ctls(struct snd_pcm *pcm, int stream,
|
||||
const struct snd_pcm_soft_vol_usr_elem *soft_vol_params,
|
||||
unsigned long private_value,
|
||||
struct snd_pcm_soft_volume **info_ret)
|
||||
{
|
||||
int err = 0;
|
||||
int size = 0;
|
||||
struct snd_pcm_soft_volume *info;
|
||||
struct snd_kcontrol_new knew = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
|
||||
SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||
.info = pcm_soft_volume_ctl_info,
|
||||
};
|
||||
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
info->pcm = pcm;
|
||||
info->stream = stream;
|
||||
info->usr_val = soft_vol_params;
|
||||
size = sizeof("Playback ") + sizeof("Soft Vol Params") +
|
||||
STRING_LENGTH_OF_INT*sizeof(char) + 1;
|
||||
knew.name = kzalloc(size, GFP_KERNEL);
|
||||
if (!knew.name) {
|
||||
kfree(info);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
snprintf((char *)knew.name, size, "%s %d %s",
|
||||
"Playback ", pcm->device, "Soft Vol Params");
|
||||
else
|
||||
snprintf((char *)knew.name, size, "%s %d %s",
|
||||
"Capture", pcm->device, "Soft Vol Params");
|
||||
knew.device = pcm->device;
|
||||
knew.count = pcm->streams[stream].substream_count;
|
||||
knew.private_value = private_value;
|
||||
info->kctl = snd_ctl_new1(&knew, info);
|
||||
if (!info->kctl) {
|
||||
kfree(info);
|
||||
kfree(knew.name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
info->kctl->private_free = pcm_soft_volume_ctl_private_free;
|
||||
err = snd_ctl_add(pcm->card, info->kctl);
|
||||
if (err < 0) {
|
||||
kfree(info);
|
||||
kfree(knew.name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (info_ret)
|
||||
*info_ret = info;
|
||||
kfree(knew.name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_add_soft_volume_ctls);
|
||||
|
||||
#ifndef SND_PCM_ADD_VOLUME_CTL
|
||||
static int pcm_volume_ctl_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
|
|
|
|||
20
asoc/msm-pcm-routing-v2.h
Normal file → Executable file
20
asoc/msm-pcm-routing-v2.h
Normal file → Executable file
|
|
@ -800,6 +800,26 @@ int msm_pcm_routing_set_channel_mixer_runtime(
|
|||
int msm_pcm_routing_set_stream_ec_ref_chmix_cfg(
|
||||
int fedai_id, struct msm_pcm_channel_mixer *cfg_data);
|
||||
|
||||
|
||||
/* array element of usr elem */
|
||||
struct snd_pcm_soft_vol_usr_elem {
|
||||
int val[3];
|
||||
};
|
||||
|
||||
/* mixer control information; retrieved via snd_kcontrol_chip() */
|
||||
struct snd_pcm_soft_volume {
|
||||
struct snd_pcm *pcm; /* assigned PCM instance */
|
||||
int stream; /* PLAYBACK or CAPTURE */
|
||||
struct snd_kcontrol *kctl; /* contorl handle*/
|
||||
const struct snd_pcm_soft_vol_usr_elem *usr_val;
|
||||
int max_length;
|
||||
void *private_data;
|
||||
};
|
||||
|
||||
int snd_pcm_add_soft_volume_ctls(struct snd_pcm *pcm, int stream,
|
||||
const struct snd_pcm_soft_vol_usr_elem *soft_vol_params,
|
||||
unsigned long private_value,
|
||||
struct snd_pcm_soft_volume **info_ret);
|
||||
#ifndef SND_PCM_ADD_VOLUME_CTL
|
||||
/* PCM Volume control API
|
||||
*/
|
||||
|
|
|
|||
2
include/dsp/q6asm-v2.h
Normal file → Executable file
2
include/dsp/q6asm-v2.h
Normal file → Executable file
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2019, 2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef __Q6_ASM_V2_H__
|
||||
#define __Q6_ASM_V2_H__
|
||||
|
|
@ -150,6 +151,7 @@ enum {
|
|||
SOFT_VOLUME_CURVE_LINEAR = 0,
|
||||
SOFT_VOLUME_CURVE_EXP,
|
||||
SOFT_VOLUME_CURVE_LOG,
|
||||
SOFT_VOLUME_CURVE_ENUM_MAX,
|
||||
};
|
||||
|
||||
#define SOFT_VOLUME_INSTANCE_1 1
|
||||
|
|
|
|||
Loading…
Reference in a new issue