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

Commit f98571b5 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: msm: qdsp6v2: add speaker protection module id"

parents b05ec824 d8f65739
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)
{
@@ -3742,6 +3741,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)
{
@@ -3749,23 +3786,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>,
@@ -4179,6 +4243,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,
@@ -5066,7 +5133,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: