dsp: add support for new AFE LSM cal types

Add support for new AFE LSM cal types in order
to avoid topology and cal block overriding during
concurrent use cases like SVA with speaker
protection.

CRs-Fixed: 2085865
Change-Id: I9af5c34ea7ad9403b9e6d63ac5d3e73e708a320e
Signed-off-by: Aditya Bavanari <abavanar@codeaurora.org>
diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c
index ffd3929..743bd93 100644
--- a/dsp/audio_cal_utils.c
+++ b/dsp/audio_cal_utils.c
@@ -77,6 +77,7 @@
 		size = sizeof(struct audio_cal_info_audstrm);
 		break;
 	case AFE_TOPOLOGY_CAL_TYPE:
+	case AFE_LSM_TOPOLOGY_CAL_TYPE:
 		size = sizeof(struct audio_cal_info_afe_top);
 		break;
 	case AFE_CUST_TOPOLOGY_CAL_TYPE:
@@ -86,6 +87,7 @@
 		size = sizeof(struct audio_cal_info_afe);
 		break;
 	case AFE_COMMON_TX_CAL_TYPE:
+	case AFE_LSM_TX_CAL_TYPE:
 		size = sizeof(struct audio_cal_info_afe);
 		break;
 	case AFE_FB_SPKR_PROT_CAL_TYPE:
@@ -223,6 +225,7 @@
 		size = sizeof(struct audio_cal_type_audstrm);
 		break;
 	case AFE_TOPOLOGY_CAL_TYPE:
+	case AFE_LSM_TOPOLOGY_CAL_TYPE:
 		size = sizeof(struct audio_cal_type_afe_top);
 		break;
 	case AFE_CUST_TOPOLOGY_CAL_TYPE:
@@ -232,6 +235,7 @@
 		size = sizeof(struct audio_cal_type_afe);
 		break;
 	case AFE_COMMON_TX_CAL_TYPE:
+	case AFE_LSM_TX_CAL_TYPE:
 		size = sizeof(struct audio_cal_type_afe);
 		break;
 	case AFE_FB_SPKR_PROT_CAL_TYPE:
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 864ae4a..481f4b1 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -30,12 +30,14 @@
 enum {
 	AFE_COMMON_RX_CAL = 0,
 	AFE_COMMON_TX_CAL,
+	AFE_LSM_TX_CAL,
 	AFE_AANC_CAL,
 	AFE_FB_SPKR_PROT_CAL,
 	AFE_HW_DELAY_CAL,
 	AFE_SIDETONE_CAL,
 	AFE_SIDETONE_IIR_CAL,
 	AFE_TOPOLOGY_CAL,
+	AFE_LSM_TOPOLOGY_CAL,
 	AFE_CUST_TOPOLOGY_CAL,
 	AFE_FB_SPKR_PROT_TH_VI_CAL,
 	AFE_FB_SPKR_PROT_EX_VI_CAL,
@@ -1396,14 +1398,15 @@
 	return NULL;
 }
 
-static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id)
+static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id,
+				   int cal_type_index)
 {
 	int ret = 0;
 
 	struct cal_block_data   *cal_block = NULL;
 	struct audio_cal_info_afe_top   *afe_top_info = NULL;
 
-	if (this_afe.cal_data[AFE_TOPOLOGY_CAL] == NULL) {
+	if (this_afe.cal_data[cal_type_index] == NULL) {
 		pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized\n", __func__);
 		return -EINVAL;
 	}
@@ -1413,9 +1416,9 @@
 	}
 	*topology_id = 0;
 
-	mutex_lock(&this_afe.cal_data[AFE_TOPOLOGY_CAL]->lock);
+	mutex_lock(&this_afe.cal_data[cal_type_index]->lock);
 	cal_block = afe_find_cal_topo_id_by_port(
-		this_afe.cal_data[AFE_TOPOLOGY_CAL], port_id);
+		this_afe.cal_data[cal_type_index], port_id);
 	if (cal_block == NULL) {
 		pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized for this port %d\n",
 				__func__, port_id);
@@ -1437,7 +1440,7 @@
 		__func__, port_id, afe_top_info->acdb_id,
 		afe_top_info->topology, ret);
 unlock:
-	mutex_unlock(&this_afe.cal_data[AFE_TOPOLOGY_CAL]->lock);
+	mutex_unlock(&this_afe.cal_data[cal_type_index]->lock);
 	return ret;
 }
 
@@ -1455,7 +1458,12 @@
 		return -EINVAL;
 	}
 
-	ret = afe_get_cal_topology_id(port_id, &topology_id);
+	ret = afe_get_cal_topology_id(port_id, &topology_id, AFE_TOPOLOGY_CAL);
+	if (ret < 0) {
+		pr_debug("%s: Check for LSM topology\n", __func__);
+		ret = afe_get_cal_topology_id(port_id, &topology_id,
+					      AFE_LSM_TOPOLOGY_CAL);
+	}
 	if (ret || !topology_id) {
 		pr_debug("%s: AFE port[%d] get_cal_topology[%d] invalid!\n",
 				__func__, port_id, topology_id);
@@ -1572,7 +1580,7 @@
 	return cal_block;
 }
 
