ASoC: msm: qdsp6v2: Add control for ICC Volume
Add control via ADM set PP Params to control volume of ICC through a mixer command "Internal ICC Volume". CRs-fixed: 1025376 Change-Id: I2b7099fe6d3a510859af42f1ac37a6db6e1b453c Signed-off-by: Derek Chen <chenche@codeaurora.org>
This commit is contained in:
parent
08a95e6878
commit
b5e3d1e282
4 changed files with 117 additions and 1 deletions
|
@ -6768,6 +6768,12 @@ struct admx_mic_gain {
|
|||
/*< Clients must set this field to zero. */
|
||||
} __packed;
|
||||
|
||||
struct adm_set_mic_gain_params {
|
||||
struct adm_cmd_set_pp_params_v5 params;
|
||||
struct adm_param_data_v5 data;
|
||||
struct admx_mic_gain mic_gain_data;
|
||||
} __packed;
|
||||
|
||||
/* end_addtogroup audio_pp_param_ids */
|
||||
|
||||
/* @ingroup audio_pp_module_ids
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -130,6 +130,8 @@ int adm_set_volume(int port_id, int copp_idx, int volume);
|
|||
int adm_set_softvolume(int port_id, int copp_idx,
|
||||
struct audproc_softvolume_params *softvol_param);
|
||||
|
||||
int adm_set_mic_gain(int port_id, int copp_idx, int volume);
|
||||
|
||||
int adm_param_enable(int port_id, int copp_idx, int module_id, int enable);
|
||||
|
||||
int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode,
|
||||
|
|
|
@ -81,6 +81,10 @@ static int msm_route_hfp_vol_control;
|
|||
static const DECLARE_TLV_DB_LINEAR(hfp_rx_vol_gain, 0,
|
||||
INT_RX_VOL_MAX_STEPS);
|
||||
|
||||
static int msm_route_icc_vol_control;
|
||||
static const DECLARE_TLV_DB_LINEAR(icc_rx_vol_gain, 0,
|
||||
INT_RX_VOL_MAX_STEPS);
|
||||
|
||||
static int msm_route_pri_auxpcm_lb_vol_ctrl;
|
||||
static const DECLARE_TLV_DB_LINEAR(pri_auxpcm_lb_vol_gain, 0,
|
||||
INT_RX_VOL_MAX_STEPS);
|
||||
|
@ -493,6 +497,23 @@ static int msm_qti_pp_set_slimbus_8_lb_vol_mixer(struct snd_kcontrol *kcontrol,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int msm_qti_pp_get_icc_vol_mixer(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.integer.value[0] = msm_route_icc_vol_control;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_qti_pp_set_icc_vol_mixer(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
adm_set_mic_gain(AFE_PORT_ID_QUATERNARY_TDM_TX,
|
||||
adm_get_default_copp_idx(AFE_PORT_ID_QUATERNARY_TDM_TX),
|
||||
ucontrol->value.integer.value[0]);
|
||||
msm_route_icc_vol_control = ucontrol->value.integer.value[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_qti_pp_get_quat_mi2s_fm_vol_mixer(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
@ -809,6 +830,12 @@ static const struct snd_kcontrol_new int_hfp_vol_mixer_controls[] = {
|
|||
msm_qti_pp_set_hfp_vol_mixer, hfp_rx_vol_gain),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new int_icc_vol_mixer_controls[] = {
|
||||
SOC_SINGLE_EXT_TLV("Internal ICC Volume", SND_SOC_NOPM, 0,
|
||||
INT_RX_VOL_GAIN, 0, msm_qti_pp_get_icc_vol_mixer,
|
||||
msm_qti_pp_set_icc_vol_mixer, icc_rx_vol_gain),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new pri_auxpcm_lb_vol_mixer_controls[] = {
|
||||
SOC_SINGLE_EXT_TLV("PRI AUXPCM LOOPBACK Volume",
|
||||
AFE_PORT_ID_PRIMARY_PCM_TX, 0, INT_RX_VOL_GAIN, 0,
|
||||
|
@ -1001,6 +1028,9 @@ void msm_qti_pp_add_controls(struct snd_soc_platform *platform)
|
|||
snd_soc_add_platform_controls(platform, int_hfp_vol_mixer_controls,
|
||||
ARRAY_SIZE(int_hfp_vol_mixer_controls));
|
||||
|
||||
snd_soc_add_platform_controls(platform, int_icc_vol_mixer_controls,
|
||||
ARRAY_SIZE(int_icc_vol_mixer_controls));
|
||||
|
||||
snd_soc_add_platform_controls(platform,
|
||||
pri_auxpcm_lb_vol_mixer_controls,
|
||||
ARRAY_SIZE(pri_auxpcm_lb_vol_mixer_controls));
|
||||
|
|
|
@ -3471,6 +3471,84 @@ fail_cmd:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int adm_set_mic_gain(int port_id, int copp_idx, int volume)
|
||||
{
|
||||
struct adm_set_mic_gain_params mic_gain_params;
|
||||
int rc = 0;
|
||||
int sz, port_idx;
|
||||
|
||||
pr_debug("%s:\n", __func__);
|
||||
port_id = afe_convert_virtual_to_portid(port_id);
|
||||
port_idx = adm_validate_and_get_port_index(port_id);
|
||||
if (port_idx < 0) {
|
||||
pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sz = sizeof(struct adm_set_mic_gain_params);
|
||||
|
||||
mic_gain_params.params.hdr.hdr_field =
|
||||
APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
|
||||
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
|
||||
mic_gain_params.params.hdr.pkt_size = sz;
|
||||
mic_gain_params.params.hdr.src_svc = APR_SVC_ADM;
|
||||
mic_gain_params.params.hdr.src_domain = APR_DOMAIN_APPS;
|
||||
mic_gain_params.params.hdr.src_port = port_id;
|
||||
mic_gain_params.params.hdr.dest_svc = APR_SVC_ADM;
|
||||
mic_gain_params.params.hdr.dest_domain = APR_DOMAIN_ADSP;
|
||||
mic_gain_params.params.hdr.dest_port =
|
||||
atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
|
||||
mic_gain_params.params.hdr.token = port_idx << 16 | copp_idx;
|
||||
mic_gain_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
|
||||
mic_gain_params.params.payload_addr_lsw = 0;
|
||||
mic_gain_params.params.payload_addr_msw = 0;
|
||||
mic_gain_params.params.mem_map_handle = 0;
|
||||
mic_gain_params.params.payload_size =
|
||||
sizeof(struct adm_param_data_v5) +
|
||||
sizeof(struct admx_mic_gain);
|
||||
mic_gain_params.data.module_id = ADM_MODULE_IDX_MIC_GAIN_CTRL;
|
||||
mic_gain_params.data.param_id = ADM_PARAM_IDX_MIC_GAIN;
|
||||
mic_gain_params.data.param_size =
|
||||
sizeof(struct admx_mic_gain);
|
||||
mic_gain_params.data.reserved = 0;
|
||||
mic_gain_params.mic_gain_data.tx_mic_gain = volume;
|
||||
mic_gain_params.mic_gain_data.reserved = 0;
|
||||
pr_debug("%s: Mic Gain set to %d at port_id 0x%x\n",
|
||||
__func__, volume, port_id);
|
||||
|
||||
atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
|
||||
rc = apr_send_pkt(this_adm.apr, (uint32_t *)&mic_gain_params);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: Set params failed port = %#x\n",
|
||||
__func__, port_id);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
}
|
||||
/* Wait for the callback */
|
||||
rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
|
||||
atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
|
||||
msecs_to_jiffies(TIMEOUT_MS));
|
||||
if (!rc) {
|
||||
pr_err("%s: Mic Gain Set params timed out port = %#x\n",
|
||||
__func__, port_id);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
} else if (atomic_read(&this_adm.copp.stat
|
||||
[port_idx][copp_idx]) > 0) {
|
||||
pr_err("%s: DSP returned error[%s]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&this_adm.copp.stat
|
||||
[port_idx][copp_idx])));
|
||||
rc = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&this_adm.copp.stat
|
||||
[port_idx][copp_idx]));
|
||||
goto fail_cmd;
|
||||
}
|
||||
rc = 0;
|
||||
fail_cmd:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int adm_param_enable(int port_id, int copp_idx, int module_id, int enable)
|
||||
{
|
||||
struct audproc_enable_param_t adm_mod_enable;
|
||||
|
|
Loading…
Add table
Reference in a new issue