Merge "soc: wsa883x: Update changes for wsa8830"
diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c
index 734b241..3a319c7 100644
--- a/asoc/codecs/wsa883x/wsa883x.c
+++ b/asoc/codecs/wsa883x/wsa883x.c
@@ -64,6 +64,8 @@
 
 static const struct wsa_reg_mask_val reg_init[] = {
 	{WSA883X_PA_FSM_BYP, 0x01, 0x00},
+	{WSA883X_ISENSE2, 0xE0, 0x40},
+	{WSA883X_ADC_6, 0x02, 0x02},
 	{WSA883X_CDC_SPK_DSM_A2_0, 0xFF, 0x0A},
 	{WSA883X_CDC_SPK_DSM_A2_1, 0x0F, 0x08},
 	{WSA883X_CDC_SPK_DSM_A3_0, 0xFF, 0xF3},
@@ -102,8 +104,12 @@
 	{WSA883X_OTP_REG_3, 0xFF, 0xC9},
 	{WSA883X_OTP_REG_4, 0xC0, 0x40},
 	{WSA883X_TAGC_CTL, 0x01, 0x01},
+	{WSA883X_ADC_2, 0x40, 0x00},
+	{WSA883X_ADC_7, 0x04, 0x04},
+	{WSA883X_ADC_7, 0x02, 0x02},
 	{WSA883X_CKWD_CTL_0, 0x60, 0x00},
 	{WSA883X_CKWD_CTL_1, 0x1F, 0x1B},
+	{WSA883X_GMAMP_SUP1, 0x60, 0x60},
 };
 
 static int wsa883x_get_temperature(struct snd_soc_component *component,
@@ -847,7 +853,7 @@
 	SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0,
 		wsa883x_get_mute, wsa883x_set_mute),
 
-	SOC_SINGLE_EXT("WSA Temp", SND_SOC_NOPM, 0, 1, 0,
+	SOC_SINGLE_EXT("WSA Temp", SND_SOC_NOPM, 0, UINT_MAX, 0,
 			wsa_get_temp, NULL),
 
 	SOC_ENUM_EXT("WSA MODE", wsa_dev_mode_enum,
@@ -1074,7 +1080,19 @@
 
 	mutex_lock(&wsa883x->res_lock);
 
-	/* TODO Vote for global PA */
+	snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP,
+				0x01, 0x01);
+	snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP,
+				0x04, 0x04);
+	snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP,
+				0x02, 0x02);
+	snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP,
+				0x80, 0x80);
+	snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP,
+				0x20, 0x20);
+	snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP,
+				0x40, 0x40);
+
 	snd_soc_component_update_bits(component, WSA883X_TADC_VALUE_CTL,
 				0x01, 0x00);
 	wsa_temp_reg->dmeas_msb = snd_soc_component_read32(
@@ -1092,7 +1110,8 @@
 	wsa_temp_reg->d2_lsb = snd_soc_component_read32(
 					component, WSA883X_OTP_REG_4);
 
-	/* TODO Unvote for global PA */
+	snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP,
+				0xE7, 0x00);
 	mutex_unlock(&wsa883x->res_lock);
 
 	return 0;
diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c
index 4804f8c..a32acfd 100644
--- a/dsp/adsp-loader.c
+++ b/dsp/adsp-loader.c
@@ -393,7 +393,7 @@
 		goto wqueue;
 	}
 	if (len <= 0 || len > sizeof(u32)) {
-		dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %d\n",
+		dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %zu\n",
 			__func__, len);
 		kfree(buf);
 		goto wqueue;
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 3d76e48..0811d6c 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -5491,8 +5491,12 @@
 			if ((q6core_get_avcs_api_version_per_service(
 				APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >=
 				AVCS_API_VERSION_V5)) {
-				/* LDAC doesn't require decoder */
-				if (codec_format == ENC_CODEC_TYPE_LDAC)
+				/*
+				 * LDAC and APTX_ADAPTIVE don't require loading decoder module
+				 * Only loading de-packetizer module.
+				 */
+				if (codec_format == ENC_CODEC_TYPE_LDAC ||
+					codec_format == ASM_MEDIA_FMT_APTX_ADAPTIVE)
 					ret = q6afe_load_avcs_modules(1, port_id,
 						DECODER_CASE, codec_format);
 				else
diff --git a/dsp/q6core.c b/dsp/q6core.c
index 8e8bedf..392b09d 100644
--- a/dsp/q6core.c
+++ b/dsp/q6core.c
@@ -990,6 +990,7 @@
 	else
 		mod->hdr.opcode =  AVCS_CMD_UNLOAD_MODULES;
 
+	q6core_lcl.adsp_status = 0;
 	q6core_lcl.avcs_module_resp_received = 0;
 	ret = apr_send_pkt(q6core_lcl.core_handle_q,
 		(uint32_t *)mod);
diff --git a/dsp/q6voice.c b/dsp/q6voice.c
index c63cf98..84a2eb9 100644
--- a/dsp/q6voice.c
+++ b/dsp/q6voice.c
@@ -7204,6 +7204,16 @@
 			goto done;
 		}
 		v->voc_state = VOC_RUN;
+
+		if (v->lch_mode == 0) {
+			pr_debug("%s: dev_mute = %d, ramp_duration = %d ms\n",
+				__func__, v->dev_rx.dev_mute,
+				 v->dev_rx.dev_mute_ramp_duration_ms);
+			ret = voice_send_device_mute_cmd(v,
+					VSS_IVOLUME_DIRECTION_RX,
+					v->dev_rx.dev_mute,
+					v->dev_rx.dev_mute_ramp_duration_ms);
+		}
 	} else {
 		pr_debug("%s: called in voc state=%d, No_OP\n",
 			 __func__, v->voc_state);
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index beaaa26..623f70e 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -56,6 +56,8 @@
 #define SWRM_COL_02    02
 #define SWRM_COL_16    16
 
+#define SWR_OVERFLOW_RETRY_COUNT 30
+
 /* pm runtime auto suspend timer in msecs */
 static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000;
 module_param(auto_suspend_timer, int, 0664);
@@ -84,6 +86,11 @@
 	LPASS_AUDIO_CORE,
 };
 
