Merge cherrypicks of ['partner-android-review.googlesource.com/2928766', 'partner-android-review.googlesource.com/2928284'] into sparse-12319158-L27000030006374856.
SPARSE_CHANGE: I7402d11f2af08b92073ed6a857d581823db075e2
SPARSE_CHANGE: I4f2607c0a17a8cee596937fba73d3e773c31ee7f


Change-Id: If9a8b43c5687cfaae78a57a9ab6892e61777fcba
Signed-off-by: Coastguard Worker <[email protected]>
diff --git a/alsa/aoc_alsa.h b/alsa/aoc_alsa.h
index 3292b9f..d154012 100644
--- a/alsa/aoc_alsa.h
+++ b/alsa/aoc_alsa.h
@@ -81,7 +81,7 @@
 #define MAX_NUM_OF_SINKS_PER_STREAM 2
 #define NUM_OF_MIC_BROKEN_RECORD 5
 
-#define MAX_NUM_OF_INCALL_CAPTURE_STREAM 3
+#define MAX_NUM_OF_INCALL_CAPTURE_STREAM 4
 
 #define N_MIC_IN_SPATIAL_MODULE 3
 
diff --git a/alsa/aoc_alsa_ctl.c b/alsa/aoc_alsa_ctl.c
index 2dd0f05..5abfc47 100644
--- a/alsa/aoc_alsa_ctl.c
+++ b/alsa/aoc_alsa_ctl.c
@@ -2360,6 +2360,7 @@
 static SOC_ENUM_SINGLE_DECL(incall_capture_stream0_enum, 1, 0, incall_capture_stream_texts);
 static SOC_ENUM_SINGLE_DECL(incall_capture_stream1_enum, 1, 1, incall_capture_stream_texts);
 static SOC_ENUM_SINGLE_DECL(incall_capture_stream2_enum, 1, 2, incall_capture_stream_texts);
+static SOC_ENUM_SINGLE_DECL(incall_capture_stream3_enum, 1, 3, incall_capture_stream_texts);
 
 /* audio capture mic source */
 static const char *audio_capture_mic_source_texts[] = { "Default", "Builtin_MIC", "USB_MIC",
@@ -2594,6 +2595,8 @@
 		     incall_capture_enable_ctl_get, incall_capture_enable_ctl_set),
 	SOC_ENUM_EXT("Incall Capture Stream2", incall_capture_stream2_enum,
 		     incall_capture_enable_ctl_get, incall_capture_enable_ctl_set),
+	SOC_ENUM_EXT("Incall Capture Stream3", incall_capture_stream3_enum,
+		     incall_capture_enable_ctl_get, incall_capture_enable_ctl_set),
 
 	SOC_SINGLE_EXT("Incall Playback Stream0", SND_SOC_NOPM, 0, 1, 0,
 		       incall_playback_enable_ctl_get, incall_playback_enable_ctl_set),
diff --git a/alsa/aoc_alsa_drv.c b/alsa/aoc_alsa_drv.c
index 37316e1..23d4154 100644
--- a/alsa/aoc_alsa_drv.c
+++ b/alsa/aoc_alsa_drv.c
@@ -68,6 +68,7 @@
 #endif
 #if IS_ENABLED(CONFIG_SOC_ZUMA)
 	"audio_displayport",
+	"audio_incall_cap_3",
 #endif
 	NULL,
 };
diff --git a/alsa/aoc_alsa_hw.c b/alsa/aoc_alsa_hw.c
index f1afb0c..98188b1 100644
--- a/alsa/aoc_alsa_hw.c
+++ b/alsa/aoc_alsa_hw.c
@@ -176,7 +176,7 @@
 	[15] = NORMAL, [16] = NORMAL,  [17] = NORMAL,	   [18] = INCALL, [19] = INCALL,
 	[20] = INCALL, [21] = INCALL,  [22] = INCALL,	   [23] = MMAPED, [24] = NORMAL,
 	[25] = HIFI,   [26] = HIFI,    [27] = ANDROID_AEC, [28] = MMAPED, [29] = INCALL,
-	[30] = NORMAL, [31] = CAP_INJ, [32] = HOTWORD_TAP,
+	[30] = NORMAL, [31] = CAP_INJ, [32] = HOTWORD_TAP, [54] = INCALL,
 };
 
 int aoc_pcm_device_to_stream_type(int device)
@@ -789,6 +789,13 @@
 	int err;
 	struct CMD_AUDIO_OUTPUT_TELE_CAPT cmd;
 
