asoc: apq8009: Add mixer control to set afe loopback channels

Add new mixer control to set afe loopback tx channels.

CRs-Fixed: 2353062
Change-Id: I21b1b121ca9cdd801853a6dde29a1e0c3593b583
Signed-off-by: Dhanalakshmi Siddani <dsiddani@codeaurora.org>
diff --git a/asoc/apq8009-i2s-ext-codec.c b/asoc/apq8009-i2s-ext-codec.c
index 774ef3f..0f3a8ba 100644
--- a/asoc/apq8009-i2s-ext-codec.c
+++ b/asoc/apq8009-i2s-ext-codec.c
@@ -1,4 +1,4 @@
- /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ /* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 and
@@ -161,6 +161,7 @@
 static int msm_btsco_ch = 1;
 
 static int msm_mi2s_tx_ch = 2;
+static int msm_afe_lb_tx_ch = 2;
 static int msm_pri_mi2s_rx_ch = 2;
 static int pri_rx_sample_rate = SAMPLING_RATE_48KHZ;
 static int pri_tx_sample_rate = SAMPLING_RATE_48KHZ;
@@ -358,6 +359,7 @@
 static char const *pri_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96",
 						"KHZ_192", "KHZ_8", 
 						"KHZ_16", "KHZ_32"};
+static const char *const afe_lb_tx_ch_text[] = {"One", "Two"};
 
 static int msm_pri_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
@@ -773,6 +775,21 @@
 	return 0;
 }
 
+static int msm_afe_lb_tx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+				struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_interval *channels = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	pr_debug("%s(), channel: %d\n", __func__, msm_afe_lb_tx_ch);
+	rate->min = rate->max = 48000;
+	channels->min = channels->max = msm_afe_lb_tx_ch;
+
+	return 0;
+}
+
 static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 		struct snd_pcm_hw_params *params)
 {
@@ -1068,6 +1085,25 @@
 	return 1;
 }
 
+static int msm_afe_loopback_tx_ch_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm_afe_lb_tx_ch = %d\n", __func__,
+		 msm_afe_lb_tx_ch);
+	ucontrol->value.integer.value[0] = msm_afe_lb_tx_ch - 1;
+	return 0;
+}
+
+static int msm_afe_loopback_tx_ch_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	msm_afe_lb_tx_ch = ucontrol->value.integer.value[0] + 1;
+
+	pr_debug("%s: msm_afe_lb_tx_ch = %d\n", __func__,
+			msm_afe_lb_tx_ch);
+	return 1;
+}
+
 static int msm_mi2s_snd_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params)
 {
@@ -1253,6 +1289,8 @@
 			tdm_bit_format_text),
 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_sample_rate_text),
 			tdm_sample_rate_text),
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(afe_lb_tx_ch_text),
+			afe_lb_tx_ch_text),
 };
 
 static const char *const btsco_rate_text[] = {"BTSCO_RATE_8KHZ",
@@ -1290,6 +1328,9 @@
 	SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", msm_snd_enum[5],
 			msm_pri_tdm_tx_0_sample_rate_get,
 			msm_pri_tdm_tx_0_sample_rate_put),
+	SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", msm_snd_enum[6],
+			msm_afe_loopback_tx_ch_get,
+			msm_afe_loopback_tx_ch_put),
 };
 
 static int apq8009_mclk_event(struct snd_soc_dapm_widget *w,
@@ -1724,6 +1765,7 @@
 		.no_pcm = 1,
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_AFE_LOOPBACK_TX,
+		.be_hw_params_fixup = msm_afe_lb_tx_hw_params_fixup,
 		.ignore_pmdown_time = 1,
 		.ignore_suspend = 1,
 	},