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

Commit d8f65739 authored by Anish Kumar's avatar Anish Kumar
Browse files

ASoC: msm: qdsp6v2: add speaker protection module id



stereo speaker protection libraray in ADSP needs
new param and module id's. Provide the same along
with passing new set of calibration data for each
speaker connected to the codec.

Change-Id: I3bb1e9788ea8b6ce8e4debfe882f7bbaed58493d
Signed-off-by: default avatarAnish Kumar <kanish@codeaurora.org>
parent 4ee8d97c
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@

#define ADM_MAX_COPPS 5

/* make sure this matches with msm_audio_calibration */
#define SP_V2_NUM_MAX_SPKR 2

/*  Session map node structure.
*	Immediately following this structure are num_copps
@@ -6860,8 +6862,10 @@ struct cmd_set_topologies {
 */

#define AFE_MODULE_FB_SPKR_PROT_RX 0x0001021C
#define AFE_MODULE_FB_SPKR_PROT_V2_RX 0x0001025F

#define AFE_PARAM_ID_FBSP_MODE_RX_CFG 0x0001021D
#define AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG 0x00010260

struct asm_fbsp_mode_rx_cfg {
	uint32_t minor_version;
@@ -6878,25 +6882,31 @@ struct asm_fbsp_mode_rx_cfg {
 */

#define AFE_MODULE_FB_SPKR_PROT_VI_PROC 0x00010226
#define AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2 0x0001026A

#define AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG 0x0001022A
#define AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2  0x0001026B

struct asm_spkr_calib_vi_proc_cfg {
	uint32_t minor_version;
	int32_t	r0_cali_q24;
	int16_t	t0_cali_q6;
	int16_t	reserved;
	uint32_t operation_mode;
	uint32_t r0_t0_selection_flag[SP_V2_NUM_MAX_SPKR];
	int32_t r0_cali_q24[SP_V2_NUM_MAX_SPKR];
	int16_t	t0_cali_q6[SP_V2_NUM_MAX_SPKR];
	uint32_t quick_calib_flag;
} __packed;

#define AFE_PARAM_ID_CALIB_RES_CFG 0x0001022B
#define AFE_PARAM_ID_CALIB_RES_CFG_V2 0x0001026E

struct asm_calib_res_cfg {
	uint32_t minor_version;
	int32_t	r0_cali_q24;
	int32_t	r0_cali_q24[SP_V2_NUM_MAX_SPKR];
	uint32_t th_vi_ca_state;
} __packed;

#define AFE_PARAM_ID_FEEDBACK_PATH_CFG 0x0001022C
#define AFE_MODULE_FEEDBACK 0x00010257

struct asm_feedback_path_cfg {
	uint32_t minor_version;
+10 −3
Original line number Diff line number Diff line
@@ -249,16 +249,23 @@ enum msm_spkr_prot_states {
	MSM_SPKR_PROT_NOT_CALIBRATED
};

enum msm_spkr_count {
	SP_V2_SPKR_1,
	SP_V2_SPKR_2,
	SP_V2_NUM_MAX_SPKRS
};

struct audio_cal_info_spk_prot_cfg {
	int32_t		r0;
	int32_t		t0;
	int32_t		r0[SP_V2_NUM_MAX_SPKRS];
	int32_t		t0[SP_V2_NUM_MAX_SPKRS];
	uint32_t	quick_calib_flag;
	uint32_t	mode; /*0 - Start spk prot
	1 - Start calib
	2 - Disable spk prot*/
};

struct audio_cal_info_msm_spk_prot_status {
	int32_t		r0;
	int32_t		r0[SP_V2_NUM_MAX_SPKRS];
	int32_t		status;
};

+70 −1
Original line number Diff line number Diff line
@@ -88,7 +88,6 @@ static const char * const mad_audio_mux_text[] = {
	TERT_MI2S_TX_TEXT
};


static void msm_pcm_routing_cfg_pp(int port_id, int copp_idx, int topology,
				   int channels)
{
@@ -3739,6 +3738,44 @@ static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol,
	return ret;
}

static int spkr_prot_put_vi_rch_port(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	int ret = 0;
	int item;
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	pr_debug("%s item is %d\n", __func__,
			ucontrol->value.enumerated.item[0]);
	mutex_lock(&routing_lock);
	item = ucontrol->value.enumerated.item[0];
	if (item < e->max) {
		pr_debug("%s RX DAI ID %d TX DAI id %d\n",
				__func__, e->shift_l , e->values[item]);
		if (e->shift_l < MSM_BACKEND_DAI_MAX &&
				e->values[item] < MSM_BACKEND_DAI_MAX)
			/* Enable feedback TX path */
			ret = afe_spk_prot_feed_back_cfg(
					msm_bedais[e->values[item]].port_id,
					msm_bedais[e->shift_l].port_id,
					1, 1, 1);
		else {
			pr_debug("%s values are out of range item %d\n",
					__func__, e->values[item]);
			/* Disable feedback TX path */
			if (e->values[item] == MSM_BACKEND_DAI_MAX)
				ret = afe_spk_prot_feed_back_cfg(0,
						0, 0, 0, 0);
			else
				ret = -EINVAL;
		}
	} else {
		pr_err("%s item value is out of range item\n", __func__);
		ret = -EINVAL;
	}
	mutex_unlock(&routing_lock);
	return ret;
}

static int spkr_prot_get_vi_lch_port(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
@@ -3746,23 +3783,50 @@ static int spkr_prot_get_vi_lch_port(struct snd_kcontrol *kcontrol,
	return 0;
}

static int spkr_prot_get_vi_rch_port(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	pr_debug("%s\n", __func__);
	ucontrol->value.enumerated.item[0] = 0;
	return 0;
}

static const char * const slim0_rx_vi_fb_tx_lch_mux_text[] = {
	"ZERO", "SLIM4_TX"
};

static const char * const slim0_rx_vi_fb_tx_rch_mux_text[] = {
	"ZERO", "SLIM4_TX"
};

static const int const slim0_rx_vi_fb_tx_lch_value[] = {
	MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX
};

static const int const slim0_rx_vi_fb_tx_rch_value[] = {
	MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX
};

static const struct soc_enum slim0_rx_vi_fb_lch_mux_enum =
	SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0,
	ARRAY_SIZE(slim0_rx_vi_fb_tx_lch_mux_text),
	slim0_rx_vi_fb_tx_lch_mux_text, slim0_rx_vi_fb_tx_lch_value);

static const struct soc_enum slim0_rx_vi_fb_rch_mux_enum =
	SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0,
	ARRAY_SIZE(slim0_rx_vi_fb_tx_rch_mux_text),
	slim0_rx_vi_fb_tx_rch_mux_text, slim0_rx_vi_fb_tx_rch_value);

static const struct snd_kcontrol_new slim0_rx_vi_fb_lch_mux =
	SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_LCH_MUX",
	slim0_rx_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port,
	spkr_prot_put_vi_lch_port);

static const struct snd_kcontrol_new slim0_rx_vi_fb_rch_mux =
	SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_RCH_MUX",
	slim0_rx_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port,
	spkr_prot_put_vi_rch_port);