+#if IS_ENABLED(CONFIG_SOC_GS101) || IS_ENABLED(CONFIG_SOC_GS201)
+	if (stream == 3) {
+		*val = chip->incall_capture_state[stream];
+		return 0;
+	}
+#endif
+
 	AocCmdHdrSet(&(cmd.parent), CMD_AUDIO_OUTPUT_GET_TELE_CAPT_ID, sizeof(cmd));
 
 	cmd.ring = stream;
@@ -813,6 +820,14 @@
 	int err;
 	struct CMD_AUDIO_OUTPUT_TELE_CAPT cmd;
 
+#if IS_ENABLED(CONFIG_SOC_GS101) || IS_ENABLED(CONFIG_SOC_GS201)
+	if (stream == 3) {
+		chip->incall_capture_state[stream] = val;
+		pr_info("%s: Not support stream 3\n", __func__);
+		return 0;
+	}
+#endif
+
 	AocCmdHdrSet(&(cmd.parent), CMD_AUDIO_OUTPUT_SET_TELE_CAPT_ID, sizeof(cmd));
 	cmd.ring = stream;
 	cmd.mode = val;
@@ -2751,6 +2766,7 @@
 {
 	int stream, err = 0;
 	struct aoc_chip *chip = alsa_stream->chip;
+	struct snd_soc_pcm_runtime *rtd = alsa_stream->substream->private_data;
 
 	if (alsa_stream->stream_type == CAP_INJ)
 		return aoc_audio_capture_inject_start(alsa_stream);
@@ -2764,15 +2780,50 @@
 	if (alsa_stream->stream_type == HOTWORD_TAP)
 		return 0;
 
-	/* TODO: stream number inferred by pcm device idx, pb_0:18, cap_0:20, better way needed */
+	if (!rtd) {
+		pr_err("ERR: invalid pcm runtime structure\n");
+		return 0;
+	}
+
 	if (alsa_stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		stream = alsa_stream->entry_point_idx - 18;
-		stream = min(stream, 2); /* stream 2 for pb_2 has device id 29 */
+		/* Mapping the incall playback to specific stream ring.*/
+		switch (rtd->dai_link->id) {
+			case IDX_INCALL_PB0_RX:
+				stream = 0;
+				break;
+			case IDX_INCALL_PB1_RX:
+				stream = 1;
+				break;
+			case IDX_INCALL_PB2_RX:
+				stream = 2;
+				break;
+			default:
+			/* TODO: Keep original logic, but should be removed if it is useless.*/
+				stream = 2;
+				break;
+		}
 		err = aoc_incall_playback_enable_set(chip, stream, 1);
 		if (err < 0)
 			pr_err("ERR:%d in incall playback start on\n", err);
 	} else {
-		stream = alsa_stream->entry_point_idx - 20;
+		/* Mapping the incall playback to specific stream ring.*/
+		switch (rtd->dai_link->id) {
+			case IDX_INCALL_CAP0_TX:
+				stream = 0;
+				break;
+			case IDX_INCALL_CAP1_TX:
+				stream = 1;
+				break;
+			case IDX_INCALL_CAP2_TX:
+				stream = 2;
+				break;
+			case IDX_INCALL_CAP3_TX:
+				stream = 3;
+				break;
+			default:
+				pr_err("ERR: dai_link id %d for incall_cap", rtd->dai_link->id);
+				return err;
+		}
 		err = aoc_incall_capture_enable_set(chip, stream,
 						    chip->incall_capture_state[stream]);
 		if (err < 0)
@@ -2786,6 +2837,7 @@
 {
 	int stream, err = 0;
 	struct aoc_chip *chip = alsa_stream->chip;
+	struct snd_soc_pcm_runtime *rtd = alsa_stream->substream->private_data;
 
 	if (alsa_stream->stream_type == CAP_INJ)
 		return aoc_audio_capture_inject_stop(alsa_stream);
@@ -2799,14 +2851,50 @@
 	if (alsa_stream->stream_type == HOTWORD_TAP)
 		return 0;
 
-	/* TODO: stream number inferred by pcm device idx, pb_0:18, cap_0:20, better way needed */
+	if (!rtd) {
+		pr_err("ERR: invalid pcm runtime structure\n");
+		return 0;
+	}
+
 	if (alsa_stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		stream = alsa_stream->entry_point_idx - 18;
+		/* Mapping the incall playback to specific stream ring.*/
+		switch (rtd->dai_link->id) {
+			case IDX_INCALL_PB0_RX:
+				stream = 0;
+				break;
+			case IDX_INCALL_PB1_RX:
+				stream = 1;
+				break;
+			case IDX_INCALL_PB2_RX:
+				stream = 2;
+				break;
+			default:
+			/* TODO: Keep original logic, but should be removed if it is useless.*/
+				stream = 2;
+				break;
+		}
 		err = aoc_incall_playback_enable_set(chip, stream, 0);
 		if (err < 0)
 			pr_err("ERR:%d in incall playback start on\n", err);
 	} else {
-		stream = alsa_stream->entry_point_idx - 20;
+		/* Mapping the incall playback to specific stream ring.*/
+		switch (rtd->dai_link->id) {
+			case IDX_INCALL_CAP0_TX:
+				stream = 0;
+				break;
+			case IDX_INCALL_CAP1_TX:
+				stream = 1;
+				break;
+			case IDX_INCALL_CAP2_TX:
+				stream = 2;
+				break;
+			case IDX_INCALL_CAP3_TX:
+				stream = 3;
+				break;
+			default:
+				pr_err("ERR: dai_link id %d for incall_cap", rtd->dai_link->id);
+				return err;
+		}
 		err = aoc_incall_capture_enable_set(chip, stream, 0);
 		if (err < 0)
 			pr_err("ERR:%d in incall capture start on\n", err);
diff --git a/alsa/aoc_alsa_incall.c b/alsa/aoc_alsa_incall.c
index 762d8d2..636d3c6 100644
--- a/alsa/aoc_alsa_incall.c
+++ b/alsa/aoc_alsa_incall.c
@@ -240,9 +240,15 @@
 
 	/* TODO: refactor needed on mapping between device number and entrypoint */
 	alsa_stream->entry_point_idx = (idx == 7) ? HAPTICS : idx;
+
+	/* reuse incall_capture 0 on tablet for voip path.
+	 * and using new incall capture 3 for phone platform. */
 	if (rtd->dai_link->id == IDX_INCALL_CAP0_TX &&
 		chip->incall_capture_state[0] == INCALL_CAPTURE_3MIC) {
 		alsa_stream->reused_for_voip = true;
+	} else if (rtd->dai_link->id == IDX_INCALL_CAP3_TX &&
+		chip->incall_capture_state[3] == INCALL_CAPTURE_3MIC) {
+		alsa_stream->reused_for_voip = true;
 	}
 	mutex_unlock(&chip->audio_mutex);
 
@@ -348,6 +354,7 @@
 	case IDX_INCALL_CAP0_TX:
 	case IDX_INCALL_CAP1_TX:
 	case IDX_INCALL_CAP2_TX:
+	case IDX_INCALL_CAP3_TX:
 		return msecs_to_jiffies(chip->voice_pcm_wait_time_in_ms);
 	default:
 		return msecs_to_jiffies(chip->pcm_wait_time_in_ms);
diff --git a/alsa/aoc_alsa_path.c b/alsa/aoc_alsa_path.c
index 8447efb..fcb4368 100644
--- a/alsa/aoc_alsa_path.c
+++ b/alsa/aoc_alsa_path.c
@@ -529,6 +529,20 @@
 
 	{
 		.capture = {
+			.stream_name = "audio_incall_cap_3",
+			.rates = SNDRV_PCM_RATE_8000_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE |
+					SNDRV_PCM_FMTBIT_S24_LE |
+					SNDRV_PCM_FMTBIT_S32_LE,
+			.channels_min = 1,
+			.channels_max = 8,
+		},
+		.name = "audio_incall_cap_3",
+		.id = IDX_INCALL_CAP3_TX,
+	},
+
+	{
+		.capture = {
 			.stream_name = "audio_hifiin",
 			.rates = SNDRV_PCM_RATE_8000_192000,
 			.formats = SNDRV_PCM_FMTBIT_S16_LE |
diff --git a/alsa/google-aoc-enum.h b/alsa/google-aoc-enum.h
index b4b2b6f..affabcd 100644
--- a/alsa/google-aoc-enum.h
+++ b/alsa/google-aoc-enum.h
@@ -78,6 +78,7 @@
 	IDX_CAPTURE_INJECTION,
 	IDX_HOTWORD_TAP,
 	IDX_DP_DMA_NoHOST,
+	IDX_INCALL_CAP3,
 	IDX_FE_MAX,
 };
 
@@ -151,5 +152,6 @@
 #define IDX_ANDROID_AEC_TX	(AOC_FE|AOC_TX|IDX_ANDROID_AEC)
 #define IDX_RAW_TX			(AOC_FE|AOC_TX|IDX_RAW)
 #define IDX_HOTWORD_TAP_TX	(AOC_FE|AOC_TX|IDX_HOTWORD_TAP)
+#define IDX_INCALL_CAP3_TX	(AOC_FE|AOC_TX|IDX_INCALL_CAP3)
 
 #endif /* __GOOGLE_AOC_ENUM_H__ */