summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorDerek Chen <chenche@codeaurora.org>2015-11-06 17:46:18 -0500
committerGerrit - the friendly Code Review server <code-review@localhost>2017-03-02 13:57:04 -0800
commit78705dc54bd0df9a21a48b5cbdc0de3951b2410c (patch)
treee6f9f8ea8cf7a5e32fb781591fe71e2bbf1d3126 /sound
parent660ab6c3a2409a5de73575976a321b8ae7a4889b (diff)
ASoC: msm: Add machine driver for APQ8096 based automotive platform
Add machine driver for APQ8096 based automotive platform. The machine driver is based on msm8996.c. On top of it, add support for TDM which is used for data transfer between APQ8096 and the automotive COODEC HW, the changes include add TDM backend and frontend DAI links as well as kcontrol functions to configure TDM channels. CRs-fixed: 2002348 Change-Id: Id4e8931c06de9cf20f8012d84cd808f919020174 Signed-off-by: Honghao Liu <honghaol@codeaurora.org> Signed-off-by: Derek Chen <chenche@codeaurora.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/msm/Makefile2
-rw-r--r--sound/soc/msm/apq8096-auto.c4458
2 files changed, 4459 insertions, 1 deletions
diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile
index cd63b491285c..63c4e61430c4 100644
--- a/sound/soc/msm/Makefile
+++ b/sound/soc/msm/Makefile
@@ -13,7 +13,7 @@ snd-soc-cpe-objs := msm-cpe-lsm.o
obj-$(CONFIG_SND_SOC_CPE) += snd-soc-cpe.o
# for MSM8996 sound card driver
-snd-soc-msm8996-objs := msm8996.o
+snd-soc-msm8996-objs := msm8996.o apq8096-auto.o
obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-msm8996.o
# for MSM8998 sound card driver
diff --git a/sound/soc/msm/apq8096-auto.c b/sound/soc/msm/apq8096-auto.c
new file mode 100644
index 000000000000..138f4a02452c
--- /dev/null
+++ b/sound/soc/msm/apq8096-auto.c
@@ -0,0 +1,4458 @@
+/*
+ * Copyright (c) 2014-2017, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/switch.h>
+#include <linux/input.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/jack.h>
+#include <sound/q6afe-v2.h>
+#include <sound/q6adm-v2.h>
+#include <sound/q6core.h>
+#include <sound/pcm_params.h>
+#include <sound/info.h>
+#include <device_event.h>
+#include "qdsp6v2/msm-pcm-routing-v2.h"
+
+#define DRV_NAME "apq8096-auto-asoc-snd"
+
+#define SAMPLING_RATE_8KHZ 8000
+#define SAMPLING_RATE_16KHZ 16000
+#define SAMPLING_RATE_32KHZ 32000
+#define SAMPLING_RATE_44P1KHZ 44100
+#define SAMPLING_RATE_48KHZ 48000
+#define SAMPLING_RATE_96KHZ 96000
+#define SAMPLING_RATE_192KHZ 192000
+#define SAMPLING_RATE_384KHZ 384000
+
+static int hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_auxpcm_rate = SAMPLING_RATE_8KHZ;
+static int msm_hdmi_rx_ch = 2;
+static int msm_proxy_rx_ch = 2;
+static int hdmi_rx_sample_rate = SAMPLING_RATE_48KHZ;
+static int msm_sec_mi2s_tx_ch = 2;
+static int msm_tert_mi2s_tx_ch = 2;
+static int msm_quat_mi2s_rx_ch = 2;
+static int msm_sec_mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_tert_mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_quat_mi2s_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
+/* TDM default channels */
+static int msm_sec_tdm_tx_0_ch = 2; /* STEREO MIC */
+static int msm_sec_tdm_tx_1_ch = 2;
+static int msm_sec_tdm_tx_2_ch = 2;
+static int msm_sec_tdm_tx_3_ch = 2;
+
+static int msm_tert_tdm_rx_0_ch = 2; /* ICC STREAM */
+static int msm_tert_tdm_rx_1_ch = 2;
+static int msm_tert_tdm_rx_2_ch = 2;
+static int msm_tert_tdm_rx_3_ch = 2;
+
+static int msm_tert_tdm_tx_0_ch = 6; /* EC_REF1-EC_REF6(6 CHAN) */
+static int msm_tert_tdm_tx_1_ch = 1;
+static int msm_tert_tdm_tx_2_ch = 1;
+static int msm_tert_tdm_tx_3_ch;
+
+static int msm_quat_tdm_rx_0_ch = 6; /* ENT */
+static int msm_quat_tdm_rx_1_ch = 1; /* ANN */
+static int msm_quat_tdm_rx_2_ch = 1; /* TEL */
+static int msm_quat_tdm_rx_3_ch;
+
+static int msm_quat_tdm_tx_0_ch = 4; /*MIC1-MIC4*/
+static int msm_quat_tdm_tx_1_ch = 2; /*EC_REF(2 CHAN)*/
+static int msm_quat_tdm_tx_2_ch = 2; /*ENT RECORD*/
+static int msm_quat_tdm_tx_3_ch;
+
+/* TDM default bit format */
+static int msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_sec_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_sec_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_sec_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
+static int msm_tert_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_tert_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_tert_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_tert_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
+static int msm_tert_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_tert_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_tert_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_tert_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
+static int msm_quat_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_quat_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_quat_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_quat_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
+static int msm_quat_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_quat_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_quat_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_quat_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
+/* EC Reference default values are set in mixer_paths.xml */
+static int msm_ec_ref_ch = 4;
+static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_ec_ref_sampling_rate = SAMPLING_RATE_48KHZ;
+
+static void *adsp_state_notifier;
+static bool dummy_device_registered;
+
+enum {
+ QUATERNARY_TDM_RX_0,
+ QUATERNARY_TDM_RX_1,
+ QUATERNARY_TDM_RX_2,
+ QUATERNARY_TDM_RX_3,
+ QUATERNARY_TDM_RX_4,
+ QUATERNARY_TDM_RX_5,
+ QUATERNARY_TDM_RX_6,
+ QUATERNARY_TDM_RX_7,
+ QUATERNARY_TDM_TX_0,
+ QUATERNARY_TDM_TX_1,
+ QUATERNARY_TDM_TX_2,
+ QUATERNARY_TDM_TX_3,
+ QUATERNARY_TDM_TX_4,
+ QUATERNARY_TDM_TX_5,
+ QUATERNARY_TDM_TX_6,
+ QUATERNARY_TDM_TX_7,
+ TERTIARY_TDM_RX_0,
+ TERTIARY_TDM_RX_1,
+ TERTIARY_TDM_RX_2,
+ TERTIARY_TDM_RX_3,
+ TERTIARY_TDM_RX_4,
+ TERTIARY_TDM_RX_5,
+ TERTIARY_TDM_RX_6,
+ TERTIARY_TDM_RX_7,
+ TERTIARY_TDM_TX_0,
+ TERTIARY_TDM_TX_1,
+ TERTIARY_TDM_TX_2,
+ TERTIARY_TDM_TX_3,
+ TERTIARY_TDM_TX_4,
+ TERTIARY_TDM_TX_5,
+ TERTIARY_TDM_TX_6,
+ TERTIARY_TDM_TX_7,
+ SECONDARY_TDM_RX_0,
+ SECONDARY_TDM_RX_1,
+ SECONDARY_TDM_RX_2,
+ SECONDARY_TDM_RX_3,
+ SECONDARY_TDM_RX_4,
+ SECONDARY_TDM_RX_5,
+ SECONDARY_TDM_RX_6,
+ SECONDARY_TDM_RX_7,
+ SECONDARY_TDM_TX_0,
+ SECONDARY_TDM_TX_1,
+ SECONDARY_TDM_TX_2,
+ SECONDARY_TDM_TX_3,
+ SECONDARY_TDM_TX_4,
+ SECONDARY_TDM_TX_5,
+ SECONDARY_TDM_TX_6,
+ SECONDARY_TDM_TX_7,
+ TDM_MAX,
+};
+
+#define TDM_SLOT_OFFSET_MAX 8
+
+/* TDM default offset */
+static unsigned int tdm_slot_offset[TDM_MAX][TDM_SLOT_OFFSET_MAX] = {
+ /* QUAT_TDM_RX */
+ {0, 4, 8, 12, 16, 20, 0xFFFF},
+ {24, 0xFFFF},
+ {28, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* QUAT_TDM_TX */
+ {0, 4, 8, 12, 0xFFFF},
+ {16, 20, 0xFFFF},
+ {24, 28, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* TERT_TDM_RX */
+ {0, 4, 8, 12, 0xFFFF},
+ {16, 20, 0xFFFF},
+ {24, 28, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* TERT_TDM_TX */
+ {0, 4, 8, 12, 16, 20, 0xFFFF},
+ {24, 0xFFFF},
+ {28, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* SEC_TDM_RX */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* SEC_TDM_TX */
+ {0, 4, 0xFFFF},
+ {8, 12, 0xFFFF},
+ {16, 20, 0xFFFF},
+ {24, 28, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+};
+
+
+/***************************************************************************
+* Codec/Platform specific tdm slot offset table
+* NOTE:
+* each entry represents the slot offset array of one backend tdm device
+* valid offset represents the starting offset in byte for the channel
+* use 0xFFFF for end or unused slot offset entry
+***************************************************************************/
+static unsigned int tdm_slot_offset_adp_mmxf[TDM_MAX][TDM_SLOT_OFFSET_MAX] = {
+ /* QUAT_TDM_RX */
+ {2, 5, 8, 11, 14, 17, 20, 23},
+ {26, 0xFFFF},
+ {28, 0xFFFF},
+ {30, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* QUAT_TDM_TX */
+ {2, 0xFFFF},
+ {10, 0xFFFF},
+ {20, 22, 26, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* TERT_TDM_RX */
+ {2, 5, 8, 11, 14, 17, 20, 23},
+ {26, 0xFFFF},
+ {28, 0xFFFF},
+ {30, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* TERT_TDM_TX */
+ {2, 0xFFFF},
+ {10, 0xFFFF},
+ {20, 22, 26, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* SEC_TDM_RX */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* SEC_TDM_TX */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+};
+
+
+static char const *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five",
+ "Six", "Seven", "Eight"};
+
+static char const *hdmi_rx_bit_format_text[] = {"S16_LE", "S24_LE"};
+
+static const char *const proxy_rx_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven", "Eight"};
+
+static char const *hdmi_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96",
+ "KHZ_192"};
+
+static const char *const auxpcm_rate_text[] = {"8000", "16000"};
+
+static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven", "Eight"};
+
+static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE"};
+
+static char const *mi2s_bit_format_text[] = {"S16_LE", "S24_LE"};
+
+static const char *const ec_ref_ch_text[] = {"Zero", "One", "Two", "Three",
+ "Four", "Five", "Six", "Seven", "Eight"};
+
+static char const *ec_ref_bit_format_text[] = {"0", "S16_LE", "S24_LE"};
+
+static const char *const ec_ref_rate_text[] = {"0", "8000", "16000",
+ "32000", "44100", "48000", "96000", "192000", "384000"};
+
+static struct afe_clk_set sec_mi2s_tx_clk = {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT,
+ Q6AFE_LPASS_IBIT_CLK_DISABLE,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+};
+
+static struct afe_clk_set mi2s_tx_clk = {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT,
+ Q6AFE_LPASS_IBIT_CLK_DISABLE,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+};
+
+static struct afe_clk_set mi2s_rx_clk = {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+};
+
+static inline int param_is_mask(int p)
+{
+ return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
+ (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
+}
+
+static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p,
+ int n)
+{
+ return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
+}
+
+static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit)
+{
+ if (bit >= SNDRV_MASK_MAX)
+ return;
+ if (param_is_mask(n)) {
+ struct snd_mask *m = param_to_mask(p, n);
+
+ m->bits[0] = 0;
+ m->bits[1] = 0;
+ m->bits[bit >> 5] |= (1 << (bit & 31));
+ }
+}
+
+static int hdmi_rx_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ switch (hdmi_rx_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+
+ pr_debug("%s: hdmi_rx_bit_format = %d, ucontrol value = %ld\n",
+ __func__, hdmi_rx_bit_format,
+ ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int hdmi_rx_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: hdmi_rx_bit_format = %d, ucontrol value = %ld\n",
+ __func__, hdmi_rx_bit_format,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_hdmi_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__,
+ msm_hdmi_rx_ch);
+ ucontrol->value.integer.value[0] = msm_hdmi_rx_ch - 2;
+
+ return 0;
+}
+
+static int msm_hdmi_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_hdmi_rx_ch = ucontrol->value.integer.value[0] + 2;
+ if (msm_hdmi_rx_ch > 8) {
+ pr_err("%s: channels %d exceeded 8.Limiting to max chs-8\n",
+ __func__, msm_hdmi_rx_ch);
+ msm_hdmi_rx_ch = 8;
+ }
+ pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__, msm_hdmi_rx_ch);
+
+ return 1;
+}
+
+static int hdmi_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int sample_rate_val = 0;
+
+ switch (hdmi_rx_sample_rate) {
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 2;
+ break;
+
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 1;
+ break;
+
+ case SAMPLING_RATE_48KHZ:
+ default:
+ sample_rate_val = 0;
+ break;
+ }
+
+ ucontrol->value.integer.value[0] = sample_rate_val;
+ pr_debug("%s: hdmi_rx_sample_rate = %d\n", __func__,
+ hdmi_rx_sample_rate);
+
+ return 0;
+}
+
+static int hdmi_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: ucontrol value = %ld\n", __func__,
+ ucontrol->value.integer.value[0]);
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 2:
+ hdmi_rx_sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 1:
+ hdmi_rx_sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 0:
+ default:
+ hdmi_rx_sample_rate = SAMPLING_RATE_48KHZ;
+ }
+
+ pr_debug("%s: hdmi_rx_sample_rate = %d\n", __func__,
+ hdmi_rx_sample_rate);
+
+ return 0;
+}
+
+static int msm_auxpcm_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = msm_auxpcm_rate;
+ return 0;
+}
+
+static int msm_auxpcm_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ msm_auxpcm_rate = SAMPLING_RATE_8KHZ;
+ break;
+ case 1:
+ msm_auxpcm_rate = SAMPLING_RATE_16KHZ;
+ break;
+ default:
+ msm_auxpcm_rate = SAMPLING_RATE_8KHZ;
+ break;
+ }
+ return 0;
+}
+
+static int msm_proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_proxy_rx_ch = %d\n", __func__, msm_proxy_rx_ch);
+ ucontrol->value.integer.value[0] = msm_proxy_rx_ch - 1;
+ return 0;
+}
+
+static int msm_proxy_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_proxy_rx_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_proxy_rx_ch = %d\n", __func__, msm_proxy_rx_ch);
+ return 1;
+}
+
+static int msm_quat_mi2s_rx_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_quat_mi2s_rx_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_quat_mi2s_rx_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_quat_mi2s_rx_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_quat_mi2s_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_quat_mi2s_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_quat_mi2s_rx_bit_format = %d\n",
+ __func__, msm_quat_mi2s_rx_bit_format);
+ return 0;
+}
+
+static int msm_tert_mi2s_tx_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_tert_mi2s_tx_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_tert_mi2s_tx_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_tert_mi2s_tx_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_tert_mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_tert_mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_tert_mi2s_tx_bit_format = %d\n",
+ __func__, msm_tert_mi2s_tx_bit_format);
+ return 0;
+}
+
+static int msm_sec_mi2s_tx_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_sec_mi2s_tx_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_sec_mi2s_tx_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_sec_mi2s_tx_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_sec_mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_sec_mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_sec_mi2s_tx_bit_format = %d\n",
+ __func__, msm_sec_mi2s_tx_bit_format);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_sec_tdm_tx_0_ch = %d\n", __func__,
+ msm_sec_tdm_tx_0_ch);
+ ucontrol->value.integer.value[0] = msm_sec_tdm_tx_0_ch - 1;
+ return 0;
+}
+
+static int msm_sec_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_sec_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_sec_tdm_tx_0_ch = %d\n", __func__,
+ msm_sec_tdm_tx_0_ch);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_1_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_sec_tdm_tx_1_ch = %d\n", __func__,
+ msm_sec_tdm_tx_1_ch);
+ ucontrol->value.integer.value[0] = msm_sec_tdm_tx_1_ch - 1;
+ return 0;
+}
+
+static int msm_sec_tdm_tx_1_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_sec_tdm_tx_1_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_sec_tdm_tx_1_ch = %d\n", __func__,
+ msm_sec_tdm_tx_1_ch);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_2_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_sec_tdm_tx_2_ch = %d\n", __func__,
+ msm_sec_tdm_tx_2_ch);
+ ucontrol->value.integer.value[0] = msm_sec_tdm_tx_2_ch - 1;
+ return 0;
+}
+
+static int msm_sec_tdm_tx_2_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_sec_tdm_tx_2_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_sec_tdm_tx_2_ch = %d\n", __func__,
+ msm_sec_tdm_tx_2_ch);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_3_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_sec_tdm_tx_3_ch = %d\n", __func__,
+ msm_sec_tdm_tx_3_ch);
+ ucontrol->value.integer.value[0] = msm_sec_tdm_tx_3_ch - 1;
+ return 0;
+}
+
+static int msm_sec_tdm_tx_3_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_sec_tdm_tx_3_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_sec_tdm_tx_3_ch = %d\n", __func__,
+ msm_sec_tdm_tx_3_ch);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_tert_tdm_rx_0_ch = %d\n", __func__,
+ msm_tert_tdm_rx_0_ch);
+ ucontrol->value.integer.value[0] = msm_tert_tdm_rx_0_ch - 1;
+ return 0;
+}
+
+static int msm_tert_tdm_rx_0_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_tert_tdm_rx_0_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_tert_tdm_rx_0_ch = %d\n", __func__,
+ msm_tert_tdm_rx_0_ch);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_1_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_tert_tdm_rx_1_ch = %d\n", __func__,
+ msm_tert_tdm_rx_1_ch);
+ ucontrol->value.integer.value[0] = msm_tert_tdm_rx_1_ch - 1;
+ return 0;
+}
+
+static int msm_tert_tdm_rx_1_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_tert_tdm_rx_1_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_tert_tdm_rx_1_ch = %d\n", __func__,
+ msm_tert_tdm_rx_1_ch);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_2_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_tert_tdm_rx_2_ch = %d\n", __func__,
+ msm_tert_tdm_rx_2_ch);
+ ucontrol->value.integer.value[0] = msm_tert_tdm_rx_2_ch - 1;
+ return 0;
+}
+
+static int msm_tert_tdm_rx_2_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_tert_tdm_rx_2_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_tert_tdm_rx_2_ch = %d\n", __func__,
+ msm_tert_tdm_rx_2_ch);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_3_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_tert_tdm_rx_3_ch = %d\n", __func__,
+ msm_tert_tdm_rx_3_ch);
+ ucontrol->value.integer.value[0] = msm_tert_tdm_rx_3_ch - 1;
+ return 0;
+}
+
+static int msm_tert_tdm_rx_3_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_tert_tdm_rx_3_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_tert_tdm_rx_3_ch = %d\n", __func__,
+ msm_tert_tdm_rx_3_ch);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_tert_tdm_tx_0_ch = %d\n", __func__,
+ msm_tert_tdm_tx_0_ch);
+ ucontrol->value.integer.value[0] = msm_tert_tdm_tx_0_ch - 1;
+ return 0;
+}
+
+static int msm_tert_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_tert_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_tert_tdm_tx_0_ch = %d\n", __func__,
+ msm_tert_tdm_tx_0_ch);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_1_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_tert_tdm_tx_1_ch = %d\n", __func__,
+ msm_tert_tdm_tx_1_ch);
+ ucontrol->value.integer.value[0] = msm_tert_tdm_tx_1_ch - 1;
+ return 0;
+}
+
+static int msm_tert_tdm_tx_1_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_tert_tdm_tx_1_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_tert_tdm_tx_1_ch = %d\n", __func__,
+ msm_tert_tdm_tx_1_ch);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_2_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_tert_tdm_tx_2_ch = %d\n", __func__,
+ msm_tert_tdm_tx_2_ch);
+ ucontrol->value.integer.value[0] = msm_tert_tdm_tx_2_ch - 1;
+ return 0;
+}
+
+static int msm_tert_tdm_tx_2_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_tert_tdm_tx_2_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_tert_tdm_tx_2_ch = %d\n", __func__,
+ msm_tert_tdm_tx_2_ch);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_3_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_tert_tdm_tx_3_ch = %d\n", __func__,
+ msm_tert_tdm_tx_3_ch);
+ ucontrol->value.integer.value[0] = msm_tert_tdm_tx_3_ch - 1;
+ return 0;
+}
+
+static int msm_tert_tdm_tx_3_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_tert_tdm_tx_3_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_tert_tdm_tx_3_ch = %d\n", __func__,
+ msm_tert_tdm_tx_3_ch);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_quat_tdm_rx_0_ch = %d\n", __func__,
+ msm_quat_tdm_rx_0_ch);
+ ucontrol->value.integer.value[0] = msm_quat_tdm_rx_0_ch - 1;
+ return 0;
+}
+
+static int msm_quat_tdm_rx_0_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_quat_tdm_rx_0_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_quat_tdm_rx_0_ch = %d\n", __func__,
+ msm_quat_tdm_rx_0_ch);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_1_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_quat_tdm_rx_1_ch = %d\n", __func__,
+ msm_quat_tdm_rx_1_ch);
+ ucontrol->value.integer.value[0] = msm_quat_tdm_rx_1_ch - 1;
+ return 0;
+}
+
+static int msm_quat_tdm_rx_1_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_quat_tdm_rx_1_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_quat_tdm_rx_1_ch = %d\n", __func__,
+ msm_quat_tdm_rx_1_ch);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_2_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_quat_tdm_rx_2_ch = %d\n", __func__,
+ msm_quat_tdm_rx_2_ch);
+ ucontrol->value.integer.value[0] = msm_quat_tdm_rx_2_ch - 1;
+ return 0;
+}
+
+static int msm_quat_tdm_rx_2_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_quat_tdm_rx_2_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_quat_tdm_rx_2_ch = %d\n", __func__,
+ msm_quat_tdm_rx_2_ch);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_3_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_quat_tdm_rx_3_ch = %d\n", __func__,
+ msm_quat_tdm_rx_3_ch);
+ ucontrol->value.integer.value[0] = msm_quat_tdm_rx_3_ch - 1;
+ return 0;
+}
+
+static int msm_quat_tdm_rx_3_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_quat_tdm_rx_3_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_quat_tdm_rx_3_ch = %d\n", __func__,
+ msm_quat_tdm_rx_3_ch);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_quat_tdm_tx_0_ch = %d\n", __func__,
+ msm_quat_tdm_tx_0_ch);
+ ucontrol->value.integer.value[0] = msm_quat_tdm_tx_0_ch - 1;
+ return 0;
+}
+
+static int msm_quat_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_quat_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_quat_tdm_tx_0_ch = %d\n", __func__,
+ msm_quat_tdm_tx_0_ch);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_1_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_quat_tdm_tx_1_ch = %d\n", __func__,
+ msm_quat_tdm_tx_1_ch);
+ ucontrol->value.integer.value[0] = msm_quat_tdm_tx_1_ch - 1;
+ return 0;
+}
+
+static int msm_quat_tdm_tx_1_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_quat_tdm_tx_1_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_quat_tdm_tx_1_ch = %d\n", __func__,
+ msm_quat_tdm_tx_1_ch);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_2_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_quat_tdm_tx_2_ch = %d\n", __func__,
+ msm_quat_tdm_tx_2_ch);
+ ucontrol->value.integer.value[0] = msm_quat_tdm_tx_2_ch - 1;
+ return 0;
+}
+
+static int msm_quat_tdm_tx_2_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_quat_tdm_tx_2_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_quat_tdm_tx_2_ch = %d\n", __func__,
+ msm_quat_tdm_tx_2_ch);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_3_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_quat_tdm_tx_3_ch = %d\n", __func__,
+ msm_quat_tdm_tx_3_ch);
+ ucontrol->value.integer.value[0] = msm_quat_tdm_tx_3_ch - 1;
+ return 0;
+}
+
+static int msm_quat_tdm_tx_3_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_quat_tdm_tx_3_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_quat_tdm_tx_3_ch = %d\n", __func__,
+ msm_quat_tdm_tx_3_ch);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_sec_tdm_tx_0_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_sec_tdm_tx_0_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_sec_tdm_tx_0_bit_format = %d\n",
+ __func__, msm_sec_tdm_tx_0_bit_format);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_1_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_sec_tdm_tx_1_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_sec_tdm_tx_1_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_1_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_sec_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_sec_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_sec_tdm_tx_1_bit_format = %d\n",
+ __func__, msm_sec_tdm_tx_1_bit_format);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_2_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_sec_tdm_tx_2_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_sec_tdm_tx_2_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_2_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_sec_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_sec_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_sec_tdm_tx_2_bit_format = %d\n",
+ __func__, msm_sec_tdm_tx_2_bit_format);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_3_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_sec_tdm_tx_3_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_sec_tdm_tx_3_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_sec_tdm_tx_3_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_sec_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_sec_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_sec_tdm_tx_3_bit_format = %d\n",
+ __func__, msm_sec_tdm_tx_3_bit_format);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_0_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_tert_tdm_rx_0_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_rx_0_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_0_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_tert_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_tert_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_rx_0_bit_format = %d\n",
+ __func__, msm_tert_tdm_rx_0_bit_format);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_1_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_tert_tdm_rx_1_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_rx_1_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_1_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_tert_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_tert_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_rx_1_bit_format = %d\n",
+ __func__, msm_tert_tdm_rx_1_bit_format);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_2_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_tert_tdm_rx_2_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_rx_2_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_2_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_tert_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_tert_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_rx_2_bit_format = %d\n",
+ __func__, msm_tert_tdm_rx_2_bit_format);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_3_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_tert_tdm_rx_3_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_rx_3_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_tert_tdm_rx_3_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_tert_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_tert_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_rx_3_bit_format = %d\n",
+ __func__, msm_tert_tdm_rx_3_bit_format);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_tert_tdm_tx_0_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_tx_0_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_tert_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_tert_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_tx_0_bit_format = %d\n",
+ __func__, msm_tert_tdm_tx_0_bit_format);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_1_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_tert_tdm_tx_1_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_tx_1_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_1_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_tert_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_tert_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_tx_1_bit_format = %d\n",
+ __func__, msm_tert_tdm_tx_1_bit_format);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_2_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_tert_tdm_tx_2_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_tx_2_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_2_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_tert_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_tert_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_tx_2_bit_format = %d\n",
+ __func__, msm_tert_tdm_tx_2_bit_format);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_3_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_tert_tdm_tx_3_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_tx_3_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_tert_tdm_tx_3_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_tert_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_tert_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_tert_tdm_tx_3_bit_format = %d\n",
+ __func__, msm_tert_tdm_tx_3_bit_format);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_0_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_quat_tdm_rx_0_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_rx_0_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_0_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_quat_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_quat_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_rx_0_bit_format = %d\n",
+ __func__, msm_quat_tdm_rx_0_bit_format);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_1_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_quat_tdm_rx_1_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_rx_1_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_1_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_quat_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_quat_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_rx_1_bit_format = %d\n",
+ __func__, msm_quat_tdm_rx_1_bit_format);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_2_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_quat_tdm_rx_2_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_rx_2_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_2_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_quat_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_quat_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_rx_2_bit_format = %d\n",
+ __func__, msm_quat_tdm_rx_2_bit_format);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_3_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_quat_tdm_rx_3_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_rx_3_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_quat_tdm_rx_3_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_quat_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_quat_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_rx_3_bit_format = %d\n",
+ __func__, msm_quat_tdm_rx_3_bit_format);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_quat_tdm_tx_0_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_tx_0_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_quat_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_quat_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_tx_0_bit_format = %d\n",
+ __func__, msm_quat_tdm_tx_0_bit_format);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_1_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_quat_tdm_tx_1_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_tx_1_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_1_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_quat_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_quat_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_tx_1_bit_format = %d\n",
+ __func__, msm_quat_tdm_tx_1_bit_format);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_2_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_quat_tdm_tx_2_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_tx_2_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_2_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_quat_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_quat_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_tx_2_bit_format = %d\n",
+ __func__, msm_quat_tdm_tx_2_bit_format);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_3_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_quat_tdm_tx_3_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_tx_3_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_quat_tdm_tx_3_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_quat_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_quat_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_quat_tdm_tx_3_bit_format = %d\n",
+ __func__, msm_quat_tdm_tx_3_bit_format);
+ return 0;
+}
+
+static int msm_ec_ref_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = msm_ec_ref_ch;
+ pr_debug("%s: msm_ec_ref_ch = %ld\n", __func__,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_ec_ref_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_ec_ref_ch = ucontrol->value.integer.value[0];
+ pr_debug("%s: msm_ec_ref_ch = %d\n", __func__, msm_ec_ref_ch);
+ adm_num_ec_ref_rx_chans(msm_ec_ref_ch);
+ return 0;
+}
+
+static int msm_ec_ref_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_ec_ref_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_ec_ref_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_ec_ref_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 2:
+ msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 1:
+ msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ default:
+ msm_ec_ref_bit_format = 0;
+ break;
+ }
+ pr_debug("%s: msm_ec_ref_bit_format = %d\n",
+ __func__, msm_ec_ref_bit_format);
+ adm_ec_ref_rx_bit_width(msm_ec_ref_bit_format);
+ return 0;
+}
+
+static int msm_ec_ref_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = msm_ec_ref_sampling_rate;
+ pr_debug("%s: msm_ec_ref_sampling_rate = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_ec_ref_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ msm_ec_ref_sampling_rate = 0;
+ break;
+ case 1:
+ msm_ec_ref_sampling_rate = SAMPLING_RATE_8KHZ;
+ break;
+ case 2:
+ msm_ec_ref_sampling_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 3:
+ msm_ec_ref_sampling_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 4:
+ msm_ec_ref_sampling_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 5:
+ msm_ec_ref_sampling_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 6:
+ msm_ec_ref_sampling_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 7:
+ msm_ec_ref_sampling_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 8:
+ msm_ec_ref_sampling_rate = SAMPLING_RATE_384KHZ;
+ break;
+ default:
+ msm_ec_ref_sampling_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ pr_debug("%s: msm_ec_ref_sampling_rate = %d\n",
+ __func__, msm_ec_ref_sampling_rate);
+ adm_ec_ref_rx_sampling_rate(msm_ec_ref_sampling_rate);
+ return 0;
+}
+
+static int msm_auxpcm_be_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);
+
+ rate->min = rate->max = msm_auxpcm_rate;
+ channels->min = channels->max = 1;
+
+ return 0;
+}
+
+static int msm_proxy_rx_be_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: msm_proxy_rx_ch =%d\n", __func__, msm_proxy_rx_ch);
+
+ if (channels->max < 2)
+ channels->min = channels->max = 2;
+ channels->min = channels->max = msm_proxy_rx_ch;
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ return 0;
+}
+
+static int msm_proxy_tx_be_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);
+
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ return 0;
+}
+
+static int msm_hdmi_be_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 channels->min %u channels->max %u ()\n", __func__,
+ channels->min, channels->max);
+
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ hdmi_rx_bit_format);
+ if (channels->max < 2)
+ channels->min = channels->max = 2;
+ rate->min = rate->max = hdmi_rx_sample_rate;
+ channels->min = channels->max = msm_hdmi_rx_ch;
+
+ return 0;
+}
+
+static int msm_mi2s_rx_be_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_quat_mi2s_rx_ch);
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ channels->min = channels->max = msm_quat_mi2s_rx_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_mi2s_rx_bit_format);
+
+ return 0;
+}
+
+static int msm_mi2s_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ 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);
+
+ switch (cpu_dai->id) {
+ case 0: /*MSM_PRIM_MI2S*/
+ break;
+ case 1: /*MSM_SEC_MI2S*/
+ pr_debug("%s: channel:%d\n", __func__, msm_sec_mi2s_tx_ch);
+ channels->min = channels->max = msm_sec_mi2s_tx_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_mi2s_tx_bit_format);
+ break;
+ case 2: /*MSM_TERT_MI2S*/
+ pr_debug("%s: channel:%d\n", __func__, msm_tert_mi2s_tx_ch);
+ channels->min = channels->max = msm_tert_mi2s_tx_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_mi2s_tx_bit_format);
+ break;
+ case 3: /*MSM_QUAT_MI2S*/
+ break;
+ default:
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+
+ pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n",
+ __func__, cpu_dai->id, channels->max, rate->max,
+ params_format(params));
+
+ return 0;
+}
+
+static int msm_be_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);
+
+ pr_debug("%s:\n", __func__);
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ return 0;
+}
+
+static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ 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);
+
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_SECONDARY_TDM_TX:
+ channels->min = channels->max = msm_sec_tdm_tx_0_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_tdm_tx_0_bit_format);
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX_1:
+ channels->min = channels->max = msm_sec_tdm_tx_1_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_tdm_tx_1_bit_format);
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX_2:
+ channels->min = channels->max = msm_sec_tdm_tx_2_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_tdm_tx_2_bit_format);
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX_3:
+ channels->min = channels->max = msm_sec_tdm_tx_3_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_tdm_tx_3_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX:
+ channels->min = channels->max = msm_tert_tdm_rx_0_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_tdm_rx_0_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX_1:
+ channels->min = channels->max = msm_tert_tdm_rx_1_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_tdm_rx_1_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX_2:
+ channels->min = channels->max = msm_tert_tdm_rx_2_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_tdm_rx_2_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX_3:
+ channels->min = channels->max = msm_tert_tdm_rx_3_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_tdm_rx_3_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX:
+ channels->min = channels->max = msm_tert_tdm_tx_0_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_tdm_tx_0_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX_1:
+ channels->min = channels->max = msm_tert_tdm_tx_1_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_tdm_tx_1_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX_2:
+ channels->min = channels->max = msm_tert_tdm_tx_2_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_tdm_tx_2_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX_3:
+ channels->min = channels->max = msm_tert_tdm_tx_3_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_tdm_tx_3_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX:
+ channels->min = channels->max = msm_quat_tdm_rx_0_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_tdm_rx_0_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
+ channels->min = channels->max = msm_quat_tdm_rx_1_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_tdm_rx_1_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
+ channels->min = channels->max = msm_quat_tdm_rx_2_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_tdm_rx_2_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
+ channels->min = channels->max = msm_quat_tdm_rx_3_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_tdm_rx_3_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX:
+ channels->min = channels->max = msm_quat_tdm_tx_0_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_tdm_tx_0_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
+ channels->min = channels->max = msm_quat_tdm_tx_1_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_tdm_tx_1_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
+ channels->min = channels->max = msm_quat_tdm_tx_2_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_tdm_tx_2_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
+ channels->min = channels->max = msm_quat_tdm_tx_3_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_tdm_tx_3_bit_format);
+ break;
+ default:
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+
+ pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n",
+ __func__, cpu_dai->id, channels->max, rate->max,
+ params_format(params));
+
+ return 0;
+}
+
+static int apq8096_mi2s_snd_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+ pr_debug("%s: substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+
+ switch (cpu_dai->id) {
+ case 0: /*MSM_PRIM_MI2S*/
+ break;
+ case 1: /*MSM_SEC_MI2S*/
+ sec_mi2s_tx_clk.enable = 1;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_SECONDARY_MI2S_TX,
+ &sec_mi2s_tx_clk);
+ if (ret < 0) {
+ pr_err("%s: afe lpass clock failed, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM);
+ if (ret < 0)
+ pr_err("%s: set fmt cpu dai failed, err:%d\n",
+ __func__, ret);
+ break;
+ case 2: /*MSM_TERT_MI2S*/
+ mi2s_tx_clk.enable = 1;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TERTIARY_MI2S_TX,
+ &mi2s_tx_clk);
+ if (ret < 0) {
+ pr_err("%s: afe lpass clock failed, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM);
+ if (ret < 0)
+ pr_err("%s: set fmt cpu dai failed, err:%d\n",
+ __func__, ret);
+ break;
+ case 3: /*MSM_QUAT_MI2S*/
+ mi2s_rx_clk.enable = 1;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_QUATERNARY_MI2S_RX,
+ &mi2s_rx_clk);
+ if (ret < 0) {
+ pr_err("%s: afe lpass clock failed, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ pr_err("%s: set fmt cpu dai failed, err:%d\n",
+ __func__, ret);
+ break;
+ default:
+ pr_err("%s: invalid cpu_dai id 0x%x\n", __func__, cpu_dai->id);
+ break;
+ }
+
+err:
+ return ret;
+}
+
+static void apq8096_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+ pr_debug("%s: substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+
+ switch (cpu_dai->id) {
+ case 0: /*MSM_PRIM_MI2S*/
+ break;
+ case 1: /*MSM_SEC_MI2S*/
+ sec_mi2s_tx_clk.enable = 0;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_SECONDARY_MI2S_TX,
+ &sec_mi2s_tx_clk);
+ if (ret < 0)
+ pr_err("%s: afe lpass clock failed, err:%d\n",
+ __func__, ret);
+ break;
+ case 2: /*MSM_TERT_MI2S*/
+ mi2s_tx_clk.enable = 0;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TERTIARY_MI2S_TX,
+ &mi2s_tx_clk);
+ if (ret < 0)
+ pr_err("%s: afe lpass clock failed, err:%d\n",
+ __func__, ret);
+ break;
+ case 3: /*MSM_QUAT_MI2S*/
+ mi2s_rx_clk.enable = 0;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_QUATERNARY_MI2S_RX,
+ &mi2s_rx_clk);
+ if (ret < 0)
+ pr_err("%s: afe lpass clock failed, err:%d\n",
+ __func__, ret);
+ break;
+ default:
+ pr_err("%s: invalid cpu_dai id 0x%x\n", __func__, cpu_dai->id);
+ break;
+ }
+}
+
+static struct snd_soc_ops apq8096_mi2s_be_ops = {
+ .startup = apq8096_mi2s_snd_startup,
+ .shutdown = apq8096_mi2s_snd_shutdown,
+};
+
+static unsigned int tdm_param_set_slot_mask(u16 port_id,
+ int slot_width, int slots)
+{
+ unsigned int slot_mask = 0;
+ int upper, lower, i, j;
+ unsigned int *slot_offset;
+
+ switch (port_id) {
+ case AFE_PORT_ID_SECONDARY_TDM_RX:
+ case AFE_PORT_ID_SECONDARY_TDM_RX_1:
+ case AFE_PORT_ID_SECONDARY_TDM_RX_2:
+ case AFE_PORT_ID_SECONDARY_TDM_RX_3:
+ case AFE_PORT_ID_SECONDARY_TDM_RX_4:
+ case AFE_PORT_ID_SECONDARY_TDM_RX_5:
+ case AFE_PORT_ID_SECONDARY_TDM_RX_6:
+ case AFE_PORT_ID_SECONDARY_TDM_RX_7:
+ lower = SECONDARY_TDM_RX_0;
+ upper = SECONDARY_TDM_RX_7;
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX:
+ case AFE_PORT_ID_SECONDARY_TDM_TX_1:
+ case AFE_PORT_ID_SECONDARY_TDM_TX_2:
+ case AFE_PORT_ID_SECONDARY_TDM_TX_3:
+ case AFE_PORT_ID_SECONDARY_TDM_TX_4:
+ case AFE_PORT_ID_SECONDARY_TDM_TX_5:
+ case AFE_PORT_ID_SECONDARY_TDM_TX_6:
+ case AFE_PORT_ID_SECONDARY_TDM_TX_7:
+ lower = SECONDARY_TDM_TX_0;
+ upper = SECONDARY_TDM_TX_7;
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX:
+ case AFE_PORT_ID_TERTIARY_TDM_RX_1:
+ case AFE_PORT_ID_TERTIARY_TDM_RX_2:
+ case AFE_PORT_ID_TERTIARY_TDM_RX_3:
+ case AFE_PORT_ID_TERTIARY_TDM_RX_4:
+ case AFE_PORT_ID_TERTIARY_TDM_RX_5:
+ case AFE_PORT_ID_TERTIARY_TDM_RX_6:
+ case AFE_PORT_ID_TERTIARY_TDM_RX_7:
+ lower = TERTIARY_TDM_RX_0;
+ upper = TERTIARY_TDM_RX_7;
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX:
+ case AFE_PORT_ID_TERTIARY_TDM_TX_1:
+ case AFE_PORT_ID_TERTIARY_TDM_TX_2:
+ case AFE_PORT_ID_TERTIARY_TDM_TX_3:
+ case AFE_PORT_ID_TERTIARY_TDM_TX_4:
+ case AFE_PORT_ID_TERTIARY_TDM_TX_5:
+ case AFE_PORT_ID_TERTIARY_TDM_TX_6:
+ case AFE_PORT_ID_TERTIARY_TDM_TX_7:
+ lower = TERTIARY_TDM_TX_0;
+ upper = TERTIARY_TDM_TX_7;
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX:
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
+ lower = QUATERNARY_TDM_RX_0;
+ upper = QUATERNARY_TDM_RX_7;
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX:
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
+ lower = QUATERNARY_TDM_TX_0;
+ upper = QUATERNARY_TDM_TX_7;
+ break;
+ default:
+ return slot_mask;
+ }
+
+ for (i = lower; i <= upper; i++) {
+ slot_offset = tdm_slot_offset[i];
+ for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
+ if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
+ /*
+ * set the mask of active slot according to
+ * the offset table for the group of devices
+ */
+ slot_mask |=
+ (1 << ((slot_offset[j] * 8) / slot_width));
+ else
+ break;
+ }
+ }
+
+ return slot_mask;
+}
+
+static int apq8096_tdm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ int channels, slot_width, slots;
+ unsigned int slot_mask;
+ unsigned int *slot_offset;
+ int offset_channels = 0;
+ int i;
+
+ pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
+
+ channels = params_channels(params);
+ switch (channels) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 6:
+ case 8:
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S16_LE:
+ /*
+ * up to 8 channel HW configuration should
+ * use 32 bit slot width for max support of
+ * stream bit width. (slot_width > bit_width)
+ */
+ slot_width = 32;
+ break;
+ default:
+ pr_err("%s: invalid param format 0x%x\n",
+ __func__, params_format(params));
+ return -EINVAL;
+ }
+ slots = 8;
+ slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
+ slot_width, slots);
+ if (!slot_mask) {
+ pr_err("%s: invalid slot_mask 0x%x\n",
+ __func__, slot_mask);
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_err("%s: invalid param channels %d\n",
+ __func__, channels);
+ return -EINVAL;
+ }
+
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_SECONDARY_TDM_RX:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_0];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_RX_1:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_1];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_RX_2:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_2];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_RX_3:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_3];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_RX_4:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_4];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_RX_5:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_5];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_RX_6:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_6];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_RX_7:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_7];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_0];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX_1:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_1];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX_2:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_2];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX_3:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_3];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX_4:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_4];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX_5:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_5];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX_6:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_6];
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX_7:
+ slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_7];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_0];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX_1:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_1];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX_2:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_2];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX_3:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_3];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX_4:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_4];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX_5:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_5];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX_6:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_6];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX_7:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_7];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_0];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX_1:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_1];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX_2:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_2];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX_3:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_3];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX_4:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_4];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX_5:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_5];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX_6:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_6];
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX_7:
+ slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_7];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_0];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_1];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_2];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_3];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_4];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_5];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_6];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_7];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_0];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_1];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_2];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_3];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_4];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_5];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_6];
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
+ slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_7];
+ break;
+ default:
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
+ if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
+ offset_channels++;
+ else
+ break;
+ }
+
+ if (offset_channels == 0) {
+ pr_err("%s: slot offset not supported, offset_channels %d\n",
+ __func__, offset_channels);
+ return -EINVAL;
+ }
+
+ if (channels > offset_channels) {
+ pr_err("%s: channels %d exceed offset_channels %d\n",
+ __func__, channels, offset_channels);
+ return -EINVAL;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ 0, NULL, channels, slot_offset);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ channels, slot_offset, 0, NULL);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+static struct snd_soc_ops apq8096_tdm_be_ops = {
+ .hw_params = apq8096_tdm_snd_hw_params,
+};
+
+static const struct soc_enum msm_snd_enum[] = {
+ SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text),
+ SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text),
+ SOC_ENUM_SINGLE_EXT(2, hdmi_rx_bit_format_text),
+ SOC_ENUM_SINGLE_EXT(8, proxy_rx_ch_text),
+ SOC_ENUM_SINGLE_EXT(3, hdmi_rx_sample_rate_text),
+ SOC_ENUM_SINGLE_EXT(8, tdm_ch_text),
+ SOC_ENUM_SINGLE_EXT(2, tdm_bit_format_text),
+ SOC_ENUM_SINGLE_EXT(2, mi2s_bit_format_text),
+ SOC_ENUM_SINGLE_EXT(9, ec_ref_ch_text),
+ SOC_ENUM_SINGLE_EXT(3, ec_ref_bit_format_text),
+ SOC_ENUM_SINGLE_EXT(9, ec_ref_rate_text),
+};
+
+static const struct snd_kcontrol_new msm_snd_controls[] = {
+ SOC_ENUM_EXT("AUX PCM SampleRate", msm_snd_enum[0],
+ msm_auxpcm_rate_get, msm_auxpcm_rate_put),
+ SOC_ENUM_EXT("HDMI_RX Channels", msm_snd_enum[1],
+ msm_hdmi_rx_ch_get, msm_hdmi_rx_ch_put),
+ SOC_ENUM_EXT("HDMI_RX Bit Format", msm_snd_enum[2],
+ hdmi_rx_bit_format_get, hdmi_rx_bit_format_put),
+ SOC_ENUM_EXT("PROXY_RX Channels", msm_snd_enum[3],
+ msm_proxy_rx_ch_get, msm_proxy_rx_ch_put),
+ SOC_ENUM_EXT("HDMI_RX SampleRate", msm_snd_enum[4],
+ hdmi_rx_sample_rate_get, hdmi_rx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", msm_snd_enum[5],
+ msm_sec_tdm_tx_0_ch_get, msm_sec_tdm_tx_0_ch_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_1 Channels", msm_snd_enum[5],
+ msm_sec_tdm_tx_1_ch_get, msm_sec_tdm_tx_1_ch_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_2 Channels", msm_snd_enum[5],
+ msm_sec_tdm_tx_2_ch_get, msm_sec_tdm_tx_2_ch_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_3 Channels", msm_snd_enum[5],
+ msm_sec_tdm_tx_3_ch_get, msm_sec_tdm_tx_3_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", msm_snd_enum[5],
+ msm_tert_tdm_rx_0_ch_get, msm_tert_tdm_rx_0_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_1 Channels", msm_snd_enum[5],
+ msm_tert_tdm_rx_1_ch_get, msm_tert_tdm_rx_1_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_2 Channels", msm_snd_enum[5],
+ msm_tert_tdm_rx_2_ch_get, msm_tert_tdm_rx_2_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_3 Channels", msm_snd_enum[5],
+ msm_tert_tdm_rx_3_ch_get, msm_tert_tdm_rx_3_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", msm_snd_enum[5],
+ msm_tert_tdm_tx_0_ch_get, msm_tert_tdm_tx_0_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_1 Channels", msm_snd_enum[5],
+ msm_tert_tdm_tx_1_ch_get, msm_tert_tdm_tx_1_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_2 Channels", msm_snd_enum[5],
+ msm_tert_tdm_tx_2_ch_get, msm_tert_tdm_tx_2_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_3 Channels", msm_snd_enum[5],
+ msm_tert_tdm_tx_3_ch_get, msm_tert_tdm_tx_3_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", msm_snd_enum[5],
+ msm_quat_tdm_rx_0_ch_get, msm_quat_tdm_rx_0_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_1 Channels", msm_snd_enum[5],
+ msm_quat_tdm_rx_1_ch_get, msm_quat_tdm_rx_1_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_2 Channels", msm_snd_enum[5],
+ msm_quat_tdm_rx_2_ch_get, msm_quat_tdm_rx_2_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_3 Channels", msm_snd_enum[5],
+ msm_quat_tdm_rx_3_ch_get, msm_quat_tdm_rx_3_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", msm_snd_enum[5],
+ msm_quat_tdm_tx_0_ch_get, msm_quat_tdm_tx_0_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_1 Channels", msm_snd_enum[5],
+ msm_quat_tdm_tx_1_ch_get, msm_quat_tdm_tx_1_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_2 Channels", msm_snd_enum[5],
+ msm_quat_tdm_tx_2_ch_get, msm_quat_tdm_tx_2_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_3 Channels", msm_snd_enum[5],
+ msm_quat_tdm_tx_3_ch_get, msm_quat_tdm_tx_3_ch_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_0 Bit Format", msm_snd_enum[6],
+ msm_sec_tdm_tx_0_bit_format_get,
+ msm_sec_tdm_tx_0_bit_format_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_1 Bit Format", msm_snd_enum[6],
+ msm_sec_tdm_tx_1_bit_format_get,
+ msm_sec_tdm_tx_1_bit_format_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_2 Bit Format", msm_snd_enum[6],
+ msm_sec_tdm_tx_2_bit_format_get,
+ msm_sec_tdm_tx_2_bit_format_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_3 Bit Format", msm_snd_enum[6],
+ msm_sec_tdm_tx_3_bit_format_get,
+ msm_sec_tdm_tx_3_bit_format_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_0 Bit Format", msm_snd_enum[6],
+ msm_tert_tdm_rx_0_bit_format_get,
+ msm_tert_tdm_rx_0_bit_format_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_1 Bit Format", msm_snd_enum[6],
+ msm_tert_tdm_rx_1_bit_format_get,
+ msm_tert_tdm_rx_1_bit_format_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_2 Bit Format", msm_snd_enum[6],
+ msm_tert_tdm_rx_2_bit_format_get,
+ msm_tert_tdm_rx_2_bit_format_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_3 Bit Format", msm_snd_enum[6],
+ msm_tert_tdm_rx_3_bit_format_get,
+ msm_tert_tdm_rx_3_bit_format_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_0 Bit Format", msm_snd_enum[6],
+ msm_tert_tdm_tx_0_bit_format_get,
+ msm_tert_tdm_tx_0_bit_format_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_1 Bit Format", msm_snd_enum[6],
+ msm_tert_tdm_tx_1_bit_format_get,
+ msm_tert_tdm_tx_1_bit_format_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_2 Bit Format", msm_snd_enum[6],
+ msm_tert_tdm_tx_2_bit_format_get,
+ msm_tert_tdm_tx_2_bit_format_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_3 Bit Format", msm_snd_enum[6],
+ msm_tert_tdm_tx_3_bit_format_get,
+ msm_tert_tdm_tx_3_bit_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_0 Bit Format", msm_snd_enum[6],
+ msm_quat_tdm_rx_0_bit_format_get,
+ msm_quat_tdm_rx_0_bit_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_1 Bit Format", msm_snd_enum[6],
+ msm_quat_tdm_rx_1_bit_format_get,
+ msm_quat_tdm_rx_1_bit_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_2 Bit Format", msm_snd_enum[6],
+ msm_quat_tdm_rx_2_bit_format_get,
+ msm_quat_tdm_rx_2_bit_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_3 Bit Format", msm_snd_enum[6],
+ msm_quat_tdm_rx_3_bit_format_get,
+ msm_quat_tdm_rx_3_bit_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_0 Bit Format", msm_snd_enum[6],
+ msm_quat_tdm_tx_0_bit_format_get,
+ msm_quat_tdm_tx_0_bit_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_1 Bit Format", msm_snd_enum[6],
+ msm_quat_tdm_tx_1_bit_format_get,
+ msm_quat_tdm_tx_1_bit_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_2 Bit Format", msm_snd_enum[6],
+ msm_quat_tdm_tx_2_bit_format_get,
+ msm_quat_tdm_tx_2_bit_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_3 Bit Format", msm_snd_enum[6],
+ msm_quat_tdm_tx_3_bit_format_get,
+ msm_quat_tdm_tx_3_bit_format_put),
+ SOC_ENUM_EXT("QUAT_MI2S_RX Bit Format", msm_snd_enum[7],
+ msm_quat_mi2s_rx_bit_format_get,
+ msm_quat_mi2s_rx_bit_format_put),
+ SOC_ENUM_EXT("TERT_MI2S_TX Bit Format", msm_snd_enum[7],
+ msm_tert_mi2s_tx_bit_format_get,
+ msm_tert_mi2s_tx_bit_format_put),
+ SOC_ENUM_EXT("SEC_MI2S_TX Bit Format", msm_snd_enum[7],
+ msm_sec_mi2s_tx_bit_format_get,
+ msm_sec_mi2s_tx_bit_format_put),
+ SOC_ENUM_EXT("EC Reference Channels", msm_snd_enum[8],
+ msm_ec_ref_ch_get, msm_ec_ref_ch_put),
+ SOC_ENUM_EXT("EC Reference Bit Format", msm_snd_enum[9],
+ msm_ec_ref_bit_format_get, msm_ec_ref_bit_format_put),
+ SOC_ENUM_EXT("EC Reference SampleRate", msm_snd_enum[10],
+ msm_ec_ref_rate_get, msm_ec_ref_rate_put),
+};
+
+static int apq8096_get_ll_qos_val(struct snd_pcm_runtime *runtime)
+{
+ int usecs;
+
+ /* take 10% of period time as the deadline */
+ usecs = (100000 / runtime->rate) * runtime->period_size;
+ usecs += ((100000 % runtime->rate) * runtime->period_size) /
+ runtime->rate;
+
+ return usecs;
+}
+
+static int apq8096_mm5_prepare(struct snd_pcm_substream *substream)
+{
+ if (pm_qos_request_active(&substream->latency_pm_qos_req))
+ pm_qos_remove_request(&substream->latency_pm_qos_req);
+ pm_qos_add_request(&substream->latency_pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY,
+ apq8096_get_ll_qos_val(substream->runtime));
+ return 0;
+}
+
+static struct snd_soc_ops apq8096_mm5_ops = {
+ .prepare = apq8096_mm5_prepare,
+};
+
+/* Digital audio interface glue - connects codec <---> CPU */
+static struct snd_soc_dai_link apq8096_common_dai_links[] = {
+ /* FrontEnd DAI Links */
+ {
+ .name = "MSM8996 Media1",
+ .stream_name = "MultiMedia1",
+ .cpu_dai_name = "MultiMedia1",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
+ },
+ {
+ .name = "MSM8996 Media2",
+ .stream_name = "MultiMedia2",
+ .cpu_dai_name = "MultiMedia2",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
+ },
+ {
+ .name = "VoiceMMode1",
+ .stream_name = "VoiceMMode1",
+ .cpu_dai_name = "VoiceMMode1",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_VOICEMMODE1,
+ },
+ {
+ .name = "MSM VoIP",
+ .stream_name = "VoIP",
+ .cpu_dai_name = "VoIP",
+ .platform_name = "msm-voip-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_VOIP,
+ },
+ {
+ .name = "MSM8996 ULL",
+ .stream_name = "MultiMedia3",
+ .cpu_dai_name = "MultiMedia3",
+ .platform_name = "msm-pcm-dsp.2",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA3,
+ },
+ /* Hostless PCM purpose */
+ {
+ .name = "SLIMBUS_0 Hostless",
+ .stream_name = "SLIMBUS_0 Hostless",
+ .cpu_dai_name = "SLIMBUS0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Tertiary MI2S TX_Hostless",
+ .stream_name = "Tertiary MI2S_TX Hostless Capture",
+ .cpu_dai_name = "TERT_MI2S_TX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "MSM AFE-PCM RX",
+ .stream_name = "AFE-PROXY RX",
+ .cpu_dai_name = "msm-dai-q6-dev.241",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .platform_name = "msm-pcm-afe",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = "MSM AFE-PCM TX",
+ .stream_name = "AFE-PROXY TX",
+ .cpu_dai_name = "msm-dai-q6-dev.240",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .platform_name = "msm-pcm-afe",
+ .ignore_suspend = 1,
+ },
+ {
+ .name = "MSM8996 Compress1",
+ .stream_name = "Compress1",
+ .cpu_dai_name = "MultiMedia4",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
+ },
+ {
+ .name = "AUXPCM Hostless",
+ .stream_name = "AUXPCM Hostless",
+ .cpu_dai_name = "AUXPCM_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "SLIMBUS_1 Hostless",
+ .stream_name = "SLIMBUS_1 Hostless",
+ .cpu_dai_name = "SLIMBUS1_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "SLIMBUS_3 Hostless",
+ .stream_name = "SLIMBUS_3 Hostless",
+ .cpu_dai_name = "SLIMBUS3_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "SLIMBUS_4 Hostless",
+ .stream_name = "SLIMBUS_4 Hostless",
+ .cpu_dai_name = "SLIMBUS4_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "VoLTE",
+ .stream_name = "VoLTE",
+ .cpu_dai_name = "VoLTE",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_VOLTE,
+ },
+ {
+ .name = "MSM8996 LowLatency",
+ .stream_name = "MultiMedia5",
+ .cpu_dai_name = "MultiMedia5",
+ .platform_name = "msm-pcm-dsp.1",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
+ .ops = &apq8096_mm5_ops,
+ },
+ {
+ .name = "Listen 1 Audio Service",
+ .stream_name = "Listen 1 Audio Service",
+ .cpu_dai_name = "LSM1",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM1,
+ },
+ /* Multiple Tunnel instances */
+ {
+ .name = "MSM8996 Compress2",
+ .stream_name = "Compress2",
+ .cpu_dai_name = "MultiMedia7",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7,
+ },
+ {
+ .name = "MSM8996 Compress3",
+ .stream_name = "Compress3",
+ .cpu_dai_name = "MultiMedia10",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10,
+ },
+ {
+ .name = "MSM8996 Compr8",
+ .stream_name = "COMPR8",
+ .cpu_dai_name = "MultiMedia8",
+ .platform_name = "msm-compr-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
+ },
+ {
+ .name = "QCHAT",
+ .stream_name = "QCHAT",
+ .cpu_dai_name = "QCHAT",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_QCHAT,
+ },
+ /* HDMI Hostless */
+ {
+ .name = "HDMI_RX_HOSTLESS",
+ .stream_name = "HDMI_RX_HOSTLESS",
+ .cpu_dai_name = "HDMI_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "VoiceMMode2",
+ .stream_name = "VoiceMMode2",
+ .cpu_dai_name = "VoiceMMode2",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_VOICEMMODE2,
+ },
+ {
+ .name = "INT_HFP_BT Hostless",
+ .stream_name = "INT_HFP_BT Hostless",
+ .cpu_dai_name = "INT_HFP_BT_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "MSM8996 HFP TX",
+ .stream_name = "MultiMedia6",
+ .cpu_dai_name = "MultiMedia6",
+ .platform_name = "msm-pcm-loopback",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6,
+ },
+ /* LSM FE */
+ {
+ .name = "Listen 2 Audio Service",
+ .stream_name = "Listen 2 Audio Service",
+ .cpu_dai_name = "LSM2",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM2,
+ },
+ {
+ .name = "Listen 3 Audio Service",
+ .stream_name = "Listen 3 Audio Service",
+ .cpu_dai_name = "LSM3",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM3,
+ },
+ {
+ .name = "Listen 4 Audio Service",
+ .stream_name = "Listen 4 Audio Service",
+ .cpu_dai_name = "LSM4",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM4,
+ },
+ {
+ .name = "Listen 5 Audio Service",
+ .stream_name = "Listen 5 Audio Service",
+ .cpu_dai_name = "LSM5",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM5,
+ },
+ {
+ .name = "Listen 6 Audio Service",
+ .stream_name = "Listen 6 Audio Service",
+ .cpu_dai_name = "LSM6",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM6,
+ },
+ {
+ .name = "Listen 7 Audio Service",
+ .stream_name = "Listen 7 Audio Service",
+ .cpu_dai_name = "LSM7",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM7,
+ },
+ {
+ .name = "Listen 8 Audio Service",
+ .stream_name = "Listen 8 Audio Service",
+ .cpu_dai_name = "LSM8",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_LSM8,
+ },
+ {
+ .name = "MSM8996 LowLatency Loopback",
+ .stream_name = "MultiMedia9",
+ .cpu_dai_name = "MultiMedia9",
+ .platform_name = "msm-pcm-loopback.1",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA9,
+ },
+ {
+ .name = "VoWLAN",
+ .stream_name = "VoWLAN",
+ .cpu_dai_name = "VoWLAN",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_VOWLAN,
+ },
+ {
+ .name = "MSM8996 Compress4",
+ .stream_name = "Compress4",
+ .cpu_dai_name = "MultiMedia11",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA11,
+ },
+ {
+ .name = "MSM8996 Compress5",
+ .stream_name = "Compress5",
+ .cpu_dai_name = "MultiMedia12",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA12,
+ },
+ {
+ .name = "MSM8996 Compress6",
+ .stream_name = "Compress6",
+ .cpu_dai_name = "MultiMedia13",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA13,
+ },
+ {
+ .name = "MSM8996 Compress7",
+ .stream_name = "Compress7",
+ .cpu_dai_name = "MultiMedia14",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA14,
+ },
+ {
+ .name = "MSM8996 Compress8",
+ .stream_name = "Compress8",
+ .cpu_dai_name = "MultiMedia15",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA15,
+ },
+ {
+ .name = "MSM8996 Compress9",
+ .stream_name = "Compress9",
+ .cpu_dai_name = "MultiMedia16",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA16,
+ },
+ {
+ .name = "Circuit-Switch Voice",
+ .stream_name = "CS-Voice",
+ .cpu_dai_name = "CS-VOICE",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_CS_VOICE,
+ },
+ {
+ .name = "Voice2",
+ .stream_name = "Voice2",
+ .cpu_dai_name = "Voice2",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_VOICE2,
+ },
+};
+
+static struct snd_soc_dai_link apq8096_auto_fe_dai_links[] = {
+ {
+ .name = "Tertiary TDM RX 0 Hostless",
+ .stream_name = "Tertiary TDM RX 0 Hostless",
+ .cpu_dai_name = "TERT_TDM_RX_0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Tertiary TDM RX 1 Hostless",
+ .stream_name = "Tertiary TDM RX 1 Hostless",
+ .cpu_dai_name = "TERT_TDM_RX_1_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Tertiary TDM RX 2 Hostless",
+ .stream_name = "Tertiary TDM RX 2 Hostless",
+ .cpu_dai_name = "TERT_TDM_RX_2_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Tertiary TDM RX 3 Hostless",
+ .stream_name = "Tertiary TDM RX 3 Hostless",
+ .cpu_dai_name = "TERT_TDM_RX_3_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Tertiary TDM TX 0 Hostless",
+ .stream_name = "Tertiary TDM TX 0 Hostless",
+ .cpu_dai_name = "TERT_TDM_TX_0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Tertiary TDM TX 1 Hostless",
+ .stream_name = "Tertiary TDM TX 1 Hostless",
+ .cpu_dai_name = "TERT_TDM_TX_1_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Tertiary TDM TX 2 Hostless",
+ .stream_name = "Tertiary TDM TX 2 Hostless",
+ .cpu_dai_name = "TERT_TDM_TX_2_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Tertiary TDM TX 3 Hostless",
+ .stream_name = "Tertiary TDM TX 3 Hostless",
+ .cpu_dai_name = "TERT_TDM_TX_3_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Quaternary TDM RX 0 Hostless",
+ .stream_name = "Quaternary TDM RX 0 Hostless",
+ .cpu_dai_name = "QUAT_TDM_RX_0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Quaternary TDM RX 1 Hostless",
+ .stream_name = "Quaternary TDM RX 1 Hostless",
+ .cpu_dai_name = "QUAT_TDM_RX_1_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Quaternary TDM RX 2 Hostless",
+ .stream_name = "Quaternary TDM RX 2 Hostless",
+ .cpu_dai_name = "QUAT_TDM_RX_2_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Quaternary TDM RX 3 Hostless",
+ .stream_name = "Quaternary TDM RX 3 Hostless",
+ .cpu_dai_name = "QUAT_TDM_RX_3_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Quaternary TDM TX 0 Hostless",
+ .stream_name = "Quaternary TDM TX 0 Hostless",
+ .cpu_dai_name = "QUAT_TDM_TX_0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Quaternary TDM TX 1 Hostless",
+ .stream_name = "Quaternary TDM TX 1 Hostless",
+ .cpu_dai_name = "QUAT_TDM_TX_1_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Quaternary TDM TX 2 Hostless",
+ .stream_name = "Quaternary TDM TX 2 Hostless",
+ .cpu_dai_name = "QUAT_TDM_TX_2_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Quaternary TDM TX 3 Hostless",
+ .stream_name = "Quaternary TDM TX 3 Hostless",
+ .cpu_dai_name = "QUAT_TDM_TX_3_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Quaternary MI2S_RX Hostless Playback",
+ .stream_name = "Quaternary MI2S_RX Hostless Playback",
+ .cpu_dai_name = "QUAT_MI2S_RX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Secondary MI2S_TX Hostless Capture",
+ .stream_name = "Secondary MI2S_TX Hostless Capture",
+ .cpu_dai_name = "SEC_MI2S_TX_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+};
+
+static struct snd_soc_dai_link apq8096_common_be_dai_links[] = {
+ /* Backend AFE DAI Links */
+ {
+ .name = LPASS_BE_AFE_PCM_RX,
+ .stream_name = "AFE Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.224",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
+ .be_hw_params_fixup = msm_proxy_rx_be_hw_params_fixup,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_AFE_PCM_TX,
+ .stream_name = "AFE Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.225",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
+ .be_hw_params_fixup = msm_proxy_tx_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Primary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_AUXPCM_RX,
+ .stream_name = "AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_RX,
+ .be_hw_params_fixup = msm_auxpcm_be_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ },
+ {
+ .name = LPASS_BE_AUXPCM_TX,
+ .stream_name = "AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_TX,
+ .be_hw_params_fixup = msm_auxpcm_be_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Record Uplink BACK END DAI Link */
+ {
+ .name = LPASS_BE_INCALL_RECORD_TX,
+ .stream_name = "Voice Uplink Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.32772",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Record Downlink BACK END DAI Link */
+ {
+ .name = LPASS_BE_INCALL_RECORD_RX,
+ .stream_name = "Voice Downlink Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.32771",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Music BACK END DAI Link */
+ {
+ .name = LPASS_BE_VOICE_PLAYBACK_TX,
+ .stream_name = "Voice Farend Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.32773",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Music 2 BACK END DAI Link */
+ {
+ .name = LPASS_BE_VOICE2_PLAYBACK_TX,
+ .stream_name = "Voice2 Farend Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.32770",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ }
+};
+
+static struct snd_soc_dai_link apq8096_auto_be_dai_links[] = {
+ /* Backend DAI Links */
+ {
+ .name = LPASS_BE_SEC_MI2S_TX,
+ .stream_name = "Secondary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+ .be_hw_params_fixup = msm_mi2s_tx_be_hw_params_fixup,
+ .ops = &apq8096_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_TX,
+ .stream_name = "Tertiary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ .be_hw_params_fixup = msm_mi2s_tx_be_hw_params_fixup,
+ .ops = &apq8096_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_RX,
+ .stream_name = "Quaternary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
+ .be_hw_params_fixup = msm_mi2s_rx_be_hw_params_fixup,
+ .ops = &apq8096_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_TDM_TX_0,
+ .stream_name = "Secondary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36881",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_TDM_TX_1,
+ .stream_name = "Secondary TDM1 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36883",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_1,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_TDM_TX_2,
+ .stream_name = "Secondary TDM2 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36885",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_2,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_TDM_TX_3,
+ .stream_name = "Secondary TDM3 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36887",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_3,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_RX_0,
+ .stream_name = "Tertiary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36896",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_RX_1,
+ .stream_name = "Tertiary TDM1 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36898",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_1,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_RX_2,
+ .stream_name = "Tertiary TDM2 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36900",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_2,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_RX_3,
+ .stream_name = "Tertiary TDM3 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36902",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_3,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_TX_0,
+ .stream_name = "Tertiary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36897",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_TX_1,
+ .stream_name = "Tertiary TDM1 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36899",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_1,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_TX_2,
+ .stream_name = "Tertiary TDM2 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36901",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_2,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_TX_3,
+ .stream_name = "Tertiary TDM3 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36903",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_3,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_RX_0,
+ .stream_name = "Quaternary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36912",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_RX_1,
+ .stream_name = "Quaternary TDM1 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36914",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_1,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_RX_2,
+ .stream_name = "Quaternary TDM2 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36916",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_2,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_RX_3,
+ .stream_name = "Quaternary TDM3 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36918",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_3,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_TX_0,
+ .stream_name = "Quaternary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36913",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_TX_1,
+ .stream_name = "Quaternary TDM1 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36915",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_1,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_TX_2,
+ .stream_name = "Quaternary TDM2 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36917",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_2,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_TX_3,
+ .stream_name = "Quaternary TDM3 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36919",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_3,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link apq8096_hdmi_dai_link[] = {
+ /* HDMI BACK END DAI Link */
+ {
+ .name = LPASS_BE_HDMI,
+ .stream_name = "HDMI Playback",
+ .cpu_dai_name = "msm-dai-q6-hdmi.8",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_HDMI_RX,
+ .be_hw_params_fixup = msm_hdmi_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link apq8096_auto_dai_links[
+ ARRAY_SIZE(apq8096_common_dai_links) +
+ ARRAY_SIZE(apq8096_auto_fe_dai_links) +
+ ARRAY_SIZE(apq8096_common_be_dai_links) +
+ ARRAY_SIZE(apq8096_auto_be_dai_links) +
+ ARRAY_SIZE(apq8096_hdmi_dai_link)];
+
+struct snd_soc_card snd_soc_card_auto_apq8096 = {
+ .name = "apq8096-auto-snd-card",
+};
+
+struct snd_soc_card snd_soc_card_adp_agave_apq8096 = {
+ .name = "apq8096-adp-agave-snd-card",
+};
+
+struct snd_soc_card snd_soc_card_adp_mmxf_apq8096 = {
+ .name = "apq8096-adp-mmxf-snd-card",
+};
+
+static int apq8096_populate_dai_link_component_of_node(
+ struct snd_soc_card *card)
+{
+ int i, index, ret = 0;
+ struct device *cdev = card->dev;
+ struct snd_soc_dai_link *dai_link = card->dai_link;
+ struct device_node *np;
+
+ if (!cdev) {
+ pr_err("%s: Sound card device memory NULL\n", __func__);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < card->num_links; i++) {
+ if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node)
+ continue;
+
+ /* populate platform_of_node for snd card dai links */
+ if (dai_link[i].platform_name &&
+ !dai_link[i].platform_of_node) {
+ index = of_property_match_string(cdev->of_node,
+ "asoc-platform-names",
+ dai_link[i].platform_name);
+ if (index < 0) {
+ pr_err("%s: No match found for platform name: %s\n",
+ __func__, dai_link[i].platform_name);
+ ret = index;
+ goto err;
+ }
+ np = of_parse_phandle(cdev->of_node, "asoc-platform",
+ index);
+ if (!np) {
+ pr_err("%s: retrieving phandle for platform %s, index %d failed\n",
+ __func__, dai_link[i].platform_name,
+ index);
+ ret = -ENODEV;
+ goto err;
+ }
+ dai_link[i].platform_of_node = np;
+ dai_link[i].platform_name = NULL;
+ }
+
+ /* populate cpu_of_node for snd card dai links */
+ if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) {
+ index = of_property_match_string(cdev->of_node,
+ "asoc-cpu-names",
+ dai_link[i].cpu_dai_name);
+ if (index >= 0) {
+ np = of_parse_phandle(cdev->of_node, "asoc-cpu",
+ index);
+ if (!np) {
+ pr_err("%s: retrieving phandle for cpu dai %s failed\n",
+ __func__,
+ dai_link[i].cpu_dai_name);
+ ret = -ENODEV;
+ goto err;
+ }
+ dai_link[i].cpu_of_node = np;
+ dai_link[i].cpu_dai_name = NULL;
+ }
+ }
+
+ /* populate codec_of_node for snd card dai links */
+ if (dai_link[i].codec_name && !dai_link[i].codec_of_node) {
+ index = of_property_match_string(cdev->of_node,
+ "asoc-codec-names",
+ dai_link[i].codec_name);
+ if (index < 0)
+ continue;
+ np = of_parse_phandle(cdev->of_node, "asoc-codec",
+ index);
+ if (!np) {
+ pr_err("%s: retrieving phandle for codec %s failed\n",
+ __func__, dai_link[i].codec_name);
+ ret = -ENODEV;
+ goto err;
+ }
+ dai_link[i].codec_of_node = np;
+ dai_link[i].codec_name = NULL;
+ }
+ }
+
+err:
+ return ret;
+}
+
+static const struct of_device_id apq8096_asoc_machine_of_match[] = {
+ { .compatible = "qcom,apq8096-asoc-snd-auto",
+ .data = "auto_codec"},
+ { .compatible = "qcom,apq8096-asoc-snd-adp-agave",
+ .data = "adp_agave_codec"},
+ { .compatible = "qcom,apq8096-asoc-snd-adp-mmxf",
+ .data = "adp_mmxf_codec"},
+ {},
+};
+
+static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
+{
+ struct snd_soc_card *card = NULL;
+ struct snd_soc_dai_link *dailink;
+ int len_1, len_2, len_3, len_4;
+ const struct of_device_id *match;
+
+ match = of_match_node(apq8096_asoc_machine_of_match, dev->of_node);
+ if (!match) {
+ dev_err(dev, "%s: No DT match found for sound card\n",
+ __func__);
+ return NULL;
+ }
+
+ if (!strcmp(match->data, "auto_codec"))
+ card = &snd_soc_card_auto_apq8096;
+ else if (!strcmp(match->data, "adp_agave_codec"))
+ card = &snd_soc_card_adp_agave_apq8096;
+ else if (!strcmp(match->data, "adp_mmxf_codec"))
+ card = &snd_soc_card_adp_mmxf_apq8096;
+ else {
+ dev_err(dev, "%s: Codec not supported\n",
+ __func__);
+ return NULL;
+ }
+
+ /* same FE and BE used for all codec */
+ len_1 = ARRAY_SIZE(apq8096_common_dai_links);
+ len_2 = len_1 + ARRAY_SIZE(apq8096_auto_fe_dai_links);
+ len_3 = len_2 + ARRAY_SIZE(apq8096_common_be_dai_links);
+
+ memcpy(apq8096_auto_dai_links,
+ apq8096_common_dai_links,
+ sizeof(apq8096_common_dai_links));
+ memcpy(apq8096_auto_dai_links + len_1,
+ apq8096_auto_fe_dai_links,
+ sizeof(apq8096_auto_fe_dai_links));
+ memcpy(apq8096_auto_dai_links + len_2,
+ apq8096_common_be_dai_links,
+ sizeof(apq8096_common_be_dai_links));
+ memcpy(apq8096_auto_dai_links + len_3,
+ apq8096_auto_be_dai_links,
+ sizeof(apq8096_auto_be_dai_links));
+
+ dailink = apq8096_auto_dai_links;
+ len_4 = len_3 + ARRAY_SIZE(apq8096_auto_be_dai_links);
+
+ if (of_property_read_bool(dev->of_node, "qcom,hdmi-audio-rx")) {
+ dev_dbg(dev, "%s(): hdmi audio support present\n",
+ __func__);
+ memcpy(dailink + len_4, apq8096_hdmi_dai_link,
+ sizeof(apq8096_hdmi_dai_link));
+ len_4 += ARRAY_SIZE(apq8096_hdmi_dai_link);
+ } else {
+ dev_dbg(dev, "%s(): No hdmi audio support\n", __func__);
+ }
+
+ if (card) {
+ card->dai_link = dailink;
+ card->num_links = len_4;
+ }
+
+ return card;
+}
+
+/*
+ * TDM offset mapping is per platform/codec specific.
+ * TO BE UPDATED if new platform/codec is introduced.
+ */
+static int apq8096_init_tdm_dev(struct device *dev)
+{
+ const struct of_device_id *match;
+
+ match = of_match_node(apq8096_asoc_machine_of_match, dev->of_node);
+ if (!match) {
+ dev_err(dev, "%s: No DT match found for sound card\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (!strcmp(match->data, "adp_mmxf_codec")) {
+ dev_dbg(dev, "%s: ADP MMXF tdm slot offset\n", __func__);
+ memcpy(tdm_slot_offset,
+ tdm_slot_offset_adp_mmxf,
+ sizeof(tdm_slot_offset_adp_mmxf));
+ } else {
+ dev_dbg(dev, "%s: DEFAULT tdm slot offset\n", __func__);
+ }
+
+ return 0;
+}
+
+static int apq8096_asoc_machine_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card;
+ const struct of_device_id *match;
+ int ret;
+
+ if (!pdev->dev.of_node) {
+ dev_err(&pdev->dev, "No platform supplied from device tree\n");
+ return -EINVAL;
+ }
+
+ card = populate_snd_card_dailinks(&pdev->dev);
+ if (!card) {
+ dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ card->dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+
+ ret = snd_soc_of_parse_card_name(card, "qcom,model");
+ if (ret) {
+ dev_err(&pdev->dev, "Parse card name failed, err:%d\n",
+ ret);
+ goto err;
+ }
+
+ match = of_match_node(apq8096_asoc_machine_of_match,
+ pdev->dev.of_node);
+ if (!match) {
+ dev_err(&pdev->dev, "%s: No matched codec is found.\n",
+ __func__);
+ goto err;
+ }
+
+ ret = apq8096_populate_dai_link_component_of_node(card);
+ if (ret) {
+ ret = -EPROBE_DEFER;
+ goto err;
+ }
+
+ /* populate controls of snd card */
+ card->controls = msm_snd_controls;
+ card->num_controls = ARRAY_SIZE(msm_snd_controls);
+
+ ret = apq8096_init_tdm_dev(&pdev->dev);
+ if (ret) {
+ ret = -EPROBE_DEFER;
+ goto err;
+ }
+
+ ret = snd_soc_register_card(card);
+ if (ret == -EPROBE_DEFER) {
+ goto err;
+ } else if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+ ret);
+ goto err;
+ }
+ dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
+
+ return 0;
+
+err:
+ return ret;
+}
+
+static int apq8096_asoc_machine_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+
+ return 0;
+}
+
+static struct platform_driver apq8096_asoc_machine_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = apq8096_asoc_machine_of_match,
+ },
+ .probe = apq8096_asoc_machine_probe,
+ .remove = apq8096_asoc_machine_remove,
+};
+
+static int dummy_machine_probe(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static int dummy_machine_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_device dummy_machine_device = {
+ .name = "apq8096-auto-asoc-dummy",
+};
+
+static struct platform_driver apq8096_asoc_machine_dummy_driver = {
+ .driver = {
+ .name = "apq8096-auto-asoc-dummy",
+ .owner = THIS_MODULE,
+ },
+ .probe = dummy_machine_probe,
+ .remove = dummy_machine_remove,
+};
+
+static int apq8096_adsp_state_callback(struct notifier_block *nb,
+ unsigned long value, void *priv)
+{
+ if (!dummy_device_registered && SUBSYS_AFTER_POWERUP == value) {
+ platform_driver_register(&apq8096_asoc_machine_dummy_driver);
+ platform_device_register(&dummy_machine_device);
+ dummy_device_registered = true;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block adsp_state_notifier_block = {
+ .notifier_call = apq8096_adsp_state_callback,
+ .priority = -INT_MAX,
+};
+
+static int __init apq8096_soc_platform_init(void)
+{
+ adsp_state_notifier = subsys_notif_register_notifier("adsp",
+ &adsp_state_notifier_block);
+ return 0;
+}
+
+module_init(apq8096_soc_platform_init);
+module_platform_driver(apq8096_asoc_machine_driver);
+
+MODULE_DESCRIPTION("ALSA SoC msm");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, apq8096_asoc_machine_of_match);