static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
	/* Frontend AIF */
	/* Widget name equals to Front-End DAI name<Need confirmation>,
@@ -4176,6 +4240,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {

	SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0,
				&slim0_rx_vi_fb_lch_mux),
	SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0,
				&slim0_rx_vi_fb_rch_mux),

	SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0,
			 &voc_ext_ec_mux),
	SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL1 MUX", SND_SOC_NOPM, 0, 0,
@@ -5061,7 +5128,9 @@ static const struct snd_soc_dapm_route intercon[] = {
	{"INCALL_RECORD_TX", NULL, "BE_IN"},
	{"INCALL_RECORD_RX", NULL, "BE_IN"},
	{"SLIM0_RX_VI_FB_LCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"},
	{"SLIM0_RX_VI_FB_RCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"},
	{"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_LCH_MUX"},
	{"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_RCH_MUX"},
};

static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
+180 −42
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/jiffies.h>
#include <linux/sched.h>
#include <linux/msm_audio_ion.h>
#include <linux/delay.h>
#include <sound/apr_audio-v2.h>
#include <sound/q6afe-v2.h>
#include <sound/q6audio-v2.h>
@@ -34,6 +35,35 @@ enum {
	MAX_AFE_CAL_TYPES
};

enum calibration_state {
	CALIB_INCORRECT_OP_MODE,
	CALIB_INACTIVE,
	CALIB_WARMUP,
	CALIB_IN_PROGRESS,
	CALIB_SUCCESS,
	CALIB_FAILED,
	MAX_CALIB_STATE
};

static char cali_state[MAX_CALIB_STATE][50] = {
	[CALIB_INCORRECT_OP_MODE] = "incorrect operation mode",
	[CALIB_INACTIVE] = "port not started",
	[CALIB_WARMUP] = "waiting for warmup",
	[CALIB_IN_PROGRESS] = "in calibration state",
	[CALIB_SUCCESS] = "success",
	[CALIB_FAILED] = "failed"
};

enum {
	USE_CALIBRATED_R0TO,
	USE_SAFE_R0TO
};

enum {
	QUICK_CALIB_DISABLE,
	QUICK_CALIB_ENABLE
};

struct afe_ctl {
	void *apr;
	atomic_t state;
@@ -160,9 +190,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
			   sizeof(this_afe.calib_data));
		if (!this_afe.calib_data.status) {
			atomic_set(&this_afe.state, 0);
			pr_err("%s: rest = %d state = 0x%x\n", __func__
			, this_afe.calib_data.res_cfg.r0_cali_q24,
			this_afe.calib_data.res_cfg.th_vi_ca_state);
			pr_err("%s: rest = %d %d state = %s\n", __func__
			, this_afe.calib_data.res_cfg.r0_cali_q24[SP_V2_SPKR_1],
			this_afe.calib_data.res_cfg.r0_cali_q24[SP_V2_SPKR_2],
			cali_state[this_afe.calib_data.res_cfg.th_vi_ca_state]);
		} else
			atomic_set(&this_afe.state, -1);
		wake_up(&this_afe.wait[data->token]);
@@ -483,6 +514,73 @@ done:
	return result;
}

static int afe_spk_ramp_dn_cfg(int port)
{
	int ret = -EINVAL;
	int index = 0;
	struct afe_spkr_prot_config_command config;

	if (afe_get_port_type(port) != MSM_AFE_PORT_TYPE_RX) {
		pr_debug("%s: port doesn't match 0x%x\n", __func__, port);
		return 0;
	}
	if (this_afe.prot_cfg.mode == MSM_SPKR_PROT_DISABLED) {
		pr_debug("%s: spkr protection disabled port 0x%x %d\n",
				__func__, port, ret);
		return 0;
	}
	memset(&config, 0 , sizeof(config));
	ret = q6audio_validate_port(port);
	if (ret < 0) {
		pr_err("%s: Invalid port 0x%x ret %d", __func__, port, ret);
		ret = -EINVAL;
		goto fail_cmd;
	}
	index = q6audio_get_port_index(port);
	config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
			APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
	config.hdr.pkt_size = sizeof(config);
	config.hdr.src_port = 0;
	config.hdr.dest_port = 0;
	config.hdr.token = index;

	config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
	config.param.port_id = q6audio_get_port_id(port);
	config.param.payload_size =
		sizeof(config) - sizeof(config.hdr) - sizeof(config.param)
		- sizeof(config.prot_config);
	config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
	config.pdata.param_id = AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG;
	config.pdata.param_size = 0;
	atomic_set(&this_afe.state, 1);
	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
	if (ret < 0) {
		pr_err("%s: port = 0x%x param = 0x%x failed %d\n",
				__func__, port, config.pdata.param_id, ret);
		goto fail_cmd;
	}
	ret = wait_event_timeout(this_afe.wait[index],
			(atomic_read(&this_afe.state) == 0),
			msecs_to_jiffies(TIMEOUT_MS));
	if (!ret) {
		pr_err("%s: wait_event timeout\n", __func__);
		ret = -EINVAL;
		goto fail_cmd;
	}
	if (atomic_read(&this_afe.status) != 0) {
		pr_err("%s: config cmd failed\n", __func__);
		ret = -EINVAL;
		goto fail_cmd;
	}
	/* dsp needs atleast 15ms to ramp down pilot tone*/
	usleep_range(15000, 15010);
	ret = 0;