+enum {
+	SWRM_WR_CHECK_AVAIL,
+	SWRM_RD_CHECK_AVAIL,
+};
+
 #define TRUE 1
 #define FALSE 0
 
@@ -743,6 +750,54 @@
 	return val;
 }
 
+static void swrm_wait_for_fifo_avail(struct swr_mstr_ctrl *swrm, int swrm_rd_wr)
+{
+	u32 fifo_outstanding_cmd;
+	u8 fifo_retry_count = SWR_OVERFLOW_RETRY_COUNT;
+
+	if (swrm_rd_wr) {
+		/* Check for fifo underflow during read */
+		/* Check no of outstanding commands in fifo before read */
+		fifo_outstanding_cmd = ((swr_master_read(swrm,
+				SWRM_CMD_FIFO_STATUS) & 0x001F0000) >> 16);
+		if (fifo_outstanding_cmd == 0) {
+			while (fifo_retry_count) {
+				usleep_range(500, 510);
+				fifo_outstanding_cmd =
+					((swr_master_read (swrm,
+					  SWRM_CMD_FIFO_STATUS) & 0x001F0000)
+					  >> 16);
+				fifo_retry_count--;
+				if (fifo_outstanding_cmd > 0)
+					break;
+			}
+		}
+		if (fifo_outstanding_cmd == 0)
+			dev_err_ratelimited(swrm->dev,
+				"%s err read underflow\n", __func__);
+	} else {
+		/* Check for fifo overflow during write */
+		/* Check no of outstanding commands in fifo before write */
+		fifo_outstanding_cmd = ((swr_master_read(swrm,
+					 SWRM_CMD_FIFO_STATUS) & 0x00001F00)
+					 >> 8);
+		if (fifo_outstanding_cmd == swrm->wr_fifo_depth) {
+			while (fifo_retry_count) {
+				usleep_range(500, 510);
+				fifo_outstanding_cmd =
+				((swr_master_read(swrm, SWRM_CMD_FIFO_STATUS)
+				  & 0x00001F00) >> 8);
+				fifo_retry_count--;
+				if (fifo_outstanding_cmd < swrm->wr_fifo_depth)
+					break;
+			}
+		}
+		if (fifo_outstanding_cmd == swrm->wr_fifo_depth)
+			dev_err_ratelimited(swrm->dev,
+				"%s err write overflow\n", __func__);
+	}
+}
+
 static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data,
 				 u8 dev_addr, u8 cmd_id, u16 reg_addr,
 				 u32 len)
@@ -756,12 +811,19 @@
 		/* skip delay if read is handled in platform driver */
 		swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val);
 	} else {
+		/*
+		 * Check for outstanding cmd wrt. write fifo depth to avoid
+		 * overflow as read will also increase write fifo cnt.
+		 */
+		swrm_wait_for_fifo_avail(swrm, SWRM_WR_CHECK_AVAIL);
 		/* wait for FIFO RD to complete to avoid overflow */
 		usleep_range(100, 105);
 		swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val);
 		/* wait for FIFO RD CMD complete to avoid overflow */
 		usleep_range(250, 255);
 	}
+	/* Check if slave responds properly after FIFO RD is complete */
+	swrm_wait_for_fifo_avail(swrm, SWRM_RD_CHECK_AVAIL);
 retry_read:
 	*cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR);
 	dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, rcmd_id: 0x%x, \
@@ -808,6 +870,11 @@
 	dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x,wcmd_id: 0x%x, \
 			dev_num: 0x%x, cmd_data: 0x%x\n", __func__,
 			reg_addr, cmd_id, swrm->wcmd_id,dev_addr, cmd_data);
+	/*
+	 * Check for outstanding cmd wrt. write fifo depth to avoid
+	 * overflow.
+	 */
+	swrm_wait_for_fifo_avail(swrm, SWRM_WR_CHECK_AVAIL);
 	swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val);
 	/*
 	 * wait for FIFO WR command to complete to avoid overflow
@@ -2785,6 +2852,11 @@
 	if (pdev->dev.of_node)
 		of_register_swr_devices(&swrm->master);
 
+	swrm->rd_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS)
+				& SWRM_COMP_PARAMS_RD_FIFO_DEPTH) >> 15);
+	swrm->wr_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS)
+				& SWRM_COMP_PARAMS_WR_FIFO_DEPTH) >> 10);
+
 #ifdef CONFIG_DEBUG_FS
 	swrm->debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0);
 	if (!IS_ERR(swrm->debugfs_swrm_dent)) {
diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h
index 8d38441..51b3538 100644
--- a/soc/swr-mstr-ctrl.h
+++ b/soc/swr-mstr-ctrl.h
@@ -182,6 +182,8 @@
 	int aud_core_clk_en;
 	int clk_src;
 	u32 disable_div2_clk_switch;
+	u32 rd_fifo_depth;
+	u32 wr_fifo_depth;
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *debugfs_swrm_dent;
 	struct dentry *debugfs_peek;