msm: audio: qdsp6v2: Enable soft volume command to avoid noise
Add support for soft volume command and enable it to avoid
noise during volume change sequence
CRs-fixed: 304164
Signed-off-by: Swaminathan Sathappan <Swami@codeaurora.org>
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
index 2165953..3225d61 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
@@ -780,22 +780,31 @@
rc = -EFAULT;
goto fail;
} else {
- struct asm_softpause_params param = {
+ struct asm_softpause_params softpause = {
.enable = SOFT_PAUSE_ENABLE,
.period = SOFT_PAUSE_PERIOD,
.step = SOFT_PAUSE_STEP,
.rampingcurve = SOFT_PAUSE_CURVE_LINEAR,
};
+ struct asm_softvolume_params softvol = {
+ .period = SOFT_VOLUME_PERIOD,
+ .step = SOFT_VOLUME_STEP,
+ .rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
+ };
audio->out_enabled = 1;
audio->out_needed = 1;
rc = q6asm_set_volume(audio->ac, audio->volume);
if (rc < 0)
pr_err("%s: Send Volume command failed rc=%d\n",
__func__, rc);
- rc = q6asm_set_softpause(audio->ac, ¶m);
+ rc = q6asm_set_softpause(audio->ac, &softpause);
if (rc < 0)
pr_err("%s: Send SoftPause Param failed rc=%d\n",
__func__, rc);
+ rc = q6asm_set_softvolume(audio->ac, &softvol);
+ if (rc < 0)
+ pr_err("%s: Send SoftVolume Param failed rc=%d\n",
+ __func__, rc);
rc = q6asm_set_lrgain(audio->ac, 0x2000, 0x2000);
if (rc < 0)
pr_err("%s: Send channel gain failed rc=%d\n",
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
index 3c99d08..90d083c 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
@@ -29,6 +29,14 @@
SOFT_PAUSE_CURVE_LOG,
};
+#define SOFT_VOLUME_PERIOD 30 /* ramp up/down for 30ms */
+#define SOFT_VOLUME_STEP 2000 /* Step value 2ms or 2000us */
+enum {
+ SOFT_VOLUME_CURVE_LINEAR = 0,
+ SOFT_VOLUME_CURVE_EXP,
+ SOFT_VOLUME_CURVE_LOG,
+};
+
struct buffer {
void *data;
unsigned size;
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index 27dbfec..514b001 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -517,6 +517,7 @@
#define L_R_CHANNEL_GAIN_PARAM_ID 0x00010c00
#define MUTE_CONFIG_PARAM_ID 0x00010c01
#define SOFT_PAUSE_PARAM_ID 0x00010D6A
+#define SOFT_VOLUME_PARAM_ID 0x00010C29
#define IIR_FILTER_ENABLE_PARAM_ID 0x00010c03
#define IIR_FILTER_PREGAIN_PARAM_ID 0x00010c04
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index 13e2846..b864f2f 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -241,6 +241,10 @@
int q6asm_set_softpause(struct audio_client *ac,
struct asm_softpause_params *param);
+/* Set Softvolume Params */
+int q6asm_set_softvolume(struct audio_client *ac,
+ struct asm_softvolume_params *param);
+
/* Send left-right channel gain */
int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain);
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 96d49a3..0f478fc 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -2217,6 +2217,70 @@
return rc;
}
+int q6asm_set_softvolume(struct audio_client *ac,
+ struct asm_softvolume_params *softvol_param)
+{
+ void *vol_cmd = NULL;
+ void *payload = NULL;
+ struct asm_pp_params_command *cmd = NULL;
+ struct asm_softvolume_params *params = NULL;
+ int sz = 0;
+ int rc = 0;
+
+ sz = sizeof(struct asm_pp_params_command) +
+ + sizeof(struct asm_softvolume_params);
+ vol_cmd = kzalloc(sz, GFP_KERNEL);
+ if (vol_cmd == NULL) {
+ pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
+ rc = -EINVAL;
+ return rc;
+ }
+ cmd = (struct asm_pp_params_command *)vol_cmd;
+ q6asm_add_hdr_async(ac, &cmd->hdr, sz, TRUE);
+ cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
+ cmd->payload = NULL;
+ cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
+ sizeof(struct asm_softvolume_params);
+ cmd->params.module_id = VOLUME_CONTROL_MODULE_ID;
+ cmd->params.param_id = SOFT_VOLUME_PARAM_ID;
+ cmd->params.param_size = sizeof(struct asm_softvolume_params);
+ cmd->params.reserved = 0;
+
+ payload = (u8 *)(vol_cmd + sizeof(struct asm_pp_params_command));
+ params = (struct asm_softvolume_params *)payload;
+
+ params->period = softvol_param->period;
+ params->step = softvol_param->step;
+ params->rampingcurve = softvol_param->rampingcurve;
+ pr_debug("%s: soft Volume:opcode = %d,payload_sz =%d,module_id =%d,"
+ "param_id = %d, param_sz = %d\n", __func__,
+ cmd->hdr.opcode, cmd->payload_size,
+ cmd->params.module_id, cmd->params.param_id,
+ cmd->params.param_size);
+ pr_debug("%s: soft Volume Command: period = %d,"
+ "step = %d, curve = %d\n", __func__, params->period,
+ params->step, params->rampingcurve);
+ rc = apr_send_pkt(ac->apr, (uint32_t *) vol_cmd);
+ if (rc < 0) {
+ pr_err("%s: Volume Command(soft_volume) failed\n", __func__);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) == 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s: timeout in sending volume command(soft_volume)"
+ "to apr\n", __func__);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ rc = 0;
+fail_cmd:
+ kfree(vol_cmd);
+ return rc;
+}
+
int q6asm_equalizer(struct audio_client *ac, void *eq)
{
void *eq_cmd = NULL;