fail_cmd:
	pr_debug("%s: config.pdata.param_id 0x%x status %d\n",
		__func__, config.pdata.param_id, ret);
return ret;
}

static int afe_spk_prot_prepare(int port, int param_id,
		union afe_spkr_prot_config *prot_config)
{
@@ -504,13 +602,14 @@ static int afe_spk_prot_prepare(int port, int param_id,
	index = q6audio_get_port_index(port);
	switch (param_id) {
	case AFE_PARAM_ID_FBSP_MODE_RX_CFG:
		config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_RX;
		config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
		break;
	case AFE_PARAM_ID_FEEDBACK_PATH_CFG:
		this_afe.vi_tx_port = port;
	case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG:
	case AFE_PARAM_ID_MODE_VI_PROC_CFG:
		config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC;
		config.pdata.module_id = AFE_MODULE_FEEDBACK;
		break;
	case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2:
		config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
		break;
	default:
		pr_err("%s: default case 0x%x\n", __func__, param_id);
@@ -572,29 +671,45 @@ static void afe_send_cal_spkr_prot_tx(int port_id)
		(this_afe.vi_tx_port == port_id)) {
		afe_spk_config.mode_rx_cfg.minor_version = 1;
		if (this_afe.prot_cfg.mode ==
			MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
			afe_spk_config.mode_rx_cfg.mode =
			MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) {
			afe_spk_config.vi_proc_cfg.operation_mode =
					Q6AFE_MSM_SPKR_CALIBRATION;
		else
			afe_spk_config.mode_rx_cfg.mode =
			afe_spk_config.vi_proc_cfg.quick_calib_flag =
					this_afe.prot_cfg.quick_calib_flag;
		} else {
			afe_spk_config.vi_proc_cfg.operation_mode =
					    Q6AFE_MSM_SPKR_PROCESSING;
		if (afe_spk_prot_prepare(port_id,
			AFE_PARAM_ID_MODE_VI_PROC_CFG,
			&afe_spk_config))
			pr_err("%s: TX VI_PROC_CFG failed\n", __func__);
		if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_NOT_CALIBRATED) {
		}
		afe_spk_config.vi_proc_cfg.minor_version = 1;
			afe_spk_config.vi_proc_cfg.r0_cali_q24 =
			(uint32_t) this_afe.prot_cfg.r0;
			afe_spk_config.vi_proc_cfg.t0_cali_q6 =
			(uint32_t) this_afe.prot_cfg.t0;
		afe_spk_config.vi_proc_cfg.r0_cali_q24[SP_V2_SPKR_1] =
			(uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_1];
		afe_spk_config.vi_proc_cfg.r0_cali_q24[SP_V2_SPKR_2] =
			(uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_2];
		afe_spk_config.vi_proc_cfg.t0_cali_q6[SP_V2_SPKR_1] =
			(uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_1];
		afe_spk_config.vi_proc_cfg.t0_cali_q6[SP_V2_SPKR_2] =
			(uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_2];
		if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_NOT_CALIBRATED) {
			struct asm_spkr_calib_vi_proc_cfg *vi_proc_cfg;
			vi_proc_cfg = &afe_spk_config.vi_proc_cfg;
			vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_1] =
					    USE_CALIBRATED_R0TO;
			vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_2] =
					    USE_CALIBRATED_R0TO;
		} else {
			struct asm_spkr_calib_vi_proc_cfg *vi_proc_cfg;
			vi_proc_cfg = &afe_spk_config.vi_proc_cfg;
			vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_1] =
							    USE_SAFE_R0TO;
			vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_2] =
							    USE_SAFE_R0TO;
		}
		if (afe_spk_prot_prepare(port_id,
				AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG,
			AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2,
						    &afe_spk_config))
				pr_err("%s: SPKR_CALIB_VI_PROC_CFG failed\n",
					__func__);
	}
	}
	mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