-static void send_afe_cal_type(int cal_index, int port_id)
+static int send_afe_cal_type(int cal_index, int port_id)
 {
 	struct cal_block_data		*cal_block = NULL;
 	int ret;
@@ -1583,19 +1591,22 @@
 	if (this_afe.cal_data[cal_index] == NULL) {
 		pr_warn("%s: cal_index %d not allocated!\n",
 			__func__, cal_index);
+		ret = -EINVAL;
 		goto done;
 	}
 
 	if (afe_port_index < 0) {
 		pr_err("%s: Error getting AFE port index %d\n",
 			__func__, afe_port_index);
+		ret = -EINVAL;
 		goto done;
 	}
 
 	mutex_lock(&this_afe.cal_data[cal_index]->lock);
 
 	if (((cal_index == AFE_COMMON_RX_CAL) ||
-	     (cal_index == AFE_COMMON_TX_CAL)) &&
+	     (cal_index == AFE_COMMON_TX_CAL) ||
+	     (cal_index == AFE_LSM_TX_CAL)) &&
 	    (this_afe.dev_acdb_id[afe_port_index] > 0))
 		cal_block = afe_find_cal(cal_index, port_id);
 	else
@@ -1604,6 +1615,7 @@
 
 	if (cal_block == NULL) {
 		pr_err("%s cal_block not found!!\n", __func__);
+		ret = -EINVAL;
 		goto unlock;
 	}
 
@@ -1613,6 +1625,7 @@
 	if (ret) {
 		pr_err("%s: Remap_cal_data failed for cal %d!\n",
 			__func__, cal_index);
+		ret = -EINVAL;
 		goto unlock;
 	}
 	ret = afe_send_cal_block(port_id, cal_block);
@@ -1622,16 +1635,20 @@
 unlock:
 	mutex_unlock(&this_afe.cal_data[cal_index]->lock);
 done:
-	return;
+	return ret;
 }
 
 void afe_send_cal(u16 port_id)
 {
+	int ret;
+
 	pr_debug("%s: port_id=0x%x\n", __func__, port_id);
 
 	if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) {
 		afe_send_cal_spkr_prot_tx(port_id);
-		send_afe_cal_type(AFE_COMMON_TX_CAL, port_id);
+		ret = send_afe_cal_type(AFE_COMMON_TX_CAL, port_id);
+		if (ret < 0)
+			send_afe_cal_type(AFE_LSM_TX_CAL, port_id);
 	} else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) {
 		afe_send_cal_spkr_prot_rx(port_id);
 		send_afe_cal_type(AFE_COMMON_RX_CAL, port_id);
@@ -6888,6 +6905,9 @@
 	case AFE_COMMON_TX_CAL_TYPE:
 		ret = AFE_COMMON_TX_CAL;
 		break;
+	case AFE_LSM_TX_CAL_TYPE:
+		ret = AFE_LSM_TX_CAL;
+		break;
 	case AFE_AANC_CAL_TYPE:
 		ret = AFE_AANC_CAL;
 		break;
@@ -6906,6 +6926,9 @@
 	case AFE_TOPOLOGY_CAL_TYPE:
 		ret = AFE_TOPOLOGY_CAL;
 		break;
+	case AFE_LSM_TOPOLOGY_CAL_TYPE:
+		ret = AFE_LSM_TOPOLOGY_CAL;
+		break;
 	case AFE_CUST_TOPOLOGY_CAL_TYPE:
 		ret = AFE_CUST_TOPOLOGY_CAL;
 		break;
@@ -7408,6 +7431,12 @@
 		{afe_map_cal_data, afe_unmap_cal_data,
 		cal_utils_match_buf_num} },
 
+		{{AFE_LSM_TX_CAL_TYPE,
+		{afe_alloc_cal, afe_dealloc_cal, NULL,
+		afe_set_cal, NULL, NULL} },
+		{afe_map_cal_data, afe_unmap_cal_data,
+		cal_utils_match_buf_num} },
+
 		{{AFE_AANC_CAL_TYPE,
 		{afe_alloc_cal, afe_dealloc_cal, NULL,
 		afe_set_cal, NULL, NULL} },
@@ -7440,6 +7469,12 @@
 		{NULL, NULL,
 		cal_utils_match_buf_num} },
 
+		{{AFE_LSM_TOPOLOGY_CAL_TYPE,
+		{NULL, NULL, NULL,
+		afe_set_cal, NULL, NULL} },
+		{NULL, NULL,
+		cal_utils_match_buf_num} },
+
 		{{AFE_CUST_TOPOLOGY_CAL_TYPE,
 		{afe_alloc_cal, afe_dealloc_cal, NULL,
 		afe_set_cal, NULL, NULL} },
diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h
index 29fdf8f..27dacde 100644
--- a/include/uapi/linux/msm_audio_calibration.h
+++ b/include/uapi/linux/msm_audio_calibration.h
@@ -99,6 +99,8 @@
 	AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE,
 	AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE,
 	AFE_SIDETONE_IIR_CAL_TYPE,
+	AFE_LSM_TOPOLOGY_CAL_TYPE,
+	AFE_LSM_TX_CAL_TYPE,
 	MAX_CAL_TYPES,
 };
 
@@ -107,6 +109,9 @@
 
 #define AFE_SIDETONE_IIR_CAL_TYPE AFE_SIDETONE_IIR_CAL_TYPE
 
+#define AFE_LSM_TOPOLOGY_CAL_TYPE AFE_LSM_TOPOLOGY_CAL_TYPE
+#define AFE_LSM_TX_CAL_TYPE AFE_LSM_TX_CAL_TYPE
+
 #define TOPOLOGY_SPECIFIC_CHANNEL_INFO
 #define MSM_SPKR_PROT_SPV3