Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2eded392 authored by Subhash Chandra Bose Naripeddy's avatar Subhash Chandra Bose Naripeddy
Browse files

ASoC: msm: qdsp6v2: Hardware accelerated effects helper routines



Audio post processing features such as HeadphoneX are supported
only in DSP. To apply post processing for the playback which is
not routed through DSP, effects are applied through hardware
accelerated mode where PCM samples are sent to DSP for effects
processing in write path and captured by userspace through read
path. Enhance the audio effects and q6asm api to support the
hardware accelerated audio post processing.

Change-Id: I11e94d998a155ada4095085ebc3a54088ceb4db6
Signed-off-by: default avatarSubhash Chandra Bose Naripeddy <snariped@codeaurora.org>
parent e92aa60f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5686,6 +5686,7 @@ struct adm_qensemble_param_set_new_angle {
 * - #ASM_PARAM_ID_MULTICHANNEL_MUTE
 */
#define ASM_MODULE_ID_VOL_CTRL   0x00010BFE
#define ASM_MODULE_ID_VOL_CTRL2  0x00010910

/* @addtogroup audio_pp_param_ids */
/* ID of the master gain parameter used by the #ASM_MODULE_ID_VOL_CTRL
+9 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2014, 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
@@ -30,4 +30,12 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
					 struct eq_params *eq,
					 long *values);

int msm_audio_effects_volume_handler(struct audio_client *ac,
				     struct soft_volume_params *vol,
				     long *values);

int msm_audio_effects_volume_handler_v2(struct audio_client *ac,
					struct soft_volume_params *vol,
					long *values, int instance);
#endif /*_MSM_AUDIO_EFFECTS_H*/
+17 −1
Original line number Diff line number Diff line
@@ -118,6 +118,9 @@ enum {
	SOFT_VOLUME_CURVE_LOG,
};

#define SOFT_VOLUME_INSTANCE_1	1
#define SOFT_VOLUME_INSTANCE_2	2

typedef void (*app_cb)(uint32_t opcode, uint32_t token,
			uint32_t *payload, void *priv);

@@ -183,6 +186,7 @@ struct audio_client {
	int                    perf_mode;
	int					   stream_id;
	struct device *dev;
	int		       topology;
	/* audio cache operations fptr*/
	int (*fptr_cache_ops)(struct audio_buffer *abuff, int cache_op);
	atomic_t               unmap_cb_success;
@@ -228,6 +232,11 @@ int q6asm_open_read_write(struct audio_client *ac,
			uint32_t rd_format,
			uint32_t wr_format);

int q6asm_open_read_write_v2(struct audio_client *ac, uint32_t rd_format,
			     uint32_t wr_format, bool is_meta_data_mode,
			     uint32_t bits_per_sample, bool overwrite_topology,
			     int topology);

int q6asm_open_loopback_v2(struct audio_client *ac,
			   uint16_t bits_per_sample);

@@ -243,6 +252,7 @@ int q6asm_async_read(struct audio_client *ac,
					  struct audio_aio_read_param *param);

int q6asm_read(struct audio_client *ac);
int q6asm_read_v2(struct audio_client *ac, uint32_t len);
int q6asm_read_nolock(struct audio_client *ac);

int q6asm_memory_map(struct audio_client *ac, phys_addr_t buf_add,
@@ -379,11 +389,13 @@ int q6asm_equalizer(struct audio_client *ac, void *eq);
/* Send Volume Command */
int q6asm_set_volume(struct audio_client *ac, int volume);

/* Send Volume Command */
int q6asm_set_volume_v2(struct audio_client *ac, int volume, int instance);

int q6asm_dts_eagle_set(struct audio_client *ac, int param_id, int size,
			void *data);
int q6asm_dts_eagle_get(struct audio_client *ac, int param_id,
			int size, void *data);

/* Set SoftPause Params */
int q6asm_set_softpause(struct audio_client *ac,
			struct asm_softpause_params *param);
@@ -392,6 +404,10 @@ int q6asm_set_softpause(struct audio_client *ac,
int q6asm_set_softvolume(struct audio_client *ac,
			struct asm_softvolume_params *param);

/* Set Softvolume Params */
int q6asm_set_softvolume_v2(struct audio_client *ac,
			    struct asm_softvolume_params *param, int instance);

/* Send left-right channel gain */
int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain);

+31 −0
Original line number Diff line number Diff line
@@ -153,6 +153,23 @@ struct dts_eagle_param_desc {
	__u32 device;
} __packed;

#define SOFT_VOLUME_MODULE		0x00006000
#define SOFT_VOLUME_ENABLE		0x00006001
#define SOFT_VOLUME_GAIN_2CH		0x00006002
#define SOFT_VOLUME_GAIN_MASTER		0x00006003
#define SOFT_VOLUME_ENABLE_PARAM_LEN		1
#define SOFT_VOLUME_GAIN_2CH_PARAM_LEN		2
#define SOFT_VOLUME_GAIN_MASTER_PARAM_LEN	1

#define SOFT_VOLUME2_MODULE		0x00007000
#define SOFT_VOLUME2_ENABLE		0x00007001
#define SOFT_VOLUME2_GAIN_2CH		0x00007002
#define SOFT_VOLUME2_GAIN_MASTER	0x00007003
#define SOFT_VOLUME2_ENABLE_PARAM_LEN		SOFT_VOLUME_ENABLE_PARAM_LEN
#define SOFT_VOLUME2_GAIN_2CH_PARAM_LEN		SOFT_VOLUME_GAIN_2CH_PARAM_LEN
#define SOFT_VOLUME2_GAIN_MASTER_PARAM_LEN	\
					SOFT_VOLUME_GAIN_MASTER_PARAM_LEN

#define COMMAND_PAYLOAD_LEN	3
#define COMMAND_PAYLOAD_SZ	(COMMAND_PAYLOAD_LEN * sizeof(uint32_t))
#define MAX_INBAND_PARAM_SZ	4096
@@ -298,4 +315,18 @@ struct eq_params {
	uint32_t freq_millihertz;
};

#define SOFT_VOLUME_ENABLE_PARAM_SZ		\
			(SOFT_VOLUME_ENABLE_PARAM_LEN*sizeof(uint32_t))
#define SOFT_VOLUME_GAIN_MASTER_PARAM_SZ	\
			(SOFT_VOLUME_GAIN_MASTER_PARAM_LEN*sizeof(uint32_t))
#define SOFT_VOLUME_GAIN_2CH_PARAM_SZ		\
			(SOFT_VOLUME_GAIN_2CH_PARAM_LEN*sizeof(uint16_t))
struct soft_volume_params {
	uint32_t device;
	uint32_t enable_flag;
	uint32_t master_gain;
	uint32_t left_gain;
	uint32_t right_gain;
};

#endif /*_MSM_AUDIO_EFFECTS_H*/
+142 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
#include <sound/apr_audio-v2.h>
#include <sound/q6asm-v2.h>
#include <sound/compress_params.h>
#include "msm-audio-effects-q6-v2.h"
#include <sound/msm-audio-effects-q6-v2.h>

int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
				struct virtualizer_params *virtualizer,
@@ -745,3 +745,144 @@ invalid_config:
	kfree(params);
	return rc;
}

static int __msm_audio_effects_volume_handler(struct audio_client *ac,
					      struct soft_volume_params *vol,
					      long *values,
					      int instance)
{
	int devices;
	int num_commands;
	char *params;
	int *updt_params, i;
	uint32_t params_length = (MAX_INBAND_PARAM_SZ);
	int rc = 0;

	pr_debug("%s: instance: %d\n", __func__, instance);
	if (!values) {
		pr_err("%s: set audio effects failed, no valid data\n",
			__func__);
		return -EINVAL;
	}
	if (!ac) {
		pr_err("%s: cannot set audio effects as audio client is NULL\n",
			__func__);
		return -EINVAL;
	}
	params = kzalloc(params_length, GFP_KERNEL);
	if (!params) {
		pr_err("%s, params memory alloc failed\n", __func__);
		return -ENOMEM;
	}
	devices = *values++;
	num_commands = *values++;
	updt_params = (int *)params;
	params_length = 0;
	for (i = 0; i < num_commands; i++) {
		uint32_t command_id = *values++;
		uint32_t command_config_state = *values++;
		uint32_t index_offset = *values++;
		uint32_t length = *values++;
		switch (command_id) {
		case SOFT_VOLUME_GAIN_2CH:
		case SOFT_VOLUME2_GAIN_2CH:
			if (length != 2 || index_offset != 0) {
				pr_err("VOLUME_GAIN_2CH/VOLUME2_GAIN_2CH:invalid params\n");
				rc = -EINVAL;
				goto invalid_config;
			}
			vol->left_gain = *values++;
			vol->right_gain = *values++;
			vol->master_gain = 0x2000;
			if (command_config_state == CONFIG_SET) {
				if (instance == SOFT_VOLUME_INSTANCE_2)
					*updt_params++ =
							ASM_MODULE_ID_VOL_CTRL2;
				else
					*updt_params++ = ASM_MODULE_ID_VOL_CTRL;
				*updt_params++ =
					ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN;
				*updt_params++ = SOFT_VOLUME_GAIN_2CH_PARAM_SZ;
				*updt_params++ = (vol->left_gain << 16) |
						 vol->right_gain;
				params_length += COMMAND_PAYLOAD_SZ +
						SOFT_VOLUME_GAIN_2CH_PARAM_SZ;
				if (instance == SOFT_VOLUME_INSTANCE_2)
					*updt_params++ =
							ASM_MODULE_ID_VOL_CTRL2;
				else
					*updt_params++ = ASM_MODULE_ID_VOL_CTRL;
				*updt_params++ =
					ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN;
				*updt_params++ =
					SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
				*updt_params++ = vol->master_gain;
				params_length += COMMAND_PAYLOAD_SZ +
					SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
			}
			break;
		case SOFT_VOLUME_GAIN_MASTER:
		case SOFT_VOLUME2_GAIN_MASTER:
			if (length != 1 || index_offset != 0) {
				pr_err("VOLUME_GAIN_MASTER/VOLUME2_GAIN_MASTER:invalid params\n");
				rc = -EINVAL;
				goto invalid_config;
			}
			vol->left_gain = 0x2000;
			vol->right_gain = 0x2000;
			vol->master_gain = *values++;
			if (command_config_state == CONFIG_SET) {
				if (instance == SOFT_VOLUME_INSTANCE_2)
					*updt_params++ =
							ASM_MODULE_ID_VOL_CTRL2;
				else
					*updt_params++ = ASM_MODULE_ID_VOL_CTRL;
				*updt_params++ =
					ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN;
				*updt_params++ = SOFT_VOLUME_GAIN_2CH_PARAM_SZ;
				*updt_params++ = (vol->left_gain << 16) |
						 vol->right_gain;
				params_length += COMMAND_PAYLOAD_SZ +
						SOFT_VOLUME_GAIN_2CH_PARAM_SZ;
				if (instance == SOFT_VOLUME_INSTANCE_2)
					*updt_params++ =
							ASM_MODULE_ID_VOL_CTRL2;
				else
					*updt_params++ = ASM_MODULE_ID_VOL_CTRL;
				*updt_params++ =
					ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN;
				*updt_params++ =
					SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
				*updt_params++ = vol->master_gain;
				params_length += COMMAND_PAYLOAD_SZ +
					SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
			}
			break;
		default:
			pr_err("%s: Invalid command id: %d to set config\n",
				__func__, command_id);
			break;
		}
	}
	if (params_length)
		q6asm_send_audio_effects_params(ac, params,
						params_length);
invalid_config:
	kfree(params);
	return rc;
}

int msm_audio_effects_volume_handler(struct audio_client *ac,
				     struct soft_volume_params *vol,
				     long *values)
{
	return __msm_audio_effects_volume_handler(ac, vol, values,
						  SOFT_VOLUME_INSTANCE_1);
}

int msm_audio_effects_volume_handler_v2(struct audio_client *ac,
					struct soft_volume_params *vol,
					long *values, int instance)
{
	return __msm_audio_effects_volume_handler(ac, vol, values, instance);
}
Loading