done:
	return;
@@ -737,8 +852,10 @@ static void send_afe_cal_type(int cal_index, int port_id)

	mutex_lock(&this_afe.cal_data[cal_index]->lock);
	cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
	if (cal_block == NULL)
	if (cal_block == NULL) {
		pr_err("%s cal_block not found!!\n", __func__);
		goto unlock;
	}

	pr_debug("%s: Sending cal_index cal %d\n", __func__, cal_index);

@@ -3460,6 +3577,13 @@ int afe_close(int port_id)
				__func__, ret);
	}

	/*
	 * even if ramp down configuration failed it is not serious enough to
	 * warrant bailaing out.
	 */
	if (afe_spk_ramp_dn_cfg(port_id) < 0)
		pr_err("%s: ramp down configuration failed\n", __func__);

	stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
	stop.hdr.pkt_size = sizeof(stop);
@@ -3760,15 +3884,15 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp)
	calib_resp->hdr.token = index;
	calib_resp->hdr.opcode =  AFE_PORT_CMD_GET_PARAM_V2;
	calib_resp->get_param.mem_map_handle = 0;
	calib_resp->get_param.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC;
	calib_resp->get_param.param_id = AFE_PARAM_ID_CALIB_RES_CFG;
	calib_resp->get_param.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
	calib_resp->get_param.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2;
	calib_resp->get_param.payload_address_lsw = 0;
	calib_resp->get_param.payload_address_msw = 0;
	calib_resp->get_param.payload_size = sizeof(*calib_resp)
		- sizeof(calib_resp->get_param) - sizeof(calib_resp->hdr);
	calib_resp->get_param.port_id = q6audio_get_port_id(port);
	calib_resp->pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC;
	calib_resp->pdata.param_id = AFE_PARAM_ID_CALIB_RES_CFG;
	calib_resp->pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
	calib_resp->pdata.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2;
	calib_resp->pdata.param_size = sizeof(calib_resp->res_cfg);
	atomic_set(&this_afe.state, 1);
	ret = apr_send_pkt(this_afe.apr, (uint32_t *)calib_resp);
