ASoC: msm8960: Add LPA volume control

LPA volume is controlled via dsp stream volume support
available. Add TLV mixer control to set LPA stream volume

Signed-off-by: Asish Bhattacharya <asishb@codeaurora.org>
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 39529c4..097bd1c 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -60,6 +60,13 @@
 static const DECLARE_TLV_DB_SCALE(fm_rx_vol_gain, 0,
 			INT_FM_RX_VOL_MAX_STEPS, 0);
 
+#define INT_LPA_RX_VOL_MAX_STEPS 0x100
+#define INT_LPA_RX_VOL_GAIN 0x3FFF
+
+static int msm_route_lpa_vol_control;
+static const DECLARE_TLV_DB_SCALE(lpa_rx_vol_gain, 0,
+			INT_LPA_RX_VOL_MAX_STEPS, 0);
+
 /* Tx mixer session is stored based on BE DAI ID
  * Need to map to actual AFE port ID since AFE port
  * ID can get really large.
@@ -405,6 +412,23 @@
 	return 0;
 }
 
+static int msm_routing_get_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = msm_route_lpa_vol_control;
+	return 0;
+}
+
+static int msm_routing_set_lpa_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	if (!lpa_set_volume(ucontrol->value.integer.value[0]))
+		msm_route_lpa_vol_control =
+			ucontrol->value.integer.value[0];
+
+	return 0;
+}
+
 static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
 	SOC_SINGLE_EXT("MultiMedia1", AUDIO_MIXER_PRI_I2S_RX ,
 	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -542,6 +566,12 @@
 	msm_routing_set_fm_vol_mixer, fm_rx_vol_gain),
 };
 
+static const struct snd_kcontrol_new lpa_vol_mixer_controls[] = {
+	SOC_SINGLE_EXT_TLV("LPA RX Volume", SND_SOC_NOPM, 0,
+	INT_LPA_RX_VOL_GAIN, 0, msm_routing_get_lpa_vol_mixer,
+	msm_routing_set_lpa_vol_mixer, lpa_rx_vol_gain),
+};
+
 static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
 	/* Frontend AIF */
 	/* Widget name equals to Front-End DAI name<Need confirmation>,
@@ -707,6 +737,10 @@
 	snd_soc_add_platform_controls(platform,
 				int_fm_vol_mixer_controls,
 			ARRAY_SIZE(int_fm_vol_mixer_controls));
+
+	snd_soc_add_platform_controls(platform,
+				lpa_vol_mixer_controls,
+			ARRAY_SIZE(lpa_vol_mixer_controls));
 	return 0;
 }