@@ -3792,9 +3916,10 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp)
	}
	memcpy(&calib_resp->res_cfg , &this_afe.calib_data.res_cfg,
		sizeof(this_afe.calib_data.res_cfg));
	pr_info("%s: state %d resistance %d\n", __func__,
			 calib_resp->res_cfg.th_vi_ca_state,
			 calib_resp->res_cfg.r0_cali_q24);
	pr_info("%s: state %s resistance %d %d\n", __func__,
			 cali_state[calib_resp->res_cfg.th_vi_ca_state],
			 calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1],
			 calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]);
	ret = 0;
fail_cmd:
	return ret;
@@ -3837,6 +3962,7 @@ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
		prot_config.feedback_path_cfg.chan_info[index++] = 4;
	}
	prot_config.feedback_path_cfg.num_channels = index;
	pr_debug("%s no of channels: %d\n", __func__, index);
	prot_config.feedback_path_cfg.minor_version = 1;
	ret = afe_spk_prot_prepare(src_port,
			AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config);
@@ -4077,31 +4203,43 @@ static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size,

	mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
	if (this_afe.prot_cfg.mode == MSM_SPKR_PROT_CALIBRATED) {
			cal_data->cal_info.r0 = this_afe.prot_cfg.r0;
			cal_data->cal_info.r0[SP_V2_SPKR_1] =
				this_afe.prot_cfg.r0[SP_V2_SPKR_1];
			cal_data->cal_info.r0[SP_V2_SPKR_2] =
				this_afe.prot_cfg.r0[SP_V2_SPKR_2];
			cal_data->cal_info.status = 0;
	} else if (this_afe.prot_cfg.mode ==
				MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) {
		/*Call AFE to query the status*/
		cal_data->cal_info.status = -EINVAL;
		cal_data->cal_info.r0 = -1;
		cal_data->cal_info.r0[SP_V2_SPKR_1] = -1;
		cal_data->cal_info.r0[SP_V2_SPKR_2] = -1;
		if (!afe_spk_prot_get_calib_data(&calib_resp)) {
			if (calib_resp.res_cfg.th_vi_ca_state == 1)
			if (calib_resp.res_cfg.th_vi_ca_state ==
							CALIB_IN_PROGRESS)
				cal_data->cal_info.status = -EAGAIN;
			else if (calib_resp.res_cfg.th_vi_ca_state == 2) {
			else if (calib_resp.res_cfg.th_vi_ca_state ==
							CALIB_SUCCESS) {
				cal_data->cal_info.status = 0;
				cal_data->cal_info.r0 =
					calib_resp.res_cfg.r0_cali_q24;
				cal_data->cal_info.r0[SP_V2_SPKR_1] =
				calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_1];
				cal_data->cal_info.r0[SP_V2_SPKR_2] =
				calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_2];
			}
		}
		if (!cal_data->cal_info.status) {
			this_afe.prot_cfg.mode =
				MSM_SPKR_PROT_CALIBRATED;
			this_afe.prot_cfg.r0 = cal_data->cal_info.r0;
			this_afe.prot_cfg.r0[SP_V2_SPKR_1] =
				cal_data->cal_info.r0[SP_V2_SPKR_1];
			this_afe.prot_cfg.r0[SP_V2_SPKR_2] =
				cal_data->cal_info.r0[SP_V2_SPKR_2];
		}
	} else {
		/*Indicates calibration data is invalid*/
		cal_data->cal_info.status = -EINVAL;
		cal_data->cal_info.r0 = -1;
		cal_data->cal_info.r0[SP_V2_SPKR_1] = -1;
		cal_data->cal_info.r0[SP_V2_SPKR_2] = -1;
	}
	mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
done: