diff options
Diffstat (limited to 'sound/soc')
29 files changed, 4193 insertions, 801 deletions
diff --git a/sound/soc/codecs/msm_sdw/msm-sdw-tables.c b/sound/soc/codecs/msm_sdw/msm-sdw-tables.c index 767b9052a7da..4cbdb728ef41 100644 --- a/sound/soc/codecs/msm_sdw/msm-sdw-tables.c +++ b/sound/soc/codecs/msm_sdw/msm-sdw-tables.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-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 @@ -105,6 +105,7 @@ const u8 msm_sdw_page_map[MSM_SDW_MAX_REGISTER] = { [MSM_SDW_TOP_TOP_CFG1] = 0xd, [MSM_SDW_TOP_RX_I2S_CTL] = 0xd, [MSM_SDW_TOP_TX_I2S_CTL] = 0xd, + [MSM_SDW_TOP_I2S_CLK] = 0xd, [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 0xd, [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 0xd, [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 0xd, diff --git a/sound/soc/codecs/msm_sdw/msm_sdw.h b/sound/soc/codecs/msm_sdw/msm_sdw.h index d464c5064635..8e7612c85455 100644 --- a/sound/soc/codecs/msm_sdw/msm_sdw.h +++ b/sound/soc/codecs/msm_sdw/msm_sdw.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-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 @@ -100,6 +100,7 @@ struct msm_sdw_priv { int (*multi_reg_write)(struct msm_sdw_priv *msm_sdw, const void *data, size_t count); struct snd_soc_codec *codec; + struct device_node *sdw_gpio_p; /* used by pinctrl API */ /* SoundWire data structure */ struct msm_sdw_ctrl_data *sdw_ctrl_data; int nr; @@ -120,6 +121,7 @@ struct msm_sdw_priv { struct mutex sdw_write_lock; struct mutex sdw_clk_lock; int sdw_clk_users; + int sdw_mclk_users; int sdw_irq; int int_mclk1_rsc_ref; diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c index c8f7b05aef87..850238764d87 100644 --- a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c +++ b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-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 @@ -14,6 +14,7 @@ #include <linux/io.h> #include <linux/init.h> #include <linux/platform_device.h> +#include <linux/mfd/msm-cdc-pinctrl.h> #include <linux/printk.h> #include <linux/debugfs.h> #include <linux/bitops.h> @@ -50,13 +51,15 @@ static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); static struct snd_soc_dai_driver msm_sdw_dai[]; static bool initial_boot = true; +static bool is_ssr_en; +static bool skip_irq = true; static int msm_sdw_config_ear_spkr_gain(struct snd_soc_codec *codec, int event, int gain_reg); static int msm_sdw_config_compander(struct snd_soc_codec *, int, int); -static int msm_sdw_mclk_enable(struct snd_soc_codec *codec, +static int msm_sdw_mclk_enable(struct msm_sdw_priv *msm_sdw, int mclk_enable, bool dapm); -static int msm_int_enable_sdw_cdc_clk(struct snd_soc_codec *codec, +static int msm_int_enable_sdw_cdc_clk(struct msm_sdw_priv *msm_sdw, int enable, bool dapm); enum { @@ -199,39 +202,10 @@ static int msm_enable_sdw_npl_clk(struct msm_sdw_priv *msm_sdw, int enable) return ret; } -/** - * msm_sdw_gpio_cb - Register callback by machine driver for sdw gpio. - * - * @sdw_cdc_gpio_fn: Function pointer to trigger for enable/disable sdw gpios. - * @codec: sdw codec instance. - * - */ -void msm_sdw_gpio_cb( - int (*sdw_cdc_gpio_fn)(bool enable, struct snd_soc_codec *codec), - struct snd_soc_codec *codec) -{ - struct msm_sdw_priv *msm_sdw; - - if (!codec) { - pr_err("%s:NULL codec pointer!\n", __func__); - return; - } - msm_sdw = snd_soc_codec_get_drvdata(codec); - msm_sdw->sdw_cdc_gpio_fn = sdw_cdc_gpio_fn; -} -EXPORT_SYMBOL(msm_sdw_gpio_cb); - -static int msm_int_enable_sdw_cdc_clk(struct snd_soc_codec *codec, +static int msm_int_enable_sdw_cdc_clk(struct msm_sdw_priv *msm_sdw, int enable, bool dapm) { int ret = 0; - struct msm_sdw_priv *msm_sdw; - - if (!codec) { - pr_err("%s:NULL codec pointer\n", __func__); - return -EINVAL; - } - msm_sdw = snd_soc_codec_get_drvdata(codec); mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); dev_dbg(msm_sdw->dev, "%s: enable %d mclk1 ref counter %d\n", @@ -297,7 +271,6 @@ static void msm_disable_int_mclk1(struct work_struct *work) dev_dbg(msm_sdw->dev, "%s: mclk1_enabled %d mclk1_rsc_ref %d\n", __func__, msm_sdw->int_mclk1_enabled, msm_sdw->int_mclk1_rsc_ref); - if (msm_sdw->int_mclk1_enabled == true && msm_sdw->int_mclk1_rsc_ref == 0) { dev_dbg(msm_sdw->dev, "Disable the mclk1\n"); @@ -321,29 +294,23 @@ static int msm_int_mclk1_event(struct snd_soc_dapm_widget *w, struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); int ret = 0; - mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); dev_dbg(msm_sdw->dev, "%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: /* enable the codec mclk config */ - msm_int_enable_sdw_cdc_clk(codec, 1, true); - msm_sdw_mclk_enable(codec, 1, true); - if (msm_sdw->sdw_cdc_gpio_fn) - msm_sdw->sdw_cdc_gpio_fn(true, codec); + msm_int_enable_sdw_cdc_clk(msm_sdw, 1, true); + msm_sdw_mclk_enable(msm_sdw, 1, true); break; case SND_SOC_DAPM_POST_PMD: /* disable the codec mclk config */ - if (msm_sdw->sdw_cdc_gpio_fn) - msm_sdw->sdw_cdc_gpio_fn(false, codec); - msm_sdw_mclk_enable(codec, 0, true); - msm_int_enable_sdw_cdc_clk(codec, 0, true); + msm_sdw_mclk_enable(msm_sdw, 0, true); + msm_int_enable_sdw_cdc_clk(msm_sdw, 0, true); break; default: dev_err(msm_sdw->dev, "%s: invalid DAPM event %d\n", __func__, event); ret = -EINVAL; } - mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); return ret; } @@ -353,7 +320,8 @@ static int msm_sdw_ahb_write_device(struct msm_sdw_priv *msm_sdw, u32 temp = (u32)(*value) & 0x000000FF; if (!msm_sdw->dev_up) { - dev_dbg(msm_sdw->dev, "%s: q6 not ready\n", __func__); + dev_err_ratelimited(msm_sdw->dev, "%s: q6 not ready\n", + __func__); return 0; } @@ -367,7 +335,8 @@ static int msm_sdw_ahb_read_device(struct msm_sdw_priv *msm_sdw, u32 temp; if (!msm_sdw->dev_up) { - dev_dbg(msm_sdw->dev, "%s: q6 not ready\n", __func__); + dev_err_ratelimited(msm_sdw->dev, "%s: q6 not ready\n", + __func__); return 0; } @@ -454,6 +423,8 @@ static int __msm_sdw_reg_write(struct msm_sdw_priv *msm_sdw, unsigned short reg, &((u8 *)src)[i]); unlock_exit: mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); + dev_dbg(msm_sdw->dev, "Write 0x%x val 0x%02x\n", + reg, (u32)(*(u32 *)src)); return ret; } @@ -592,6 +563,9 @@ static int msm_sdwm_handle_irq(void *handle, } msm_sdw = (struct msm_sdw_priv *) handle; + if (skip_irq) + return ret; + if (action) { ret = request_threaded_irq(msm_sdw->sdw_irq, NULL, swrm_irq_handler, @@ -634,6 +608,55 @@ static void msm_sdw_codec_hd2_control(struct snd_soc_codec *codec, } } +static int msm_sdw_enable_swr(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct msm_sdw_priv *msm_sdw; + int i, ch_cnt; + + msm_sdw = snd_soc_codec_get_drvdata(codec); + + if (!msm_sdw->nr) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!(strnstr(w->name, "RX4", sizeof("RX4 MIX"))) && + !msm_sdw->rx_4_count) + msm_sdw->rx_4_count++; + if (!(strnstr(w->name, "RX5", sizeof("RX5 MIX"))) && + !msm_sdw->rx_5_count) + msm_sdw->rx_5_count++; + ch_cnt = msm_sdw->rx_4_count + msm_sdw->rx_5_count; + + for (i = 0; i < msm_sdw->nr; i++) { + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_DEVICE_UP, NULL); + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (!(strnstr(w->name, "RX4", sizeof("RX4 MIX"))) && + msm_sdw->rx_4_count) + msm_sdw->rx_4_count--; + if (!(strnstr(w->name, "RX5", sizeof("RX5 MIX"))) && + msm_sdw->rx_5_count) + msm_sdw->rx_5_count--; + ch_cnt = msm_sdw->rx_4_count + msm_sdw->rx_5_count; + + for (i = 0; i < msm_sdw->nr; i++) + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + break; + } + dev_dbg(msm_sdw->dev, "%s: current swr ch cnt: %d\n", + __func__, msm_sdw->rx_4_count + msm_sdw->rx_5_count); + + return 0; +} + static int msm_sdw_codec_enable_interpolator(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -643,7 +666,6 @@ static int msm_sdw_codec_enable_interpolator(struct snd_soc_dapm_widget *w, u16 gain_reg; u16 reg; int val; - int i, ch_cnt; int offset_val = 0; dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); @@ -665,21 +687,6 @@ static int msm_sdw_codec_enable_interpolator(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, reg, 0x10, 0x10); msm_sdw_codec_hd2_control(codec, reg, event); snd_soc_update_bits(codec, reg, 1 << 0x5, 1 << 0x5); - /* Reset if needed */ - if (!(strcmp(w->name, "RX INT4 INTERP")) && - !msm_sdw->rx_4_count) - msm_sdw->rx_4_count++; - if (!(strcmp(w->name, "RX INT5 INTERP")) && - !msm_sdw->rx_5_count) - msm_sdw->rx_5_count++; - ch_cnt = msm_sdw->rx_4_count + msm_sdw->rx_5_count; - - for (i = 0; i < msm_sdw->nr; i++) { - swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, - SWR_DEVICE_UP, NULL); - swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, - SWR_SET_NUM_RX_CH, &ch_cnt); - } break; case SND_SOC_DAPM_POST_PMU: msm_sdw_config_compander(codec, w->shift, event); @@ -705,6 +712,7 @@ static int msm_sdw_codec_enable_interpolator(struct snd_soc_dapm_widget *w, val += offset_val; snd_soc_write(codec, gain_reg, val); msm_sdw_config_ear_spkr_gain(codec, event, gain_reg); + snd_soc_update_bits(codec, reg, 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, reg, 1 << 0x5, 0 << 0x5); @@ -733,17 +741,6 @@ static int msm_sdw_codec_enable_interpolator(struct snd_soc_dapm_widget *w, snd_soc_write(codec, gain_reg, val); } msm_sdw_config_ear_spkr_gain(codec, event, gain_reg); - if (!(strcmp(w->name, "RX INT4 INTERP")) && - msm_sdw->rx_4_count) - msm_sdw->rx_4_count--; - if (!(strcmp(w->name, "RX INT5 INTERP")) && - msm_sdw->rx_5_count) - msm_sdw->rx_5_count--; - ch_cnt = msm_sdw->rx_4_count + msm_sdw->rx_5_count; - - for (i = 0; i < msm_sdw->nr; i++) - swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, - SWR_SET_NUM_RX_CH, &ch_cnt); break; }; @@ -989,39 +986,35 @@ static int msm_sdw_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, return 0; } -static int msm_sdw_mclk_enable(struct snd_soc_codec *codec, +static int msm_sdw_mclk_enable(struct msm_sdw_priv *msm_sdw, int mclk_enable, bool dapm) { - struct msm_sdw_priv *msm_sdw; - - if (!codec) { - pr_err("%s:NULL codec pointer\n", __func__); - return -EINVAL; - } - msm_sdw = snd_soc_codec_get_drvdata(codec); - - mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); - dev_dbg(codec->dev, "%s: mclk_enable = %u, dapm = %d\n", - __func__, mclk_enable, dapm); + dev_dbg(msm_sdw->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", + __func__, mclk_enable, dapm, msm_sdw->sdw_mclk_users); if (mclk_enable) { - snd_soc_update_bits(codec, - MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x01, 0x01); - snd_soc_update_bits(codec, + msm_sdw->sdw_mclk_users++; + if (msm_sdw->sdw_mclk_users == 1) { + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + regmap_update_bits(msm_sdw->regmap, MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x01); - /* 9.6MHz MCLK, set value 0x00 if other frequency */ - snd_soc_update_bits(codec, + /* 9.6MHz MCLK, set value 0x00 if other frequency */ + regmap_update_bits(msm_sdw->regmap, MSM_SDW_TOP_FREQ_MCLK, 0x01, 0x01); + } } else { - snd_soc_update_bits(codec, - MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x01, 0x00); - snd_soc_update_bits(codec, - MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, - 0x01, 0x00); + msm_sdw->sdw_mclk_users--; + if (msm_sdw->sdw_mclk_users == 0) { + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + } } - mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); return 0; } EXPORT_SYMBOL(msm_sdw_mclk_enable); @@ -1193,10 +1186,13 @@ static int msm_sdw_swrm_clock(void *handle, bool enable) if (enable) { msm_sdw->sdw_clk_users++; if (msm_sdw->sdw_clk_users == 1) { - msm_enable_sdw_npl_clk(msm_sdw, true); + msm_int_enable_sdw_cdc_clk(msm_sdw, 1, true); + msm_sdw_mclk_enable(msm_sdw, 1, true); regmap_update_bits(msm_sdw->regmap, - MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, - 0x01, 0x01); + MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x01); + msm_enable_sdw_npl_clk(msm_sdw, true); + msm_cdc_pinctrl_select_active_state( + msm_sdw->sdw_gpio_p); } } else { msm_sdw->sdw_clk_users--; @@ -1204,7 +1200,10 @@ static int msm_sdw_swrm_clock(void *handle, bool enable) regmap_update_bits(msm_sdw->regmap, MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x00); + msm_sdw_mclk_enable(msm_sdw, 0, true); + msm_int_enable_sdw_cdc_clk(msm_sdw, 0, true); msm_enable_sdw_npl_clk(msm_sdw, false); + msm_cdc_pinctrl_select_sleep_state(msm_sdw->sdw_gpio_p); } } dev_dbg(msm_sdw->dev, "%s: swrm clock users %d\n", @@ -1319,7 +1318,7 @@ static ssize_t msm_sdw_codec_version_read(struct snd_info_entry *entry, switch (msm_sdw->version) { case MSM_SDW_VERSION_1_0: - len = snprintf(buffer, sizeof(buffer), "MSM_SDW_CDC_1_0\n"); + len = snprintf(buffer, sizeof(buffer), "SDW-CDC_1_0\n"); break; default: len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); @@ -1355,10 +1354,10 @@ int msm_sdw_codec_info_create_codec_entry(struct snd_info_entry *codec_root, msm_sdw = snd_soc_codec_get_drvdata(codec); card = codec->component.card; msm_sdw->entry = snd_register_module_info(codec_root->module, - "msm_sdw", + "152c1000.msm-sdw-codec", codec_root); if (!msm_sdw->entry) { - dev_dbg(codec->dev, "%s: failed to create msm_sdw entry\n", + dev_err(codec->dev, "%s: failed to create msm_sdw entry\n", __func__); return -ENOMEM; } @@ -1367,7 +1366,7 @@ int msm_sdw_codec_info_create_codec_entry(struct snd_info_entry *codec_root, "version", msm_sdw->entry); if (!version_entry) { - dev_dbg(codec->dev, "%s: failed to create msm_sdw version entry\n", + dev_err(codec->dev, "%s: failed to create msm_sdw version entry\n", __func__); return -ENOMEM; } @@ -1485,14 +1484,18 @@ static const struct snd_soc_dapm_widget msm_sdw_dapm_widgets[] = { SND_SOC_DAPM_MIXER("AIF1_VI_SDW Mixer", SND_SOC_NOPM, AIF1_SDW_VIFEED, 0, aif1_vi_mixer, ARRAY_SIZE(aif1_vi_mixer)), - SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0, - &rx4_mix1_inp1_mux), - SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0, - &rx4_mix1_inp2_mux), - SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0, - &rx5_mix1_inp1_mux), - SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0, - &rx5_mix1_inp2_mux), + SND_SOC_DAPM_MUX_E("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx4_mix1_inp1_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx4_mix1_inp2_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx5_mix1_inp1_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx5_mix1_inp2_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIXER("RX4 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("RX5 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), @@ -1588,6 +1591,24 @@ static const struct msm_sdw_reg_mask_val msm_sdw_reg_init[] = { {MSM_SDW_BOOST1_BOOST_CFG1, 0x3F, 0x12}, {MSM_SDW_BOOST1_BOOST_CFG2, 0x1C, 0x08}, {MSM_SDW_COMPANDER8_CTL7, 0x1E, 0x18}, + {MSM_SDW_BOOST0_BOOST_CTL, 0x70, 0x50}, + {MSM_SDW_BOOST1_BOOST_CTL, 0x70, 0x50}, + {MSM_SDW_RX7_RX_PATH_CFG1, 0x08, 0x08}, + {MSM_SDW_RX8_RX_PATH_CFG1, 0x08, 0x08}, + {MSM_SDW_TOP_TOP_CFG1, 0x02, 0x02}, + {MSM_SDW_TOP_TOP_CFG1, 0x01, 0x01}, + {MSM_SDW_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_COMPANDER7_CTL3, 0x80, 0x80}, + {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x80}, + {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x01}, + {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x01}, + {MSM_SDW_RX7_RX_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_RX8_RX_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_RX7_RX_PATH_MIX_CFG, 0x01, 0x01}, + {MSM_SDW_RX8_RX_PATH_MIX_CFG, 0x01, 0x01}, }; static void msm_sdw_init_reg(struct snd_soc_codec *codec) @@ -1654,14 +1675,17 @@ static int msm_sdw_codec_probe(struct snd_soc_codec *codec) msm_sdw->spkr_gain_offset = RX_GAIN_OFFSET_0_DB; msm_sdw_init_reg(codec); msm_sdw->version = MSM_SDW_VERSION_1_0; - msm_sdw->dev_up = true; - msm_sdw->service_nb.notifier_call = msm_sdw_notifier_service_cb; - ret = audio_notifier_register("msm_sdw", AUDIO_NOTIFIER_ADSP_DOMAIN, - &msm_sdw->service_nb); - if (ret < 0) - dev_err(msm_sdw->dev, - "%s: Audio notifier register failed ret = %d\n", - __func__, ret); + + if (is_ssr_en) { + msm_sdw->service_nb.notifier_call = msm_sdw_notifier_service_cb; + ret = audio_notifier_register("msm_sdw", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &msm_sdw->service_nb); + if (ret < 0) + dev_err(msm_sdw->dev, + "%s: Audio notifier register failed ret = %d\n", + __func__, ret); + } return 0; } @@ -1801,15 +1825,11 @@ static int msm_sdw_probe(struct platform_device *pdev) if (!msm_sdw) return -ENOMEM; dev_set_drvdata(&pdev->dev, msm_sdw); + msm_sdw->dev_up = true; msm_sdw->dev = &pdev->dev; INIT_WORK(&msm_sdw->msm_sdw_add_child_devices_work, msm_sdw_add_child_devices); - mutex_init(&msm_sdw->sdw_read_lock); - mutex_init(&msm_sdw->sdw_write_lock); - mutex_init(&msm_sdw->sdw_clk_lock); - - mutex_init(&msm_sdw->codec_mutex); msm_sdw->sdw_plat_data.handle = (void *) msm_sdw; msm_sdw->sdw_plat_data.read = msm_sdw_swrm_read; msm_sdw->sdw_plat_data.write = msm_sdw_swrm_write; @@ -1823,6 +1843,9 @@ static int msm_sdw_probe(struct platform_device *pdev) __func__, "reg"); goto err_sdw_cdc; } + + msm_sdw->sdw_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-sdw-gpios", 0); msm_sdw->sdw_base = ioremap(msm_sdw->sdw_base_addr, MSM_SDW_MAX_REGISTER); msm_sdw->read_dev = __msm_sdw_reg_read; @@ -1873,6 +1896,11 @@ static int msm_sdw_probe(struct platform_device *pdev) msm_disable_int_mclk1); mutex_init(&msm_sdw->cdc_int_mclk1_mutex); mutex_init(&msm_sdw->sdw_npl_clk_mutex); + mutex_init(&msm_sdw->io_lock); + mutex_init(&msm_sdw->sdw_read_lock); + mutex_init(&msm_sdw->sdw_write_lock); + mutex_init(&msm_sdw->sdw_clk_lock); + mutex_init(&msm_sdw->codec_mutex); schedule_work(&msm_sdw->msm_sdw_add_child_devices_work); dev_dbg(&pdev->dev, "%s: msm_sdw driver probe done\n", __func__); diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c index 5c210dc2176e..df0bdf666ba1 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -50,6 +50,9 @@ static unsigned long rx_digital_gain_reg[] = { static unsigned long tx_digital_gain_reg[] = { MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN, MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, }; static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); @@ -729,6 +732,7 @@ static int msm_dig_cdc_hw_params(struct snd_pcm_substream *substream, MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x20); break; case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: snd_soc_update_bits(dai->codec, MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x00); break; @@ -799,13 +803,8 @@ static int msm_dig_cdc_codec_enable_dmic(struct snd_soc_dapm_widget *w, dmic_clk_en, dmic_clk_en); } snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_TX1_DMIC_CTL, 0x07, 0x02); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_TX2_DMIC_CTL, 0x07, 0x02); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_TX3_DMIC_CTL, 0x07, 0x02); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_TX4_DMIC_CTL, 0x07, 0x02); + MSM89XX_CDC_CORE_TX1_DMIC_CTL + (dmic - 1) * 0x20, + 0x07, 0x02); break; case SND_SOC_DAPM_POST_PMD: (*dmic_clk_cnt)--; @@ -884,6 +883,10 @@ static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w, 32 * (decimator - 1); tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL + 32 * (decimator - 1); + if (decimator == 5) { + tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG; + tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL; + } switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -1225,11 +1228,18 @@ static const struct snd_soc_dapm_route audio_dig_map[] = { {"I2S TX1", NULL, "DEC1 MUX"}, {"I2S TX2", NULL, "DEC2 MUX"}, - {"I2S TX3", NULL, "DEC3 MUX"}, - {"I2S TX4", NULL, "DEC4 MUX"}, + {"I2S TX3", NULL, "I2S TX2 INP1"}, + {"I2S TX4", NULL, "I2S TX2 INP2"}, {"I2S TX5", NULL, "DEC3 MUX"}, - {"I2S TX6", NULL, "DEC4 MUX"}, - {"I2S TX6", NULL, "DEC5 MUX"}, + {"I2S TX6", NULL, "I2S TX3 INP2"}, + + {"I2S TX2 INP1", "RX_MIX1", "RX1 MIX2"}, + {"I2S TX2 INP1", "DEC3", "DEC3 MUX"}, + {"I2S TX2 INP2", "RX_MIX2", "RX2 MIX2"}, + {"I2S TX2 INP2", "RX_MIX3", "RX3 MIX1"}, + {"I2S TX2 INP2", "DEC4", "DEC4 MUX"}, + {"I2S TX3 INP2", "DEC4", "DEC4 MUX"}, + {"I2S TX3 INP2", "DEC5", "DEC5 MUX"}, {"PDM_OUT_RX1", NULL, "RX1 CHAIN"}, {"PDM_OUT_RX2", NULL, "RX2 CHAIN"}, @@ -1350,6 +1360,19 @@ static const struct snd_soc_dapm_route audio_dig_map[] = { {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"}, }; + +static const char * const i2s_tx2_inp1_text[] = { + "ZERO", "RX_MIX1", "DEC3" +}; + +static const char * const i2s_tx2_inp2_text[] = { + "ZERO", "RX_MIX2", "RX_MIX3", "DEC4" +}; + +static const char * const i2s_tx3_inp2_text[] = { + "DEC4", "DEC5" +}; + static const char * const rx_mix1_text[] = { "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3" }; @@ -1365,6 +1388,20 @@ static const char * const dec_mux_text[] = { static const char * const iir_inp1_text[] = { "ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3", "DEC3", "DEC4" }; + +/* I2S TX MUXes */ +static const struct soc_enum i2s_tx2_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, + 2, 3, i2s_tx2_inp1_text); + +static const struct soc_enum i2s_tx2_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, + 0, 4, i2s_tx2_inp2_text); + +static const struct soc_enum i2s_tx3_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, + 4, 2, i2s_tx3_inp2_text); + /* RX1 MIX1 */ static const struct soc_enum rx_mix1_inp1_chain_enum = SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B1_CTL, @@ -1482,6 +1519,15 @@ static const struct snd_kcontrol_new dec4_mux = static const struct snd_kcontrol_new decsva_mux = MSM89XX_DEC_ENUM("DEC5 MUX Mux", decsva_mux_enum); +static const struct snd_kcontrol_new i2s_tx2_inp1_mux = + SOC_DAPM_ENUM("I2S TX2 INP1 Mux", i2s_tx2_inp1_chain_enum); + +static const struct snd_kcontrol_new i2s_tx2_inp2_mux = + SOC_DAPM_ENUM("I2S TX2 INP2 Mux", i2s_tx2_inp2_chain_enum); + +static const struct snd_kcontrol_new i2s_tx3_inp2_mux = + SOC_DAPM_ENUM("I2S TX3 INP2 Mux", i2s_tx3_inp2_chain_enum); + static const struct snd_kcontrol_new iir1_inp1_mux = SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum); @@ -1623,6 +1669,14 @@ static const struct snd_soc_dapm_widget msm_dig_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", MSM89XX_CDC_CORE_CLK_TX_I2S_CTL, 4, 0, NULL, 0), + + SND_SOC_DAPM_MUX("I2S TX2 INP1", SND_SOC_NOPM, 0, 0, + &i2s_tx2_inp1_mux), + SND_SOC_DAPM_MUX("I2S TX2 INP2", SND_SOC_NOPM, 0, 0, + &i2s_tx2_inp2_mux), + SND_SOC_DAPM_MUX("I2S TX3 INP2", SND_SOC_NOPM, 0, 0, + &i2s_tx3_inp2_mux), + /* Digital Mic Inputs */ SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | diff --git a/sound/soc/codecs/wcd-dsp-mgr.c b/sound/soc/codecs/wcd-dsp-mgr.c index f51301d1ab08..71a2052f1089 100644 --- a/sound/soc/codecs/wcd-dsp-mgr.c +++ b/sound/soc/codecs/wcd-dsp-mgr.c @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-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 @@ -881,12 +880,50 @@ done: static int wdsp_suspend(struct device *wdsp_dev) { - return 0; + struct wdsp_mgr_priv *wdsp; + int rc = 0, i; + + if (!wdsp_dev) { + pr_err("%s: Invalid handle to device\n", __func__); + return -EINVAL; + } + + wdsp = dev_get_drvdata(wdsp_dev); + + for (i = WDSP_CMPNT_TYPE_MAX - 1; i >= 0; i--) { + rc = wdsp_unicast_event(wdsp, i, WDSP_EVENT_SUSPEND, NULL); + if (rc < 0) { + WDSP_ERR(wdsp, "component %s failed to suspend\n", + WDSP_GET_CMPNT_TYPE_STR(i)); + break; + } + } + + return rc; } static int wdsp_resume(struct device *wdsp_dev) { - return 0; + struct wdsp_mgr_priv *wdsp; + int rc = 0, i; + + if (!wdsp_dev) { + pr_err("%s: Invalid handle to device\n", __func__); + return -EINVAL; + } + + wdsp = dev_get_drvdata(wdsp_dev); + + for (i = 0; i < WDSP_CMPNT_TYPE_MAX; i++) { + rc = wdsp_unicast_event(wdsp, i, WDSP_EVENT_RESUME, NULL); + if (rc < 0) { + WDSP_ERR(wdsp, "component %s failed to resume\n", + WDSP_GET_CMPNT_TYPE_STR(i)); + break; + } + } + + return rc; } static struct wdsp_mgr_ops wdsp_ops = { diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index cb201899b4b8..8454ebfc6216 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -1610,12 +1610,8 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0); wcd_mbhc_report_plug(mbhc, 0, SND_JACK_LINEOUT); } else if (mbhc->current_plug == MBHC_PLUG_TYPE_ANC_HEADPHONE) { - mbhc->mbhc_cb->irq_control(codec, - mbhc->intr_ids->mbhc_hs_rem_intr, - false); - mbhc->mbhc_cb->irq_control(codec, - mbhc->intr_ids->mbhc_hs_ins_intr, - false); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM, false); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, 0); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0); diff --git a/sound/soc/codecs/wcd-spi.c b/sound/soc/codecs/wcd-spi.c index 614410c26a91..b03a8a9caed7 100644 --- a/sound/soc/codecs/wcd-spi.c +++ b/sound/soc/codecs/wcd-spi.c @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-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 @@ -60,7 +59,8 @@ /* Command delays */ #define WCD_SPI_CLKREQ_DELAY_USECS (500) -#define WCD_SPI_CLK_OFF_TIMER_MS (3000) +#define WCD_SPI_CLK_OFF_TIMER_MS (500) +#define WCD_SPI_RESUME_TIMEOUT_MS 100 /* Command masks */ #define WCD_CMD_ADDR_MASK \ @@ -90,6 +90,7 @@ /* Status mask bits */ #define WCD_SPI_CLK_STATE_ENABLED BIT(0) +#define WCD_SPI_IS_SUSPENDED BIT(1) /* Locking related */ #define WCD_SPI_MUTEX_LOCK(spi, lock) \ @@ -144,6 +145,9 @@ struct wcd_spi_priv { /* Debugfs related information */ struct wcd_spi_debug_data debug_data; + + /* Completion object to indicate system resume completion */ + struct completion resume_comp; }; enum xfer_request { @@ -170,6 +174,55 @@ static void wcd_spi_reinit_xfer(struct spi_transfer *xfer) xfer->len = 0; } +static bool wcd_spi_is_suspended(struct wcd_spi_priv *wcd_spi) +{ + return test_bit(WCD_SPI_IS_SUSPENDED, &wcd_spi->status_mask); +} + +static bool wcd_spi_can_suspend(struct wcd_spi_priv *wcd_spi) +{ + struct spi_device *spi = wcd_spi->spi; + + if (wcd_spi->clk_users > 0 || + test_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask)) { + dev_err(&spi->dev, "%s: cannot suspend, clk_users = %d\n", + __func__, wcd_spi->clk_users); + return false; + } + + return true; +} + +static int wcd_spi_wait_for_resume(struct wcd_spi_priv *wcd_spi) +{ + struct spi_device *spi = wcd_spi->spi; + int rc = 0; + + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + /* If the system is already in resumed state, return right away */ + if (!wcd_spi_is_suspended(wcd_spi)) + goto done; + + /* If suspended then wait for resume to happen */ + reinit_completion(&wcd_spi->resume_comp); + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + rc = wait_for_completion_timeout(&wcd_spi->resume_comp, + msecs_to_jiffies(WCD_SPI_RESUME_TIMEOUT_MS)); + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + if (rc == 0) { + dev_err(&spi->dev, "%s: failed to resume in %u msec\n", + __func__, WCD_SPI_RESUME_TIMEOUT_MS); + rc = -EIO; + goto done; + } + + dev_dbg(&spi->dev, "%s: resume successful\n", __func__); + rc = 0; +done: + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + return rc; +} + static int wcd_spi_read_single(struct spi_device *spi, u32 remote_addr, u32 *val) { @@ -579,6 +632,18 @@ static int wcd_spi_clk_ctrl(struct spi_device *spi, } if (request == WCD_SPI_CLK_ENABLE) { + /* + * If the SPI bus is suspended, then return error + * as the transaction cannot be completed. + */ + if (wcd_spi_is_suspended(wcd_spi)) { + dev_err(&spi->dev, + "%s: SPI suspended, cannot enable clk\n", + __func__); + ret = -EIO; + goto done; + } + /* Cancel the disable clk work */ WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); cancel_delayed_work_sync(&wcd_spi->clk_dwork); @@ -899,6 +964,17 @@ static int wdsp_spi_event_handler(struct device *dev, void *priv_data, ret = wdsp_spi_read_section(spi, data); break; + case WDSP_EVENT_SUSPEND: + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + if (!wcd_spi_can_suspend(wcd_spi)) + ret = -EBUSY; + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + break; + + case WDSP_EVENT_RESUME: + ret = wcd_spi_wait_for_resume(wcd_spi); + break; + default: dev_dbg(&spi->dev, "%s: Unhandled event %d\n", __func__, event); @@ -1303,6 +1379,7 @@ static int wcd_spi_probe(struct spi_device *spi) mutex_init(&wcd_spi->clk_mutex); mutex_init(&wcd_spi->xfer_mutex); INIT_DELAYED_WORK(&wcd_spi->clk_dwork, wcd_spi_clk_work); + init_completion(&wcd_spi->resume_comp); wcd_spi->spi = spi; spi_set_drvdata(spi, wcd_spi); @@ -1340,6 +1417,61 @@ static int wcd_spi_remove(struct spi_device *spi) return 0; } +#ifdef CONFIG_PM +static int wcd_spi_suspend(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + int rc = 0; + + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + if (!wcd_spi_can_suspend(wcd_spi)) { + rc = -EBUSY; + goto done; + } + + /* + * If we are here, it is okay to let the suspend go + * through for this driver. But, still need to notify + * the master to make sure all other components can suspend + * as well. + */ + if (wcd_spi->m_dev && wcd_spi->m_ops && + wcd_spi->m_ops->suspend) { + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + rc = wcd_spi->m_ops->suspend(wcd_spi->m_dev); + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + } + + if (rc == 0) + set_bit(WCD_SPI_IS_SUSPENDED, &wcd_spi->status_mask); + else + dev_dbg(&spi->dev, "%s: cannot suspend, err = %d\n", + __func__, rc); +done: + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + return rc; +} + +static int wcd_spi_resume(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + clear_bit(WCD_SPI_IS_SUSPENDED, &wcd_spi->status_mask); + complete(&wcd_spi->resume_comp); + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + + return 0; +} + +static const struct dev_pm_ops wcd_spi_pm_ops = { + .suspend = wcd_spi_suspend, + .resume = wcd_spi_resume, +}; +#endif + static const struct of_device_id wcd_spi_of_match[] = { { .compatible = "qcom,wcd-spi-v2", }, { } @@ -1350,6 +1482,9 @@ static struct spi_driver wcd_spi_driver = { .driver = { .name = "wcd-spi-v2", .of_match_table = wcd_spi_of_match, +#ifdef CONFIG_PM + .pm = &wcd_spi_pm_ops, +#endif }, .probe = wcd_spi_probe, .remove = wcd_spi_remove, diff --git a/sound/soc/codecs/wcd934x/wcd934x-routing.h b/sound/soc/codecs/wcd934x/wcd934x-routing.h index 8ca4c07a3327..cd165af43eab 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-routing.h +++ b/sound/soc/codecs/wcd934x/wcd934x-routing.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-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 @@ -914,9 +914,23 @@ const struct snd_soc_dapm_route tavil_audio_map[] = { {"ANC OUT EAR Enable", "Switch", "ADC MUX11"}, {"RX INT0 MIX2", NULL, "ANC OUT EAR Enable"}, + {"ANC OUT HPHL Enable", "Switch", "ADC MUX10"}, + {"ANC OUT HPHL Enable", "Switch", "ADC MUX11"}, + {"RX INT1 MIX2", NULL, "ANC OUT HPHL Enable"}, + + {"ANC OUT HPHR Enable", "Switch", "ADC MUX12"}, + {"ANC OUT HPHR Enable", "Switch", "ADC MUX13"}, + {"RX INT2 MIX2", NULL, "ANC OUT HPHR Enable"}, + {"ANC EAR PA", NULL, "RX INT0 DAC"}, {"ANC EAR", NULL, "ANC EAR PA"}, + {"ANC HPHL PA", NULL, "RX INT1 DAC"}, + {"ANC HPHL", NULL, "ANC HPHL PA"}, + + {"ANC HPHR PA", NULL, "RX INT2 DAC"}, + {"ANC HPHR", NULL, "ANC HPHR PA"}, + {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"}, {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"}, {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"}, diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index c5d2b1ce8151..5b300a668489 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -176,6 +176,10 @@ enum { AUDIO_NOMINAL, HPH_PA_DELAY, CLSH_Z_CONFIG, + ANC_MIC_AMIC1, + ANC_MIC_AMIC2, + ANC_MIC_AMIC3, + ANC_MIC_AMIC4, }; enum { @@ -510,6 +514,7 @@ module_param(tx_unmute_delay, int, S_IRUGO | S_IWUSR | S_IWGRP); MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); +static void tavil_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); /* Hold instance to soundwire platform device */ struct tavil_swr_ctrl_data { @@ -998,14 +1003,30 @@ static int tavil_put_anc_func(struct snd_kcontrol *kcontrol, snd_soc_dapm_enable_pin(dapm, "ANC EAR PA"); snd_soc_dapm_enable_pin(dapm, "ANC EAR"); snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHR"); snd_soc_dapm_disable_pin(dapm, "EAR PA"); snd_soc_dapm_disable_pin(dapm, "EAR"); + snd_soc_dapm_disable_pin(dapm, "HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "HPHL"); + snd_soc_dapm_disable_pin(dapm, "HPHR"); } else { snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); snd_soc_dapm_disable_pin(dapm, "ANC EAR"); snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR"); snd_soc_dapm_enable_pin(dapm, "EAR PA"); snd_soc_dapm_enable_pin(dapm, "EAR"); + snd_soc_dapm_enable_pin(dapm, "HPHL"); + snd_soc_dapm_enable_pin(dapm, "HPHR"); + snd_soc_dapm_enable_pin(dapm, "HPHL PA"); + snd_soc_dapm_enable_pin(dapm, "HPHR PA"); } mutex_unlock(&tavil->codec_mutex); @@ -1122,16 +1143,56 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, } /* Rate converter clk enable and set bypass mode */ - snd_soc_update_bits(codec, WCD934X_CDC_ANC0_RC_COMMON_CTL, - 0x05, 0x05); + if (!strcmp(w->name, "RX INT0 DAC") || + !strcmp(w->name, "RX INT1 DAC") || + !strcmp(w->name, "ANC SPK1 PA")) { + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_RC_COMMON_CTL, + 0x05, 0x05); + if (!strcmp(w->name, "RX INT1 DAC")) { + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_FIFO_COMMON_CTL, + 0x66, 0x66); + } + } else if (!strcmp(w->name, "RX INT2 DAC")) { + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_RC_COMMON_CTL, + 0x05, 0x05); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_FIFO_COMMON_CTL, + 0x66, 0x66); + } + if (!strcmp(w->name, "RX INT1 DAC")) + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08); + else if (!strcmp(w->name, "RX INT2 DAC")) + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08); + if (!hwdep_cal) release_firmware(fw); break; + + case SND_SOC_DAPM_POST_PMU: + if (!strcmp(w->name, "ANC HPHL PA") || + !strcmp(w->name, "ANC HPHR PA")) { + /* Remove ANC Rx from reset */ + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_CLK_RESET_CTL, + 0x08, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x08, 0x00); + } + + break; + case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WCD934X_CDC_ANC0_RC_COMMON_CTL, 0x05, 0x00); if (!strcmp(w->name, "ANC EAR PA") || - !strcmp(w->name, "ANC SPK1 PA")) { + !strcmp(w->name, "ANC SPK1 PA") || + !strcmp(w->name, "ANC HPHL PA")) { snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_1_CTL, 0x30, 0x00); msleep(50); @@ -1146,6 +1207,21 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD934X_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x00); + } else if (!strcmp(w->name, "ANC HPHR PA")) { + snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_1_CTL, + 0x30, 0x00); + msleep(50); + snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_1_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x00); } break; } @@ -1893,6 +1969,18 @@ static void tavil_codec_override(struct snd_soc_codec *codec, int mode, } } +static void tavil_codec_clear_anc_tx_hold(struct tavil_priv *tavil) +{ + if (test_and_clear_bit(ANC_MIC_AMIC1, &tavil->status_mask)) + tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC1, false); + if (test_and_clear_bit(ANC_MIC_AMIC2, &tavil->status_mask)) + tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC2, false); + if (test_and_clear_bit(ANC_MIC_AMIC3, &tavil->status_mask)) + tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC3, false); + if (test_and_clear_bit(ANC_MIC_AMIC4, &tavil->status_mask)) + tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC4, false); +} + static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -1900,6 +1988,7 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + int ret = 0; dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); @@ -1908,6 +1997,11 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, if (TAVIL_IS_1_0(tavil->wcd9xxx)) snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, 0x06, (0x03 << 1)); + + if ((!(strcmp(w->name, "ANC HPHR PA"))) && + (test_bit(HPH_PA_DELAY, &tavil->status_mask))) + snd_soc_update_bits(codec, WCD934X_ANA_HPH, 0xC0, 0xC0); + set_bit(HPH_PA_DELAY, &tavil->status_mask); if (dsd_conf && (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) { @@ -1917,6 +2011,16 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, } break; case SND_SOC_DAPM_POST_PMU: + if ((!(strcmp(w->name, "ANC HPHR PA")))) { + if ((snd_soc_read(codec, WCD934X_ANA_HPH) & 0xC0) + != 0xC0) + /* + * If PA_EN is not set (potentially in ANC case) + * then do nothing for POST_PMU and let left + * channel handle everything. + */ + break; + } /* * 7ms sleep is required after PA is enabled as per * HW requirement. If compander is disabled, then @@ -1929,6 +2033,12 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, usleep_range(7000, 7100); clear_bit(HPH_PA_DELAY, &tavil->status_mask); } + if (tavil->anc_func) { + /* Clear Tx FE HOLD if both PAs are enabled */ + if ((snd_soc_read(tavil->codec, WCD934X_ANA_HPH) & + 0xC0) == 0xC0) + tavil_codec_clear_anc_tx_hold(tavil); + } snd_soc_update_bits(codec, WCD934X_HPH_R_TEST, 0x01, 0x01); @@ -1951,6 +2061,34 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x04, 0x00); + if (!(strcmp(w->name, "ANC HPHR PA"))) { + pr_debug("%s:Do everything needed for left channel\n", + __func__); + /* Do everything needed for left channel */ + snd_soc_update_bits(codec, WCD934X_HPH_L_TEST, + 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); + + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + WCD934X_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD934X_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x00); + + if (dsd_conf && (snd_soc_read(codec, + WCD934X_CDC_DSD0_PATH_CTL) & + 0x01)) + snd_soc_update_bits(codec, + WCD934X_CDC_DSD0_CFG2, + 0x04, 0x00); + /* Remove ANC Rx from reset */ + ret = tavil_codec_enable_anc(w, kcontrol, event); + } tavil_codec_override(codec, tavil->hph_mode, event); break; case SND_SOC_DAPM_PRE_PMD: @@ -1967,6 +2105,8 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, 0x10, 0x10); snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_MIX_CTL, 0x10, 0x10); + if (!(strcmp(w->name, "ANC HPHR PA"))) + snd_soc_update_bits(codec, WCD934X_ANA_HPH, 0x40, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* @@ -1984,10 +2124,16 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, if (TAVIL_IS_1_0(tavil->wcd9xxx)) snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, 0x06, 0x0); + if (!(strcmp(w->name, "ANC HPHR PA"))) { + ret = tavil_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + WCD934X_CDC_RX2_RX_PATH_CFG0, + 0x10, 0x00); + } break; }; - return 0; + return ret; } static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, @@ -1997,6 +2143,7 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + int ret = 0; dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); @@ -2005,6 +2152,10 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, if (TAVIL_IS_1_0(tavil->wcd9xxx)) snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, 0x06, (0x03 << 1)); + if ((!(strcmp(w->name, "ANC HPHL PA"))) && + (test_bit(HPH_PA_DELAY, &tavil->status_mask))) + snd_soc_update_bits(codec, WCD934X_ANA_HPH, + 0xC0, 0xC0); set_bit(HPH_PA_DELAY, &tavil->status_mask); if (dsd_conf && (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) { @@ -2014,6 +2165,16 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, } break; case SND_SOC_DAPM_POST_PMU: + if (!(strcmp(w->name, "ANC HPHL PA"))) { + if ((snd_soc_read(codec, WCD934X_ANA_HPH) & 0xC0) + != 0xC0) + /* + * If PA_EN is not set (potentially in ANC + * case) then do nothing for POST_PMU and + * let right channel handle everything. + */ + break; + } /* * 7ms sleep is required after PA is enabled as per * HW requirement. If compander is disabled, then @@ -2026,6 +2187,13 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, usleep_range(7000, 7100); clear_bit(HPH_PA_DELAY, &tavil->status_mask); } + if (tavil->anc_func) { + /* Clear Tx FE HOLD if both PAs are enabled */ + if ((snd_soc_read(tavil->codec, WCD934X_ANA_HPH) & + 0xC0) == 0xC0) + tavil_codec_clear_anc_tx_hold(tavil); + } + snd_soc_update_bits(codec, WCD934X_HPH_L_TEST, 0x01, 0x01); /* Remove Mute on primary path */ snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL, @@ -2046,6 +2214,33 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, 0x04, 0x00); + if (!(strcmp(w->name, "ANC HPHL PA"))) { + pr_debug("%s:Do everything needed for right channel\n", + __func__); + + /* Do everything needed for right channel */ + snd_soc_update_bits(codec, WCD934X_HPH_R_TEST, + 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); + + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + WCD934X_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD934X_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x00); + if (dsd_conf && (snd_soc_read(codec, + WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) + snd_soc_update_bits(codec, + WCD934X_CDC_DSD1_CFG2, + 0x04, 0x00); + /* Remove ANC Rx from reset */ + ret = tavil_codec_enable_anc(w, kcontrol, event); + } tavil_codec_override(codec, tavil->hph_mode, event); break; case SND_SOC_DAPM_PRE_PMD: @@ -2063,6 +2258,9 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, 0x10, 0x10); snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_MIX_CTL, 0x10, 0x10); + if (!(strcmp(w->name, "ANC HPHL PA"))) + snd_soc_update_bits(codec, WCD934X_ANA_HPH, + 0x80, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* @@ -2080,10 +2278,15 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, if (TAVIL_IS_1_0(tavil->wcd9xxx)) snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, 0x06, 0x0); + if (!(strcmp(w->name, "ANC HPHL PA"))) { + ret = tavil_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + WCD934X_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00); + } break; }; - return 0; + return ret; } static int tavil_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, @@ -2190,12 +2393,18 @@ static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, int hph_mode = tavil->hph_mode; u8 dem_inp; struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, w->name, event, hph_mode); switch (event) { case SND_SOC_DAPM_PRE_PMU: + if (tavil->anc_func) { + ret = tavil_codec_enable_anc(w, kcontrol, event); + /* 40 msec delay is needed to avoid click and pop */ + msleep(40); + } /* Read DEM INP Select */ dem_inp = snd_soc_read(codec, WCD934X_CDC_RX2_RX_PATH_SEC0) & 0x03; @@ -2226,6 +2435,10 @@ static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHR, hph_mode); + if (tavil->anc_func) + snd_soc_update_bits(codec, + WCD934X_CDC_RX2_RX_PATH_CFG0, + 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ @@ -2269,6 +2482,11 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + if (tavil->anc_func) { + ret = tavil_codec_enable_anc(w, kcontrol, event); + /* 40 msec delay is needed to avoid click and pop */ + msleep(40); + } /* Read DEM INP Select */ dem_inp = snd_soc_read(codec, WCD934X_CDC_RX1_RX_PATH_SEC0) & 0x03; @@ -2300,6 +2518,11 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, WCD_CLSH_STATE_HPHL, hph_mode); + if (tavil->anc_func) + snd_soc_update_bits(codec, + WCD934X_CDC_RX1_RX_PATH_CFG0, + 0x10, 0x10); + ret = tavil_mbhc_get_impedance(tavil->mbhc, &impedl, &impedr); if (!ret) { @@ -3184,6 +3407,15 @@ int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec, } EXPORT_SYMBOL(tavil_codec_enable_interp_clk); +static int tavil_anc_out_switch_cb(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + tavil_codec_enable_interp_clk(codec, event, w->shift); + + return 0; +} static int tavil_codec_set_idle_detect_thr(struct snd_soc_codec *codec, int interp, int path_type) { @@ -3638,8 +3870,8 @@ static int tavil_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, { int adc_mux_n = w->shift; struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); int amic_n; - u16 amic_reg; dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); @@ -3647,8 +3879,13 @@ static int tavil_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: amic_n = tavil_codec_find_amic_input(codec, adc_mux_n); if (amic_n) { - amic_reg = WCD934X_ANA_AMIC1 + amic_n - 1; - tavil_codec_set_tx_hold(codec, amic_reg, false); + /* + * Prevent ANC Rx pop by leaving Tx FE in HOLD + * state until PA is up. Track AMIC being used + * so we can release the HOLD later. + */ + set_bit(ANC_MIC_AMIC1 + amic_n - 1, + &tavil->status_mask); } break; default: @@ -6471,6 +6708,12 @@ static const struct snd_kcontrol_new anc_ear_spkr_switch = static const struct snd_kcontrol_new anc_spkr_pa_switch = SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); +static const struct snd_kcontrol_new anc_hphl_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_hphr_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + static const struct snd_kcontrol_new mad_cpe1_switch = SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); @@ -7110,6 +7353,14 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = { SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0, tavil_codec_enable_spkr_anc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0, + tavil_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0, + tavil_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_OUTPUT("EAR"), SND_SOC_DAPM_OUTPUT("HPHL"), @@ -7119,6 +7370,8 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("SPK1 OUT"), SND_SOC_DAPM_OUTPUT("SPK2 OUT"), SND_SOC_DAPM_OUTPUT("ANC EAR"), + SND_SOC_DAPM_OUTPUT("ANC HPHL"), + SND_SOC_DAPM_OUTPUT("ANC HPHR"), SND_SOC_DAPM_SWITCH("ANC OUT EAR Enable", SND_SOC_NOPM, 0, 0, &anc_ear_switch), @@ -7127,6 +7380,13 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = { SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0, &anc_spkr_pa_switch), + SND_SOC_DAPM_SWITCH_E("ANC OUT HPHL Enable", SND_SOC_NOPM, INTERP_HPHL, + 0, &anc_hphl_pa_switch, tavil_anc_out_switch_cb, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SWITCH_E("ANC OUT HPHR Enable", SND_SOC_NOPM, INTERP_HPHR, + 0, &anc_hphr_pa_switch, tavil_anc_out_switch_cb, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0, tavil_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -9030,6 +9290,10 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) mutex_lock(&tavil->codec_mutex); snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); snd_soc_dapm_disable_pin(dapm, "ANC EAR"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR"); snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA"); mutex_unlock(&tavil->codec_mutex); diff --git a/sound/soc/codecs/wcd_cpe_core.c b/sound/soc/codecs/wcd_cpe_core.c index 2088698392de..2082c356203d 100644 --- a/sound/soc/codecs/wcd_cpe_core.c +++ b/sound/soc/codecs/wcd_cpe_core.c @@ -3029,7 +3029,7 @@ err_ret: static int wcd_cpe_set_one_param(void *core_handle, struct cpe_lsm_session *session, struct lsm_params_info *p_info, - void *data, enum LSM_PARAM_TYPE param_type) + void *data, uint32_t param_type) { struct wcd_cpe_core *core = core_handle; int rc = 0; @@ -3044,25 +3044,9 @@ static int wcd_cpe_set_one_param(void *core_handle, rc = wcd_cpe_send_param_epd_thres(core, session, data, &ids); break; - case LSM_OPERATION_MODE: { - struct cpe_lsm_ids connectport_ids; - - rc = wcd_cpe_send_param_opmode(core, session, - data, &ids); - if (rc) - break; - - connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK; - connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; - - rc = wcd_cpe_send_param_connectport(core, session, NULL, - &connectport_ids, CPE_AFE_PORT_1_TX); - if (rc) - dev_err(core->dev, - "%s: send_param_connectport failed, err %d\n", - __func__, rc); + case LSM_OPERATION_MODE: + rc = wcd_cpe_send_param_opmode(core, session, data, &ids); break; - } case LSM_GAIN: rc = wcd_cpe_send_param_gain(core, session, data, &ids); break; @@ -3081,13 +3065,13 @@ static int wcd_cpe_set_one_param(void *core_handle, break; default: pr_err("%s: wrong param_type 0x%x\n", - __func__, p_info->param_type); + __func__, param_type); } if (rc) dev_err(core->dev, "%s: send_param(%d) failed, err %d\n", - __func__, p_info->param_type, rc); + __func__, param_type, rc); return rc; } diff --git a/sound/soc/codecs/wsa881x-regmap.c b/sound/soc/codecs/wsa881x-regmap.c index 63bbbfa6beab..faa44301286c 100644 --- a/sound/soc/codecs/wsa881x-regmap.c +++ b/sound/soc/codecs/wsa881x-regmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-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 @@ -216,6 +216,9 @@ static bool wsa881x_readable_register(struct device *dev, unsigned int reg) static bool wsa881x_volatile_register(struct device *dev, unsigned int reg) { + if (cache_always) + return false; + switch (reg) { case WSA881X_CHIP_ID0: case WSA881X_CHIP_ID1: diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index d7f4044b71ee..171735c8efd4 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-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 @@ -78,6 +78,7 @@ enum { WSA881X_DEV_UP, }; +bool cache_always; /* * Private data Structure for wsa881x. All parameters related to * WSA881X codec needs to be defined here. @@ -1227,6 +1228,9 @@ static int wsa881x_swr_probe(struct swr_device *pdev) if (ret) goto err; } + + cache_always = of_property_read_bool(pdev->dev.of_node, + "qcom,cache-always"); wsa881x_gpio_ctrl(wsa881x, true); wsa881x->state = WSA881X_DEV_UP; diff --git a/sound/soc/codecs/wsa881x.h b/sound/soc/codecs/wsa881x.h index be234ac0cd07..178237555c54 100644 --- a/sound/soc/codecs/wsa881x.h +++ b/sound/soc/codecs/wsa881x.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-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 @@ -20,6 +20,7 @@ #define WSA881X_MAX_SWR_PORTS 4 +extern bool cache_always; extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port, unsigned int *ch_mask, unsigned int *ch_rate); diff --git a/sound/soc/msm/msm-cpe-lsm.c b/sound/soc/msm/msm-cpe-lsm.c index ffc6119e543d..b2008d6da2a1 100644 --- a/sound/soc/msm/msm-cpe-lsm.c +++ b/sound/soc/msm/msm-cpe-lsm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017, 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 @@ -1049,7 +1049,6 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, struct cpe_lsm_lab *lab_d = &lsm_d->lab; struct snd_dma_buffer *dma_buf = &substream->dma_buffer; struct msm_slim_dma_data *dma_data = NULL; - struct snd_lsm_event_status *user; struct snd_lsm_detection_params det_params; int rc = 0; @@ -1318,11 +1317,20 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, break; case SNDRV_LSM_EVENT_STATUS: + case SNDRV_LSM_EVENT_STATUS_V3: { + struct snd_lsm_event_status *user; + struct snd_lsm_event_status_v3 *user_v3; + dev_dbg(rtd->dev, "%s: %s\n", - __func__, "SNDRV_LSM_EVENT_STATUS"); - - user = arg; + __func__, "SNDRV_LSM_EVENT_STATUS(_V3)"); + if (!arg) { + dev_err(rtd->dev, + "%s: Invalid argument to ioctl %s\n", + __func__, + "SNDRV_LSM_EVENT_STATUS(_V3)"); + return -EINVAL; + } /* * Release the api lock before wait to allow @@ -1343,31 +1351,62 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, if (atomic_read(&lsm_d->event_avail) == 1) { rc = 0; atomic_set(&lsm_d->event_avail, 0); - if (lsm_d->ev_det_pld_size > - user->payload_size) { - dev_err(rtd->dev, - "%s: avail pld_bytes = %u, needed = %u\n", - __func__, - user->payload_size, - lsm_d->ev_det_pld_size); - return -EINVAL; - } - - user->status = lsm_d->ev_det_status; - user->payload_size = lsm_d->ev_det_pld_size; - - memcpy(user->payload, - lsm_d->ev_det_payload, - lsm_d->ev_det_pld_size); + if (cmd == SNDRV_LSM_EVENT_STATUS) { + user = arg; + if (lsm_d->ev_det_pld_size > + user->payload_size) { + dev_err(rtd->dev, + "%s: avail pld_bytes = %u, needed = %u\n", + __func__, + user->payload_size, + lsm_d->ev_det_pld_size); + return -EINVAL; + } + + user->status = lsm_d->ev_det_status; + user->payload_size = + lsm_d->ev_det_pld_size; + memcpy(user->payload, + lsm_d->ev_det_payload, + lsm_d->ev_det_pld_size); + } else { + user_v3 = arg; + if (lsm_d->ev_det_pld_size > + user_v3->payload_size) { + dev_err(rtd->dev, + "%s: avail pld_bytes = %u, needed = %u\n", + __func__, + user_v3->payload_size, + lsm_d->ev_det_pld_size); + return -EINVAL; + } + /* event status timestamp not supported + * on CPE mode. Set msw and lsw to 0. + */ + user_v3->timestamp_lsw = 0; + user_v3->timestamp_msw = 0; + user_v3->status = lsm_d->ev_det_status; + user_v3->payload_size = + lsm_d->ev_det_pld_size; + memcpy(user_v3->payload, + lsm_d->ev_det_payload, + lsm_d->ev_det_pld_size); + } } else if (atomic_read(&lsm_d->event_stop) == 1) { dev_dbg(rtd->dev, "%s: wait_aborted\n", __func__); - user->payload_size = 0; + if (cmd == SNDRV_LSM_EVENT_STATUS) { + user = arg; + user->payload_size = 0; + } else { + user_v3 = arg; + user_v3->payload_size = 0; + } rc = 0; } } - + } break; case SNDRV_LSM_ABORT_EVENT: @@ -1499,6 +1538,20 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, } break; + case SNDRV_LSM_SET_PORT: { + u32 port_id = cpe->input_port_id; + + dev_dbg(rtd->dev, "%s: %s\n", __func__, "SNDRV_LSM_SET_PORT"); + rc = lsm_ops->lsm_set_port(cpe->core_handle, session, &port_id); + if (rc) { + dev_err(rtd->dev, + "%s: lsm_set_port failed, err = %d\n", + __func__, rc); + return rc; + } + } + break; + default: dev_dbg(rtd->dev, "%s: Default snd_lib_ioctl cmd 0x%x\n", @@ -1510,7 +1563,7 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, } static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, - struct snd_lsm_event_status *event_status) + u16 event_det_status) { struct snd_soc_pcm_runtime *rtd; struct cpe_lsm_data *lsm_d = NULL; @@ -1563,7 +1616,7 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, reinit_completion(&lab_d->thread_complete); if (session->lab_enable && - event_status->status == + event_det_status == LSM_VOICE_WAKEUP_STATUS_DETECTED) { out_port = &session->afe_out_port_cfg; out_port->port_id = session->afe_out_port_id; @@ -2167,7 +2220,60 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, goto done; } - msm_cpe_lsm_lab_start(substream, event_status); + msm_cpe_lsm_lab_start(substream, event_status->status); + msm_cpe_process_event_status_done(lsm_d); + kfree(event_status); + } + break; + case SNDRV_LSM_EVENT_STATUS_V3: { + struct snd_lsm_event_status_v3 u_event_status; + struct snd_lsm_event_status_v3 *event_status = NULL; + int u_pld_size = 0; + + if (copy_from_user(&u_event_status, (void *)arg, + sizeof(struct snd_lsm_event_status_v3))) { + dev_err(rtd->dev, + "%s: event status copy from user failed, size %zd\n", + __func__, + sizeof(struct snd_lsm_event_status_v3)); + err = -EFAULT; + goto done; + } + + if (u_event_status.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + dev_err(rtd->dev, + "%s: payload_size %d is invalid, max allowed = %d\n", + __func__, u_event_status.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + err = -EINVAL; + goto done; + } + + u_pld_size = sizeof(struct snd_lsm_event_status_v3) + + u_event_status.payload_size; + + event_status = kzalloc(u_pld_size, GFP_KERNEL); + if (!event_status) { + err = -ENOMEM; + goto done; + } else { + event_status->payload_size = + u_event_status.payload_size; + err = msm_cpe_lsm_ioctl_shared(substream, + cmd, event_status); + } + + if (!err && copy_to_user(arg, event_status, u_pld_size)) { + dev_err(rtd->dev, + "%s: copy to user failed\n", + __func__); + kfree(event_status); + err = -EFAULT; + goto done; + } + + msm_cpe_lsm_lab_start(substream, event_status->status); msm_cpe_process_event_status_done(lsm_d); kfree(event_status); } @@ -2297,7 +2403,7 @@ struct lsm_params_info_32 { u32 param_id; u32 param_size; compat_uptr_t param_data; - enum LSM_PARAM_TYPE param_type; + uint32_t param_type; }; struct snd_lsm_module_params_32 { @@ -2480,7 +2586,97 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, goto done; } - msm_cpe_lsm_lab_start(substream, event_status); + msm_cpe_lsm_lab_start(substream, event_status->status); + msm_cpe_process_event_status_done(lsm_d); + kfree(event_status); + kfree(udata_32); + } + break; + case SNDRV_LSM_EVENT_STATUS_V3: { + struct snd_lsm_event_status_v3 *event_status = NULL; + struct snd_lsm_event_status_v3 u_event_status32; + struct snd_lsm_event_status_v3 *udata_32 = NULL; + int u_pld_size = 0; + + dev_dbg(rtd->dev, + "%s: ioctl %s\n", __func__, + "SNDRV_LSM_EVENT_STATUS_V3_32"); + + if (copy_from_user(&u_event_status32, (void *)arg, + sizeof(struct snd_lsm_event_status_v3))) { + dev_err(rtd->dev, + "%s: event status copy from user failed, size %zd\n", + __func__, + sizeof(struct snd_lsm_event_status_v3)); + err = -EFAULT; + goto done; + } + + if (u_event_status32.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + dev_err(rtd->dev, + "%s: payload_size %d is invalid, max allowed = %d\n", + __func__, u_event_status32.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + err = -EINVAL; + goto done; + } + + u_pld_size = sizeof(struct snd_lsm_event_status_v3) + + u_event_status32.payload_size; + event_status = kzalloc(u_pld_size, GFP_KERNEL); + if (!event_status) { + dev_err(rtd->dev, + "%s: No memory for event status\n", + __func__); + err = -ENOMEM; + goto done; + } else { + event_status->payload_size = + u_event_status32.payload_size; + err = msm_cpe_lsm_ioctl_shared(substream, + cmd, event_status); + if (err) + dev_err(rtd->dev, + "%s: %s failed, error = %d\n", + __func__, + "SNDRV_LSM_EVENT_STATUS_V3_32", + err); + } + + if (!err) { + udata_32 = kzalloc(u_pld_size, GFP_KERNEL); + if (!udata_32) { + dev_err(rtd->dev, + "%s: nomem for udata\n", + __func__); + err = -EFAULT; + } else { + udata_32->timestamp_lsw = + event_status->timestamp_lsw; + udata_32->timestamp_msw = + event_status->timestamp_msw; + udata_32->status = event_status->status; + udata_32->payload_size = + event_status->payload_size; + memcpy(udata_32->payload, + event_status->payload, + u_pld_size); + } + } + + if (!err && copy_to_user(arg, udata_32, + u_pld_size)) { + dev_err(rtd->dev, + "%s: copy to user failed\n", + __func__); + kfree(event_status); + kfree(udata_32); + err = -EFAULT; + goto done; + } + + msm_cpe_lsm_lab_start(substream, event_status->status); msm_cpe_process_event_status_done(lsm_d); kfree(event_status); kfree(udata_32); diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c index 6c1897340e74..44a6a245c7a2 100644 --- a/sound/soc/msm/msm-dai-fe.c +++ b/sound/soc/msm/msm-dai-fe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -2203,12 +2203,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "Listen 1 Audio Service Capture", .aif_name = "LSM1_UL_HL", - .rates = SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, - .channels_max = 1, + .channels_max = 4, .rate_min = 16000, - .rate_max = 16000, + .rate_max = 48000, }, .ops = &msm_fe_dai_ops, .name = "LSM1", @@ -2218,12 +2220,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "Listen 2 Audio Service Capture", .aif_name = "LSM2_UL_HL", - .rates = SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, - .channels_max = 1, + .channels_max = 4, .rate_min = 16000, - .rate_max = 16000, + .rate_max = 48000, }, .ops = &msm_fe_dai_ops, .name = "LSM2", @@ -2233,12 +2237,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "Listen 3 Audio Service Capture", .aif_name = "LSM3_UL_HL", - .rates = SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, - .channels_max = 1, + .channels_max = 4, .rate_min = 16000, - .rate_max = 16000, + .rate_max = 48000, }, .ops = &msm_fe_dai_ops, .name = "LSM3", @@ -2248,12 +2254,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "Listen 4 Audio Service Capture", .aif_name = "LSM4_UL_HL", - .rates = SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, - .channels_max = 1, + .channels_max = 4, .rate_min = 16000, - .rate_max = 16000, + .rate_max = 48000, }, .ops = &msm_fe_dai_ops, .name = "LSM4", @@ -2263,12 +2271,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "Listen 5 Audio Service Capture", .aif_name = "LSM5_UL_HL", - .rates = SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, - .channels_max = 1, + .channels_max = 4, .rate_min = 16000, - .rate_max = 16000, + .rate_max = 48000, }, .ops = &msm_fe_dai_ops, .name = "LSM5", @@ -2278,12 +2288,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "Listen 6 Audio Service Capture", .aif_name = "LSM6_UL_HL", - .rates = SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, - .channels_max = 1, + .channels_max = 4, .rate_min = 16000, - .rate_max = 16000, + .rate_max = 48000, }, .ops = &msm_fe_dai_ops, .name = "LSM6", @@ -2293,12 +2305,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "Listen 7 Audio Service Capture", .aif_name = "LSM7_UL_HL", - .rates = SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, - .channels_max = 1, + .channels_max = 4, .rate_min = 16000, - .rate_max = 16000, + .rate_max = 48000, }, .ops = &msm_fe_dai_ops, .name = "LSM7", @@ -2308,12 +2322,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "Listen 8 Audio Service Capture", .aif_name = "LSM8_UL_HL", - .rates = SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, - .channels_max = 1, + .channels_max = 4, .rate_min = 16000, - .rate_max = 16000, + .rate_max = 48000, }, .ops = &msm_fe_dai_ops, .name = "LSM8", diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c index 557c7946506a..391640d53d56 100644 --- a/sound/soc/msm/msm8998.c +++ b/sound/soc/msm/msm8998.c @@ -3383,12 +3383,12 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "HPHR"); snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3"); snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1"); snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2"); } diff --git a/sound/soc/msm/qdsp6v2/audio_cal_utils.c b/sound/soc/msm/qdsp6v2/audio_cal_utils.c index 75af648baef3..b54cde4ef0c3 100644 --- a/sound/soc/msm/qdsp6v2/audio_cal_utils.c +++ b/sound/soc/msm/qdsp6v2/audio_cal_utils.c @@ -607,7 +607,6 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type, } INIT_LIST_HEAD(&cal_block->list); - list_add_tail(&cal_block->list, &cal_type->cal_blocks); cal_block->map_data.ion_map_handle = basic_cal->cal_data.mem_handle; if (basic_cal->cal_data.mem_handle > 0) { @@ -639,6 +638,7 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type, goto err; } cal_block->buffer_number = basic_cal->cal_hdr.buffer_number; + list_add_tail(&cal_block->list, &cal_type->cal_blocks); pr_debug("%s: created block for cal type %d, buf num %d, map handle %d, map size %zd paddr 0x%pK!\n", __func__, cal_type->info.reg.cal_type, cal_block->buffer_number, @@ -648,6 +648,8 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type, done: return cal_block; err: + kfree(cal_block->cal_info); + kfree(cal_block->client_info); kfree(cal_block); cal_block = NULL; return cal_block; diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c index 8da75d74776b..4664d39e87e0 100644 --- a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.c @@ -816,6 +816,10 @@ int msm_dolby_dap_param_to_get_control_get(struct snd_kcontrol *kcontrol, __func__, copp_idx); return -EINVAL; } + if (dolby_dap_params_get.length > 128 - DOLBY_PARAM_PAYLOAD_SIZE) { + pr_err("%s: Incorrect parameter length", __func__); + return -EINVAL; + } params_value = kzalloc(params_length + param_payload_len, GFP_KERNEL); if (!params_value) { pr_err("%s, params memory alloc failed\n", __func__); diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c index efb6644e551f..55ca659567f5 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017, 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 @@ -35,7 +35,7 @@ #define CAPTURE_MIN_NUM_PERIODS 2 #define CAPTURE_MAX_NUM_PERIODS 8 -#define CAPTURE_MAX_PERIOD_SIZE 4096 +#define CAPTURE_MAX_PERIOD_SIZE 61440 #define CAPTURE_MIN_PERIOD_SIZE 320 #define LISTEN_MAX_STATUS_PAYLOAD_SIZE 256 @@ -47,12 +47,14 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = { SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_16000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), .rate_min = 16000, - .rate_max = 16000, + .rate_max = 48000, .channels_min = 1, - .channels_max = 1, + .channels_max = 4, .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE, .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, @@ -64,7 +66,7 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = { /* Conventional and unconventional sample rate supported */ static unsigned int supported_sample_rates[] = { - 16000, + 16000, 48000, }; static struct snd_pcm_hw_constraint_list constraints_sample_rates = { @@ -76,7 +78,7 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = { struct lsm_priv { struct snd_pcm_substream *substream; struct lsm_client *lsm_client; - struct snd_lsm_event_status *event_status; + struct snd_lsm_event_status_v3 *event_status; spinlock_t event_lock; wait_queue_head_t event_wait; unsigned long event_avail; @@ -88,6 +90,11 @@ struct lsm_priv { int dma_write; }; +enum { /* lsm session states */ + IDLE = 0, + RUNNING, +}; + static int msm_lsm_queue_lab_buffer(struct lsm_priv *prtd, int i) { int rc = 0; @@ -196,6 +203,8 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, uint16_t status = 0; uint16_t payload_size = 0; uint16_t index = 0; + uint32_t event_ts_lsw = 0; + uint32_t event_ts_msw = 0; if (!substream || !substream->private_data) { pr_err("%s: Invalid %s\n", __func__, @@ -269,24 +278,44 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, "%s: event detect status = %d payload size = %d\n", __func__, status , payload_size); break; + + case LSM_SESSION_EVENT_DETECTION_STATUS_V3: + event_ts_lsw = ((uint32_t *)payload)[0]; + event_ts_msw = ((uint32_t *)payload)[1]; + status = (uint16_t)((uint8_t *)payload)[8]; + payload_size = (uint16_t)((uint8_t *)payload)[9]; + index = 10; + dev_dbg(rtd->dev, + "%s: ts_msw = %u, ts_lsw = %u, event detect status = %d payload size = %d\n", + __func__, event_ts_msw, event_ts_lsw, status, + payload_size); + break; + default: break; } if (opcode == LSM_SESSION_EVENT_DETECTION_STATUS || - opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V2) { + opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V2 || + opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V3) { spin_lock_irqsave(&prtd->event_lock, flags); prtd->event_status = krealloc(prtd->event_status, - sizeof(struct snd_lsm_event_status) + + sizeof(struct snd_lsm_event_status_v3) + payload_size, GFP_ATOMIC); if (!prtd->event_status) { dev_err(rtd->dev, "%s: no memory for event status\n", __func__); return; } - + /* + * event status timestamp will be non-zero and valid if + * opcode is LSM_SESSION_EVENT_DETECTION_STATUS_V3 + */ + prtd->event_status->timestamp_lsw = event_ts_lsw; + prtd->event_status->timestamp_msw = event_ts_msw; prtd->event_status->status = status; prtd->event_status->payload_size = payload_size; + if (likely(prtd->event_status)) { memcpy(prtd->event_status->payload, &((uint8_t *)payload)[index], @@ -641,6 +670,54 @@ err_ret: return rc; } +static int msm_lsm_set_poll_enable(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_lsm_poll_enable poll_enable; + int rc = 0; + + if (p_info->param_size != sizeof(poll_enable)) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + rc = -EINVAL; + goto done; + } + + if (copy_from_user(&poll_enable, p_info->param_data, + sizeof(poll_enable))) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size = %zd\n", + __func__, sizeof(poll_enable)); + rc = -EFAULT; + goto done; + } + + if (prtd->lsm_client->poll_enable == poll_enable.poll_en) { + dev_dbg(rtd->dev, + "%s: Polling for session %d already %s\n", + __func__, prtd->lsm_client->session, + (poll_enable.poll_en ? "enabled" : "disabled")); + rc = 0; + goto done; + } + + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, + &poll_enable, LSM_POLLING_ENABLE); + if (!rc) { + prtd->lsm_client->poll_enable = poll_enable.poll_en; + } else { + dev_err(rtd->dev, + "%s: Failed to set poll enable, err = %d\n", + __func__, rc); + } +done: + return rc; +} + static int msm_lsm_process_params(struct snd_pcm_substream *substream, struct snd_lsm_module_params *p_data, void *params) @@ -681,6 +758,9 @@ static int msm_lsm_process_params(struct snd_pcm_substream *substream, case LSM_CUSTOM_PARAMS: rc = msm_lsm_set_custom(substream, p_info); break; + case LSM_POLLING_ENABLE: + rc = msm_lsm_set_poll_enable(substream, p_info); + break; default: dev_err(rtd->dev, "%s: Invalid param_type %d\n", @@ -710,10 +790,8 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, struct snd_lsm_session_data session_data; int rc = 0; int xchg = 0; - u32 size = 0; struct snd_pcm_runtime *runtime; struct lsm_priv *prtd; - struct snd_lsm_event_status *user = arg; struct snd_lsm_detection_params det_params; uint8_t *confidence_level = NULL; @@ -870,6 +948,10 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, break; case SNDRV_LSM_EVENT_STATUS: + case SNDRV_LSM_EVENT_STATUS_V3: { + uint32_t ts_lsw, ts_msw; + uint16_t status = 0, payload_size = 0; + dev_dbg(rtd->dev, "%s: Get event status\n", __func__); atomic_set(&prtd->event_wait_stop, 0); rc = wait_event_freezable(prtd->event_wait, @@ -882,9 +964,12 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_dbg(rtd->dev, "%s: New event available %ld\n", __func__, prtd->event_avail); spin_lock_irqsave(&prtd->event_lock, flags); + if (prtd->event_status) { - size = sizeof(*(prtd->event_status)) + - prtd->event_status->payload_size; + payload_size = prtd->event_status->payload_size; + ts_lsw = prtd->event_status->timestamp_lsw; + ts_msw = prtd->event_status->timestamp_msw; + status = prtd->event_status->status; spin_unlock_irqrestore(&prtd->event_lock, flags); } else { @@ -896,15 +981,43 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, __func__); break; } - if (user->payload_size < - prtd->event_status->payload_size) { - dev_dbg(rtd->dev, - "%s: provided %d bytes isn't enough, needs %d bytes\n", - __func__, user->payload_size, - prtd->event_status->payload_size); - rc = -ENOMEM; + + if (cmd == SNDRV_LSM_EVENT_STATUS) { + struct snd_lsm_event_status *user = arg; + + if (user->payload_size < payload_size) { + dev_dbg(rtd->dev, + "%s: provided %d bytes isn't enough, needs %d bytes\n", + __func__, user->payload_size, + payload_size); + rc = -ENOMEM; + } else { + user->status = status; + user->payload_size = payload_size; + memcpy(user->payload, + prtd->event_status->payload, + payload_size); + } } else { - memcpy(user, prtd->event_status, size); + struct snd_lsm_event_status_v3 *user_v3 = arg; + + if (user_v3->payload_size < payload_size) { + dev_dbg(rtd->dev, + "%s: provided %d bytes isn't enough, needs %d bytes\n", + __func__, user_v3->payload_size, + payload_size); + rc = -ENOMEM; + } else { + user_v3->timestamp_lsw = ts_lsw; + user_v3->timestamp_msw = ts_msw; + user_v3->status = status; + user_v3->payload_size = payload_size; + memcpy(user_v3->payload, + prtd->event_status->payload, + payload_size); + } + } + if (!rc) { if (prtd->lsm_client->lab_enable && !prtd->lsm_client->lab_started && prtd->event_status->status == @@ -929,6 +1042,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, rc = 0; } break; + } case SNDRV_LSM_ABORT_EVENT: dev_dbg(rtd->dev, "%s: Aborting event status wait\n", @@ -1035,6 +1149,43 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, prtd->lsm_client->lab_started = false; } break; + + case SNDRV_LSM_SET_PORT: + dev_dbg(rtd->dev, "%s: set LSM port\n", __func__); + rc = q6lsm_set_port_connected(prtd->lsm_client); + break; + + case SNDRV_LSM_SET_FWK_MODE_CONFIG: { + u32 *mode = NULL; + + if (!arg) { + dev_err(rtd->dev, + "%s: Invalid param arg for ioctl %s session %d\n", + __func__, "SNDRV_LSM_SET_FWK_MODE_CONFIG", + prtd->lsm_client->session); + rc = -EINVAL; + break; + } + mode = (u32 *)arg; + if (prtd->lsm_client->event_mode == *mode) { + dev_dbg(rtd->dev, + "%s: mode for %d already set to %d\n", + __func__, prtd->lsm_client->session, *mode); + rc = 0; + } else { + dev_dbg(rtd->dev, "%s: Event mode = %d\n", + __func__, *mode); + rc = q6lsm_set_fwk_mode_cfg(prtd->lsm_client, *mode); + if (!rc) + prtd->lsm_client->event_mode = *mode; + else + dev_err(rtd->dev, + "%s: set event mode failed %d\n", + __func__, rc); + } + break; + } + default: dev_dbg(rtd->dev, "%s: Falling into default snd_lib_ioctl cmd 0x%x\n", @@ -1053,6 +1204,21 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, return rc; } #ifdef CONFIG_COMPAT + +struct snd_lsm_event_status32 { + u16 status; + u16 payload_size; + u8 payload[0]; +}; + +struct snd_lsm_event_status_v3_32 { + u32 timestamp_lsw; + u32 timestamp_msw; + u16 status; + u16 payload_size; + u8 payload[0]; +}; + struct snd_lsm_sound_model_v2_32 { compat_uptr_t data; compat_uptr_t confidence_level; @@ -1074,7 +1240,7 @@ struct lsm_params_info_32 { u32 param_id; u32 param_size; compat_uptr_t param_data; - enum LSM_PARAM_TYPE param_type; + uint32_t param_type; }; struct snd_lsm_module_params_32 { @@ -1090,6 +1256,8 @@ enum { _IOW('U', 0x0A, struct snd_lsm_detection_params_32), SNDRV_LSM_SET_MODULE_PARAMS_32 = _IOW('U', 0x0B, struct snd_lsm_module_params_32), + SNDRV_LSM_EVENT_STATUS_V3_32 = + _IOW('U', 0x0F, struct snd_lsm_event_status_v3_32), }; static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, @@ -1178,6 +1346,73 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, break; } + case SNDRV_LSM_EVENT_STATUS_V3_32: { + struct snd_lsm_event_status_v3_32 userarg32, *user32 = NULL; + struct snd_lsm_event_status_v3 *user = NULL; + + if (copy_from_user(&userarg32, arg, sizeof(userarg32))) { + dev_err(rtd->dev, "%s: err copyuser ioctl %s\n", + __func__, "SNDRV_LSM_EVENT_STATUS_V3_32"); + return -EFAULT; + } + + if (userarg32.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + pr_err("%s: payload_size %d is invalid, max allowed = %d\n", + __func__, userarg32.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + return -EINVAL; + } + + size = sizeof(*user) + userarg32.payload_size; + user = kmalloc(size, GFP_KERNEL); + if (!user) { + dev_err(rtd->dev, + "%s: Allocation failed event status size %d\n", + __func__, size); + return -EFAULT; + } + cmd = SNDRV_LSM_EVENT_STATUS_V3; + user->payload_size = userarg32.payload_size; + err = msm_lsm_ioctl_shared(substream, cmd, user); + + /* Update size with actual payload size */ + size = sizeof(userarg32) + user->payload_size; + if (!err && !access_ok(VERIFY_WRITE, arg, size)) { + dev_err(rtd->dev, + "%s: write verify failed size %d\n", + __func__, size); + err = -EFAULT; + } + if (!err) { + user32 = kmalloc(size, GFP_KERNEL); + if (!user32) { + dev_err(rtd->dev, + "%s: Allocation event user status size %d\n", + __func__, size); + err = -EFAULT; + } else { + user32->timestamp_lsw = user->timestamp_lsw; + user32->timestamp_msw = user->timestamp_msw; + user32->status = user->status; + user32->payload_size = user->payload_size; + memcpy(user32->payload, + user->payload, user32->payload_size); + } + } + if (!err && (copy_to_user(arg, user32, size))) { + dev_err(rtd->dev, "%s: failed to copy payload %d", + __func__, size); + err = -EFAULT; + } + kfree(user); + kfree(user32); + if (err) + dev_err(rtd->dev, "%s: lsmevent failed %d", + __func__, err); + break; + } + case SNDRV_LSM_REG_SND_MODEL_V2_32: { struct snd_lsm_sound_model_v2_32 snd_modelv232; struct snd_lsm_sound_model_v2 snd_modelv2; @@ -1573,6 +1808,67 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, "%s: lsmevent failed %d", __func__, err); return err; } + + case SNDRV_LSM_EVENT_STATUS_V3: { + struct snd_lsm_event_status_v3 *user = NULL; + struct snd_lsm_event_status_v3 userarg; + + dev_dbg(rtd->dev, + "%s: SNDRV_LSM_EVENT_STATUS_V3\n", __func__); + if (!arg) { + dev_err(rtd->dev, + "%s: Invalid params event_status_v3\n", + __func__); + return -EINVAL; + } + if (copy_from_user(&userarg, arg, sizeof(userarg))) { + dev_err(rtd->dev, + "%s: err copyuser event_status_v3\n", + __func__); + return -EFAULT; + } + + if (userarg.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + pr_err("%s: payload_size %d is invalid, max allowed = %d\n", + __func__, userarg.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + return -EINVAL; + } + + size = sizeof(struct snd_lsm_event_status_v3) + + userarg.payload_size; + user = kmalloc(size, GFP_KERNEL); + if (!user) { + dev_err(rtd->dev, + "%s: Allocation failed event status size %d\n", + __func__, size); + return -EFAULT; + } + user->payload_size = userarg.payload_size; + err = msm_lsm_ioctl_shared(substream, cmd, user); + + /* Update size with actual payload size */ + size = sizeof(*user) + user->payload_size; + if (!err && !access_ok(VERIFY_WRITE, arg, size)) { + dev_err(rtd->dev, + "%s: write verify failed size %d\n", + __func__, size); + err = -EFAULT; + } + if (!err && (copy_to_user(arg, user, size))) { + dev_err(rtd->dev, + "%s: failed to copy payload %d", + __func__, size); + err = -EFAULT; + } + kfree(user); + if (err) + dev_err(rtd->dev, + "%s: lsm_event_v3 failed %d", __func__, err); + break; + } + default: err = msm_lsm_ioctl_shared(substream, cmd, arg); break; @@ -1640,6 +1936,11 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) return -ENOMEM; } prtd->lsm_client->opened = false; + prtd->lsm_client->session_state = IDLE; + prtd->lsm_client->poll_enable = true; + prtd->lsm_client->perf_mode = 0; + prtd->lsm_client->event_mode = LSM_EVENT_NON_TIME_STAMP_MODE; + return 0; } @@ -1648,6 +1949,7 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd; + int ret = 0; if (!substream->private_data) { pr_err("%s: Invalid private_data", __func__); @@ -1661,9 +1963,30 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream) "%s: LSM client data ptr is NULL\n", __func__); return -EINVAL; } + + if (q6lsm_set_media_fmt_params(prtd->lsm_client)) + dev_dbg(rtd->dev, + "%s: failed to set lsm media fmt params\n", __func__); + + if (prtd->lsm_client->session_state == IDLE) { + ret = msm_pcm_routing_reg_phy_compr_stream( + rtd->dai_link->be_id, + prtd->lsm_client->perf_mode, + prtd->lsm_client->session, + SNDRV_PCM_STREAM_CAPTURE, + LISTEN); + if (ret) { + dev_err(rtd->dev, + "%s: register phy compr stream failed %d\n", + __func__, ret); + return ret; + } + } + + prtd->lsm_client->session_state = RUNNING; prtd->lsm_client->started = false; runtime->private_data = prtd; - return 0; + return ret; } static int msm_lsm_close(struct snd_pcm_substream *substream) @@ -1712,6 +2035,9 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) __func__); } + msm_pcm_routing_dereg_phy_stream(rtd->dai_link->be_id, + SNDRV_PCM_STREAM_CAPTURE); + if (prtd->lsm_client->opened) { q6lsm_close(prtd->lsm_client); prtd->lsm_client->opened = false; @@ -1733,7 +2059,7 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; - struct lsm_lab_hw_params *hw_params = NULL; + struct lsm_hw_params *hw_params = NULL; struct snd_soc_pcm_runtime *rtd; if (!substream->private_data) { @@ -1749,25 +2075,36 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } hw_params = &prtd->lsm_client->hw_params; - hw_params->sample_rate = params_rate(params); - hw_params->sample_size = - (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) ? 16 : 0; + hw_params->num_chs = params_channels(params); hw_params->period_count = params_periods(params); - if (hw_params->sample_rate != 16000 || hw_params->sample_size != 16 || - hw_params->period_count == 0) { + hw_params->sample_rate = params_rate(params); + if (((hw_params->sample_rate != 16000) && + (hw_params->sample_rate != 48000)) || + (hw_params->period_count == 0)) { dev_err(rtd->dev, - "%s: Invalid params sample rate %d sample size %d period count %d", + "%s: Invalid Params sample rate %d period count %d\n", __func__, hw_params->sample_rate, - hw_params->sample_size, - hw_params->period_count); + hw_params->period_count); return -EINVAL; } + + if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) { + hw_params->sample_size = 16; + } else if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE) { + hw_params->sample_size = 24; + } else { + dev_err(rtd->dev, "%s: Invalid Format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + hw_params->buf_sz = params_buffer_bytes(params) / - hw_params->period_count; + hw_params->period_count; dev_dbg(rtd->dev, - "%s: sample rate %d sample size %d buffer size %d period count %d\n", - __func__, hw_params->sample_rate, hw_params->sample_size, - hw_params->buf_sz, hw_params->period_count); + "%s: channels %d sample rate %d sample size %d buffer size %d period count %d\n", + __func__, hw_params->num_chs, hw_params->sample_rate, + hw_params->sample_size, hw_params->buf_sz, + hw_params->period_count); return 0; } @@ -1863,6 +2200,109 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, return 0; } +static int msm_lsm_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int app_type; + int acdb_dev_id; + int sample_rate; + + pr_debug("%s: fe_id- %llu\n", __func__, fe_id); + if ((fe_id < MSM_FRONTEND_DAI_LSM1) || + (fe_id > MSM_FRONTEND_DAI_LSM8)) { + pr_err("%s: Received out of bounds fe_id %llu\n", + __func__, fe_id); + return -EINVAL; + } + + app_type = ucontrol->value.integer.value[0]; + acdb_dev_id = ucontrol->value.integer.value[1]; + sample_rate = ucontrol->value.integer.value[2]; + + pr_debug("%s: app_type- %d acdb_dev_id- %d sample_rate- %d session_type- %d\n", + __func__, app_type, acdb_dev_id, sample_rate, SESSION_TYPE_TX); + msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type, + acdb_dev_id, sample_rate, SESSION_TYPE_TX); + + return 0; +} + +static int msm_lsm_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int ret = 0; + int app_type; + int acdb_dev_id; + int sample_rate; + + pr_debug("%s: fe_id- %llu\n", __func__, fe_id); + if ((fe_id < MSM_FRONTEND_DAI_LSM1) || + (fe_id > MSM_FRONTEND_DAI_LSM8)) { + pr_err("%s: Received out of bounds fe_id %llu\n", + __func__, fe_id); + return -EINVAL; + } + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_TX, + &app_type, &acdb_dev_id, &sample_rate); + if (ret < 0) { + pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[0] = app_type; + ucontrol->value.integer.value[1] = acdb_dev_id; + ucontrol->value.integer.value[2] = sample_rate; + pr_debug("%s: fedai_id %llu, session_type %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, SESSION_TYPE_TX, + app_type, acdb_dev_id, sample_rate); +done: + return ret; +} + +static int msm_lsm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + struct snd_pcm_usr *app_type_info; + struct snd_kcontrol *kctl; + const char *mixer_ctl_name = "Listen Stream"; + const char *deviceNo = "NN"; + const char *suffix = "App Type Cfg"; + int ctl_len, ret = 0; + + ctl_len = strlen(mixer_ctl_name) + 1 + + strlen(deviceNo) + 1 + strlen(suffix) + 1; + pr_debug("%s: Listen app type cntrl add\n", __func__); + ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE, + NULL, 1, ctl_len, rtd->dai_link->be_id, + &app_type_info); + if (ret < 0) { + pr_err("%s: Listen app type cntrl add failed: %d\n", + __func__, ret); + return ret; + } + kctl = app_type_info->kctl; + snprintf(kctl->id.name, ctl_len, "%s %d %s", + mixer_ctl_name, rtd->pcm->device, suffix); + kctl->put = msm_lsm_app_type_cfg_ctl_put; + kctl->get = msm_lsm_app_type_cfg_ctl_get; + return 0; +} + +static int msm_lsm_add_controls(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + + ret = msm_lsm_add_app_type_controls(rtd); + if (ret) + pr_err("%s, add app type controls failed:%d\n", __func__, ret); + + return ret; +} + static struct snd_pcm_ops msm_lsm_ops = { .open = msm_lsm_open, .close = msm_lsm_close, @@ -1877,11 +2317,16 @@ static struct snd_pcm_ops msm_lsm_ops = { static int msm_asoc_lsm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; + int ret = 0; if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - return 0; + ret = msm_lsm_add_controls(rtd); + if (ret) + pr_err("%s, kctl add failed:%d\n", __func__, ret); + + return ret; } static int msm_asoc_lsm_probe(struct snd_soc_platform *platform) diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index 2d410170f48d..39fdd6b49357 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -72,9 +72,12 @@ static int tert_mi2s_switch_enable; static int quat_mi2s_switch_enable; static int fm_pcmrx_switch_enable; static int usb_switch_enable; -static int lsm_mux_slim_port; +static int lsm_port_index; static int slim0_rx_aanc_fb_port; static int msm_route_ec_ref_rx; +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 = 48000; static uint32_t voc_session_id = ALL_SESSION_VSID; static int msm_route_ext_ec_ref; static bool is_custom_stereo_on; @@ -88,6 +91,8 @@ enum { MADSWAUDIO, }; +#define ADM_LSM_PORT_INDEX 9 + #define SLIMBUS_0_TX_TEXT "SLIMBUS_0_TX" #define SLIMBUS_1_TX_TEXT "SLIMBUS_1_TX" #define SLIMBUS_2_TX_TEXT "SLIMBUS_2_TX" @@ -96,12 +101,14 @@ enum { #define SLIMBUS_TX_VI_TEXT "SLIMBUS_TX_VI" #define SLIMBUS_5_TX_TEXT "SLIMBUS_5_TX" #define TERT_MI2S_TX_TEXT "TERT_MI2S_TX" +#define QUAT_MI2S_TX_TEXT "QUAT_MI2S_TX" +#define ADM_LSM_TX_TEXT "ADM_LSM_TX" #define LSM_FUNCTION_TEXT "LSM Function" -static const char * const mad_audio_mux_text[] = { +static const char * const lsm_port_text[] = { "None", SLIMBUS_0_TX_TEXT, SLIMBUS_1_TX_TEXT, SLIMBUS_2_TX_TEXT, - SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_TX_VI_TEXT, - SLIMBUS_5_TX_TEXT, TERT_MI2S_TX_TEXT + SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT, + TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT }; struct msm_pcm_route_bdai_pp_params { @@ -270,254 +277,262 @@ static void msm_pcm_routng_cfg_matrix_map_pp(struct route_payload payload, #define SLIMBUS_EXTPROC_RX AFE_PORT_INVALID struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { - { PRIMARY_I2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_RX}, - { PRIMARY_I2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_TX}, - { SLIMBUS_0_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_RX}, - { SLIMBUS_0_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_TX}, - { HDMI_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_HDMI}, - { INT_BT_SCO_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_RX}, - { INT_BT_SCO_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_TX}, - { INT_FM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_RX}, - { INT_FM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_TX}, - { RT_PROXY_PORT_001_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_AFE_PCM_RX}, - { RT_PROXY_PORT_001_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_AFE_PCM_TX}, - { AFE_PORT_ID_PRIMARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { PRIMARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_RX}, + { PRIMARY_I2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_TX}, + { SLIMBUS_0_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_RX}, + { SLIMBUS_0_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_TX}, + { HDMI_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_HDMI}, + { INT_BT_SCO_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_RX}, + { INT_BT_SCO_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_TX}, + { INT_FM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_RX}, + { INT_FM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_TX}, + { RT_PROXY_PORT_001_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_AFE_PCM_RX}, + { RT_PROXY_PORT_001_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_AFE_PCM_TX}, + { AFE_PORT_ID_PRIMARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_AUXPCM_RX}, - { AFE_PORT_ID_PRIMARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_AUXPCM_TX}, - { VOICE_PLAYBACK_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { VOICE_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_VOICE_PLAYBACK_TX}, - { VOICE2_PLAYBACK_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { VOICE2_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_VOICE2_PLAYBACK_TX}, - { VOICE_RECORD_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INCALL_RECORD_RX}, - { VOICE_RECORD_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INCALL_RECORD_TX}, - { MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_RX}, - { MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_TX}, - { SECONDARY_I2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_I2S_RX}, - { SLIMBUS_1_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_RX}, - { SLIMBUS_1_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_TX}, - { SLIMBUS_2_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_RX}, - { SLIMBUS_2_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_TX}, - { SLIMBUS_3_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_RX}, - { SLIMBUS_3_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_TX}, - { SLIMBUS_4_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX}, - { SLIMBUS_4_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX}, - { SLIMBUS_5_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_RX}, - { SLIMBUS_5_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_TX}, - { SLIMBUS_6_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_RX}, - { SLIMBUS_6_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_TX}, - { SLIMBUS_7_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_RX}, - { SLIMBUS_7_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX}, - { SLIMBUS_8_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX}, - { SLIMBUS_8_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX}, - { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_RX}, - { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_TX}, - { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_1_TX}, - { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { VOICE_RECORD_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_INCALL_RECORD_RX}, + { VOICE_RECORD_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_INCALL_RECORD_TX}, + { MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_RX}, + { MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_TX}, + { SECONDARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_I2S_RX}, + { SLIMBUS_1_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_RX}, + { SLIMBUS_1_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_TX}, + { SLIMBUS_2_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_RX}, + { SLIMBUS_2_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_TX}, + { SLIMBUS_3_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_RX}, + { SLIMBUS_3_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_TX}, + { SLIMBUS_4_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX}, + { SLIMBUS_4_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX}, + { SLIMBUS_5_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_RX}, + { SLIMBUS_5_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_TX}, + { SLIMBUS_6_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_RX}, + { SLIMBUS_6_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_TX}, + { SLIMBUS_7_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_RX}, + { SLIMBUS_7_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX}, + { SLIMBUS_8_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX}, + { SLIMBUS_8_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_RX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_TX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_1_TX}, + { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_MI2S_RX}, - { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_MI2S_TX}, - { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_MI2S_RX}, - { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_MI2S_TX}, - { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_MI2S_RX}, - { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_MI2S_TX}, - { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_MI2S_RX}, - { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_MI2S_TX}, - { AUDIO_PORT_ID_I2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AUDIO_PORT_ID_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_AUDIO_I2S_RX}, - { AFE_PORT_ID_SECONDARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_AUXPCM_RX}, - { AFE_PORT_ID_SECONDARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_AUXPCM_TX}, - { AFE_PORT_ID_SPDIF_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SPDIF_RX}, - { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SPDIF_RX}, + { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_MI2S_RX_SD1}, - { AFE_PORT_ID_QUINARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUINARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUIN_MI2S_RX}, - { AFE_PORT_ID_QUINARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUINARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUIN_MI2S_TX}, - { AFE_PORT_ID_SENARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SENARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SENARY_MI2S_TX}, - { AFE_PORT_ID_PRIMARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_0}, - { AFE_PORT_ID_PRIMARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_0}, - { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_1}, - { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_1}, - { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_2}, - { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_2}, - { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_3}, - { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_3}, - { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_4}, - { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_4}, - { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_5}, - { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_5}, - { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_6}, - { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_6}, - { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_7}, - { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_7}, - { AFE_PORT_ID_SECONDARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_0}, - { AFE_PORT_ID_SECONDARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_0}, - { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_1}, - { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_1}, - { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_2}, - { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_2}, - { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_3}, - { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_3}, - { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_4}, - { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_4}, - { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_5}, - { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_5}, - { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_6}, - { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_6}, - { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_7}, - { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_7}, - { AFE_PORT_ID_TERTIARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_0}, - { AFE_PORT_ID_TERTIARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_0}, - { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_1}, - { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_1}, - { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_2}, - { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_2}, - { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_3}, - { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_3}, - { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_4}, - { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_4}, - { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_5}, - { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_5}, - { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_6}, - { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_6}, - { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_7}, - { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_7}, - { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_0}, - { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_0}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_1}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_1}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_2}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_2}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_3}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_3}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_4}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_4}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_5}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_5}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_6}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_6}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_7}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_7}, - { INT_BT_A2DP_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_A2DP_RX}, - { AFE_PORT_ID_USB_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_RX}, - { AFE_PORT_ID_USB_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_TX}, - { DISPLAY_PORT_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_DISPLAY_PORT}, - { AFE_PORT_ID_TERTIARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { INT_BT_A2DP_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_A2DP_RX}, + { AFE_PORT_ID_USB_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_USB_AUDIO_RX}, + { AFE_PORT_ID_USB_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, + LPASS_BE_USB_AUDIO_TX}, + { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_DISPLAY_PORT}, + { AFE_PORT_ID_TERTIARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_AUXPCM_RX}, - { AFE_PORT_ID_TERTIARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_TERTIARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_TERT_AUXPCM_TX}, - { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_AUXPCM_RX}, - { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_AUXPCM_TX}, - { AFE_PORT_ID_INT0_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT0_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT0_MI2S_RX}, - { AFE_PORT_ID_INT0_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT0_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT0_MI2S_TX}, - { AFE_PORT_ID_INT1_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT1_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT1_MI2S_RX}, - { AFE_PORT_ID_INT1_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT1_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT1_MI2S_TX}, - { AFE_PORT_ID_INT2_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT2_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT2_MI2S_RX}, - { AFE_PORT_ID_INT2_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT2_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT2_MI2S_TX}, - { AFE_PORT_ID_INT3_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT3_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT3_MI2S_RX}, - { AFE_PORT_ID_INT3_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT3_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT3_MI2S_TX}, - { AFE_PORT_ID_INT4_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT4_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT4_MI2S_RX}, - { AFE_PORT_ID_INT4_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT4_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT4_MI2S_TX}, - { AFE_PORT_ID_INT5_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT5_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT5_MI2S_RX}, - { AFE_PORT_ID_INT5_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT5_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT5_MI2S_TX}, - { AFE_PORT_ID_INT6_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT6_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT6_MI2S_RX}, - { AFE_PORT_ID_INT6_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, + { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT6_MI2S_TX}, - { SLIMBUS_TX_VI, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_TX_VI}, + { SLIMBUS_TX_VI, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_TX_VI}, }; -/* Track ASM playback & capture sessions of DAI */ +/* Track ASM playback & capture sessions of DAI + * Track LSM listen sessions + */ static struct msm_pcm_routing_fdai_data - fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = { + fe_dai_map[MSM_FRONTEND_DAI_MAX][2] = { /* MULTIMEDIA1 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, @@ -575,13 +590,80 @@ static struct msm_pcm_routing_fdai_data /* MULTIMEDIA19 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* CS_VOICE */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOIP */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* AFE_RX */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* AFE_TX */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICE_STUB */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOLTE */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* DTMF_RX */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICE2 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* QCHAT */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOLTE_STUB */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM1 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM2 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM3 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM4 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM5 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM6 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM7 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM8 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICE2_STUB */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOWLAN */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICEMMODE1 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICEMMODE2 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, }; -static unsigned long session_copp_map[MSM_FRONTEND_DAI_MM_SIZE][2] +static unsigned long session_copp_map[MSM_FRONTEND_DAI_MAX][2] [MSM_BACKEND_DAI_MAX]; static struct msm_pcm_routing_app_type_data app_type_cfg[MAX_APP_TYPES]; +static struct msm_pcm_routing_app_type_data lsm_app_type_cfg[MAX_APP_TYPES]; static struct msm_pcm_stream_app_type_cfg - fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MM_SIZE][2]; + fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MAX][2]; /* The caller of this should aqcuire routing lock */ void msm_pcm_routing_get_bedai_info(int be_idx, @@ -624,13 +706,39 @@ static int msm_pcm_routing_get_app_type_idx(int app_type) return 0; } +static int msm_pcm_routing_get_lsm_app_type_idx(int app_type) +{ + int idx; + + pr_debug("%s: app_type: %d\n", __func__, app_type); + for (idx = 0; idx < MAX_APP_TYPES; idx++) { + if (lsm_app_type_cfg[idx].app_type == app_type) + return idx; + } + pr_debug("%s: App type not available, fallback to default\n", __func__); + return 0; +} + +static bool is_mm_lsm_fe_id(int fe_id) +{ + bool rc = true; + + if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID && + ((fe_id < MSM_FRONTEND_DAI_LSM1) || + (fe_id > MSM_FRONTEND_DAI_LSM8))) { + rc = false; + } + return rc; +} + + void msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int app_type, int acdb_dev_id, int sample_rate, int session_type) { pr_debug("%s: fedai_id %d, session_type %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", __func__, fedai_id, session_type, app_type, acdb_dev_id, sample_rate); - if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + if (!is_mm_lsm_fe_id(fedai_id)) { pr_err("%s: Invalid machine driver ID %d\n", __func__, fedai_id); return; @@ -677,7 +785,7 @@ int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int session_type, pr_err("%s: NULL pointer sent for sample rate\n", __func__); ret = -EINVAL; goto done; - } else if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + } else if (!is_mm_lsm_fe_id(fedai_id)) { pr_err("%s: Invalid FE ID %d\n", __func__, fedai_id); ret = -EINVAL; @@ -791,7 +899,8 @@ static uint8_t is_be_dai_extproc(int be_dai) } static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, - int path_type, int perf_mode) + int path_type, int perf_mode, + uint32_t passthr_mode) { int i, port_type, j, num_copps = 0; struct route_payload payload; @@ -804,7 +913,7 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && - (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) { + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { for (j = 0; j < MAX_COPPS_PER_PORT; j++) { unsigned long copp = session_copp_map[fedai_id][sess_type][i]; @@ -827,7 +936,7 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, fe_dai_app_type_cfg[fedai_id][sess_type].acdb_dev_id; payload.sample_rate = fe_dai_app_type_cfg[fedai_id][sess_type].sample_rate; - adm_matrix_map(path_type, payload, perf_mode); + adm_matrix_map(path_type, payload, perf_mode, passthr_mode); msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); } } @@ -861,7 +970,7 @@ void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id, if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && - (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) { + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { mode = afe_get_port_type(msm_bedais[i].port_id); adm_connect_afe_port(mode, dspst_id, msm_bedais[i].port_id); @@ -871,28 +980,51 @@ void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id, mutex_unlock(&routing_lock); } +static bool route_check_fe_id_adm_support(int fe_id) +{ + bool rc = true; + + if ((fe_id >= MSM_FRONTEND_DAI_LSM1) && + (fe_id <= MSM_FRONTEND_DAI_LSM8)) { + /* fe id is listen while port is set to afe */ + if (lsm_port_index != ADM_LSM_PORT_INDEX) { + pr_debug("%s: fe_id %d, lsm mux slim port %d\n", + __func__, fe_id, lsm_port_index); + rc = false; + } + } + + return rc; +} + int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, int dspst_id, int stream_type, - uint32_t compr_passthr_mode) + uint32_t passthr_mode) { int i, j, session_type, path_type, port_type, topology, num_copps = 0; struct route_payload payload; u32 channels, sample_rate; u16 bit_width = 16; + bool is_lsm; pr_debug("%s:fe_id[%d] perf_mode[%d] id[%d] stream_type[%d] passt[%d]", __func__, fe_id, perf_mode, dspst_id, - stream_type, compr_passthr_mode); - - if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + stream_type, passthr_mode); + if (!is_mm_lsm_fe_id(fe_id)) { /* bad ID assigned in machine driver */ pr_err("%s: bad MM ID %d\n", __func__, fe_id); return -EINVAL; } + if (!route_check_fe_id_adm_support(fe_id)) { + /* ignore adm open if not supported for fe_id */ + pr_debug("%s: No ADM support for fe id %d\n", __func__, fe_id); + return 0; + } + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { session_type = SESSION_TYPE_RX; - if (compr_passthr_mode != LEGACY_PCM) + if (passthr_mode != LEGACY_PCM) path_type = ADM_PATH_COMPRESSED_RX; else path_type = ADM_PATH_PLAYBACK; @@ -906,6 +1038,8 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, return -EINVAL; } + is_lsm = (fe_id >= MSM_FRONTEND_DAI_LSM1) && + (fe_id <= MSM_FRONTEND_DAI_LSM8); mutex_lock(&routing_lock); payload.num_copps = 0; /* only RX needs to use payload */ @@ -913,14 +1047,14 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, /* re-enable EQ if active */ msm_qti_pp_send_eq_values(fe_id); for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { - if (test_bit(fe_id, &msm_bedais[i].fe_sessions)) - msm_bedais[i].compr_passthr_mode = compr_passthr_mode; + if (test_bit(fe_id, &msm_bedais[i].fe_sessions[0])) + msm_bedais[i].passthr_mode = passthr_mode; if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && - (test_bit(fe_id, &msm_bedais[i].fe_sessions))) { + (test_bit(fe_id, &msm_bedais[i].fe_sessions[0]))) { int app_type, app_type_idx, copp_idx, acdb_dev_id; /* @@ -936,7 +1070,15 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, msm_bedais[i].format); app_type = fe_dai_app_type_cfg[fe_id][session_type].app_type; - if (app_type) { + if (app_type && is_lsm) { + app_type_idx = + msm_pcm_routing_get_lsm_app_type_idx(app_type); + sample_rate = + fe_dai_app_type_cfg[fe_id][session_type]. + sample_rate; + bit_width = + lsm_app_type_cfg[app_type_idx].bit_width; + } else if (app_type) { app_type_idx = msm_pcm_routing_get_app_type_idx( app_type); @@ -951,9 +1093,10 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, fe_dai_app_type_cfg[fe_id][session_type].acdb_dev_id; topology = msm_routing_get_adm_topology(path_type, fe_id, session_type); - if (compr_passthr_mode == COMPRESSED_PASSTHROUGH_DSD) + + if (passthr_mode == COMPRESSED_PASSTHROUGH_DSD) topology = COMPRESS_PASSTHROUGH_NONE_TOPOLOGY; - pr_err("%s: Before adm open topology %d\n", __func__, + pr_debug("%s: Before adm open topology %d\n", __func__, topology); copp_idx = @@ -990,7 +1133,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, num_copps++; } } - if (compr_passthr_mode != COMPRESSED_PASSTHROUGH_DSD) { + if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD) { msm_routing_send_device_pp_params( msm_bedais[i].port_id, copp_idx); @@ -1004,7 +1147,9 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, fe_dai_app_type_cfg[fe_id][session_type].app_type; payload.acdb_dev_id = fe_dai_app_type_cfg[fe_id][session_type].acdb_dev_id; - adm_matrix_map(path_type, payload, perf_mode); + payload.sample_rate = + fe_dai_app_type_cfg[fe_id][session_type].sample_rate; + adm_matrix_map(path_type, payload, perf_mode, passthr_mode); msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); } mutex_unlock(&routing_lock); @@ -1055,6 +1200,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, struct route_payload payload; u32 channels, sample_rate; uint16_t bits_per_sample = 16; + uint32_t passthr_mode = LEGACY_PCM; if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) { /* bad ID assigned in machine driver */ @@ -1084,7 +1230,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && - (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) { + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { int app_type, app_type_idx, copp_idx, acdb_dev_id; /* * check if ADM needs to be configured with different @@ -1094,7 +1240,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, channels = msm_bedais[i].channel; else channels = msm_bedais[i].adm_override_ch; - msm_bedais[i].compr_passthr_mode = + msm_bedais[i].passthr_mode = LEGACY_PCM; bits_per_sample = msm_routing_get_bit_width( @@ -1151,7 +1297,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, } } if ((perf_mode == LEGACY_PCM_MODE) && - (msm_bedais[i].compr_passthr_mode == + (msm_bedais[i].passthr_mode == LEGACY_PCM)) msm_pcm_routing_cfg_pp(msm_bedais[i].port_id, copp_idx, topology, @@ -1167,7 +1313,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id; payload.sample_rate = fe_dai_app_type_cfg[fedai_id][session_type].sample_rate; - adm_matrix_map(path_type, payload, perf_mode); + adm_matrix_map(path_type, payload, perf_mode, passthr_mode); msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); } mutex_unlock(&routing_lock); @@ -1196,7 +1342,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) int i, port_type, session_type, path_type, topology; struct msm_pcm_routing_fdai_data *fdai; - if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + if (!is_mm_lsm_fe_id(fedai_id)) { /* bad ID assigned in machine driver */ pr_err("%s: bad MM ID\n", __func__); return; @@ -1217,7 +1363,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && - (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) { + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { int idx; unsigned long copp = session_copp_map[fedai_id][session_type][i]; @@ -1242,7 +1388,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology || DS2_ADM_COPP_TOPOLOGY_ID == topology) && (fdai->perf_mode == LEGACY_PCM_MODE) && - (msm_bedais[i].compr_passthr_mode == + (msm_bedais[i].passthr_mode == LEGACY_PCM)) msm_pcm_routing_deinit_pp(msm_bedais[i].port_id, topology); @@ -1259,13 +1405,13 @@ static bool msm_pcm_routing_route_is_set(u16 be_id, u16 fe_id) { bool rc = false; - if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + if (!is_mm_lsm_fe_id(fe_id)) { /* recheck FE ID in the mixer control defined in this file */ pr_err("%s: bad MM ID\n", __func__); return rc; } - if (test_bit(fe_id, &msm_bedais[be_id].fe_sessions)) + if (test_bit(fe_id, &msm_bedais[be_id].fe_sessions[0])) rc = true; return rc; @@ -1277,19 +1423,27 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) u32 channels, sample_rate; uint16_t bits_per_sample = 16; struct msm_pcm_routing_fdai_data *fdai; + uint32_t passthr_mode = msm_bedais[reg].passthr_mode; + bool is_lsm; pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set); - if (val > MSM_FRONTEND_DAI_MM_MAX_ID) { + if (!is_mm_lsm_fe_id(val)) { /* recheck FE ID in the mixer control defined in this file */ pr_err("%s: bad MM ID\n", __func__); return; } + if (!route_check_fe_id_adm_support(val)) { + /* ignore adm open if not supported for fe_id */ + pr_debug("%s: No ADM support for fe id %d\n", __func__, val); + return; + } + if (afe_get_port_type(msm_bedais[reg].port_id) == MSM_AFE_PORT_TYPE_RX) { session_type = SESSION_TYPE_RX; - if (msm_bedais[reg].compr_passthr_mode != LEGACY_PCM) + if (passthr_mode != LEGACY_PCM) path_type = ADM_PATH_COMPRESSED_RX; else path_type = ADM_PATH_PLAYBACK; @@ -1297,15 +1451,17 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) session_type = SESSION_TYPE_TX; path_type = ADM_PATH_LIVE_REC; } + is_lsm = (val >= MSM_FRONTEND_DAI_LSM1) && + (val <= MSM_FRONTEND_DAI_LSM8); mutex_lock(&routing_lock); if (set) { - if (!test_bit(val, &msm_bedais[reg].fe_sessions) && + if (!test_bit(val, &msm_bedais[reg].fe_sessions[0]) && ((msm_bedais[reg].port_id == VOICE_PLAYBACK_TX) || (msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX))) voc_start_playback(set, msm_bedais[reg].port_id); - set_bit(val, &msm_bedais[reg].fe_sessions); + set_bit(val, &msm_bedais[reg].fe_sessions[0]); fdai = &fe_dai_map[val][session_type]; if (msm_bedais[reg].active && fdai->strm_id != INVALID_SESSION) { @@ -1336,7 +1492,15 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) app_type = fe_dai_app_type_cfg[val][session_type].app_type; - if (app_type) { + if (app_type && is_lsm) { + app_type_idx = + msm_pcm_routing_get_lsm_app_type_idx(app_type); + sample_rate = + fe_dai_app_type_cfg[val][session_type]. + sample_rate; + bits_per_sample = + lsm_app_type_cfg[app_type_idx].bit_width; + } else if (app_type) { app_type_idx = msm_pcm_routing_get_app_type_idx(app_type); sample_rate = @@ -1381,20 +1545,20 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) msm_pcm_routing_build_matrix(val, session_type, path_type, - fdai->perf_mode); + fdai->perf_mode, + passthr_mode); if ((fdai->perf_mode == LEGACY_PCM_MODE) && - (msm_bedais[reg].compr_passthr_mode == - LEGACY_PCM)) + (passthr_mode == LEGACY_PCM)) msm_pcm_routing_cfg_pp(msm_bedais[reg].port_id, copp_idx, topology, channels); } } else { - if (test_bit(val, &msm_bedais[reg].fe_sessions) && + if (test_bit(val, &msm_bedais[reg].fe_sessions[0]) && ((msm_bedais[reg].port_id == VOICE_PLAYBACK_TX) || (msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX))) voc_start_playback(set, msm_bedais[reg].port_id); - clear_bit(val, &msm_bedais[reg].fe_sessions); + clear_bit(val, &msm_bedais[reg].fe_sessions[0]); fdai = &fe_dai_map[val][session_type]; if (msm_bedais[reg].active && fdai->strm_id != INVALID_SESSION) { @@ -1419,14 +1583,14 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology || DS2_ADM_COPP_TOPOLOGY_ID == topology) && (fdai->perf_mode == LEGACY_PCM_MODE) && - (msm_bedais[reg].compr_passthr_mode == - LEGACY_PCM)) + (passthr_mode == LEGACY_PCM)) msm_pcm_routing_deinit_pp( msm_bedais[reg].port_id, topology); msm_pcm_routing_build_matrix(val, session_type, path_type, - fdai->perf_mode); + fdai->perf_mode, + passthr_mode); } } if ((msm_bedais[reg].port_id == VOICE_RECORD_RX) @@ -1442,7 +1606,7 @@ static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions)) + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; @@ -1476,6 +1640,51 @@ static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol, return 1; } +static int msm_routing_get_listen_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_routing_put_listen_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + if (ucontrol->value.integer.value[0]) { + if (msm_pcm_routing_route_is_set(mc->reg, mc->shift) == false) + msm_pcm_routing_process_audio(mc->reg, mc->shift, 1); + snd_soc_dapm_mixer_update_power(widget->dapm, + kcontrol, 1, update); + } else if (!ucontrol->value.integer.value[0]) { + if (msm_pcm_routing_route_is_set(mc->reg, mc->shift) == true) + msm_pcm_routing_process_audio(mc->reg, mc->shift, 0); + snd_soc_dapm_mixer_update_power(widget->dapm, + kcontrol, 0, update); + } + + return 1; +} + static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set) { u32 session_id = 0; @@ -1492,9 +1701,9 @@ static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set) mutex_lock(&routing_lock); if (set) - set_bit(val, &msm_bedais[reg].fe_sessions); + set_bit(val, &msm_bedais[reg].fe_sessions[0]); else - clear_bit(val, &msm_bedais[reg].fe_sessions); + clear_bit(val, &msm_bedais[reg].fe_sessions[0]); if (val == MSM_FRONTEND_DAI_DTMF_RX && afe_get_port_type(msm_bedais[reg].port_id) == @@ -1553,7 +1762,7 @@ static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol, mutex_lock(&routing_lock); - if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions)) + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; @@ -1595,7 +1804,7 @@ static int msm_routing_get_voice_stub_mixer(struct snd_kcontrol *kcontrol, mutex_lock(&routing_lock); - if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions)) + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; @@ -1620,13 +1829,13 @@ static int msm_routing_put_voice_stub_mixer(struct snd_kcontrol *kcontrol, if (ucontrol->value.integer.value[0]) { mutex_lock(&routing_lock); - set_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions); + set_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]); mutex_unlock(&routing_lock); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, update); } else { mutex_lock(&routing_lock); - clear_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions); + clear_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]); mutex_unlock(&routing_lock); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, update); @@ -1928,23 +2137,19 @@ static int msm_routing_put_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, return 1; } -static int msm_routing_lsm_mux_get(struct snd_kcontrol *kcontrol, +static int msm_routing_lsm_port_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - ucontrol->value.integer.value[0] = lsm_mux_slim_port; + ucontrol->value.integer.value[0] = lsm_port_index; return 0; } -static int msm_routing_lsm_mux_put(struct snd_kcontrol *kcontrol, +static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int mux = ucontrol->value.enumerated.item[0]; int lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX; - struct snd_soc_dapm_update *update = NULL; if (mux >= e->items) { pr_err("%s: Invalid mux value %d\n", __func__, mux); @@ -1975,19 +2180,18 @@ static int msm_routing_lsm_mux_put(struct snd_kcontrol *kcontrol, case 7: lsm_port = AFE_PORT_ID_TERTIARY_MI2S_TX; break; + case 8: + lsm_port = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case 9: + lsm_port = ADM_LSM_PORT_ID; + break; default: pr_err("Default lsm port"); break; } set_lsm_port(lsm_port); - - if (ucontrol->value.integer.value[0]) { - lsm_mux_slim_port = ucontrol->value.integer.value[0]; - snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e, update); - } else { - snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e, update); - lsm_mux_slim_port = ucontrol->value.integer.value[0]; - } + lsm_port_index = ucontrol->value.integer.value[0]; return 0; } @@ -2000,23 +2204,27 @@ static int msm_routing_lsm_func_get(struct snd_kcontrol *kcontrol, enum afe_mad_type mad_type; pr_debug("%s: enter\n", __func__); - for (i = 0; i < ARRAY_SIZE(mad_audio_mux_text); i++) - if (!strncmp(kcontrol->id.name, mad_audio_mux_text[i], - strlen(mad_audio_mux_text[i]))) + for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++) + if (!strnstr(kcontrol->id.name, lsm_port_text[i], + strlen(lsm_port_text[i]))) break; - if (i-- == ARRAY_SIZE(mad_audio_mux_text)) { + if (i-- == ARRAY_SIZE(lsm_port_text)) { WARN(1, "Invalid id name %s\n", kcontrol->id.name); return -EINVAL; } /*Check for Tertiary TX port*/ - if (!strcmp(kcontrol->id.name, mad_audio_mux_text[7])) { + if (!strcmp(kcontrol->id.name, lsm_port_text[7])) { ucontrol->value.integer.value[0] = MADSWAUDIO; return 0; } port_id = i * 2 + 1 + SLIMBUS_0_RX; + + if (!strcmp(kcontrol->id.name, lsm_port_text[8])) + port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + mad_type = afe_port_get_mad_type(port_id); pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); @@ -2051,12 +2259,12 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, enum afe_mad_type mad_type; pr_debug("%s: enter\n", __func__); - for (i = 0; i < ARRAY_SIZE(mad_audio_mux_text); i++) - if (!strncmp(kcontrol->id.name, mad_audio_mux_text[i], - strlen(mad_audio_mux_text[i]))) + for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++) + if (strnstr(kcontrol->id.name, lsm_port_text[i], + strlen(lsm_port_text[i]))) break; - if (i-- == ARRAY_SIZE(mad_audio_mux_text)) { + if (i-- == ARRAY_SIZE(lsm_port_text)) { WARN(1, "Invalid id name %s\n", kcontrol->id.name); return -EINVAL; } @@ -2084,11 +2292,16 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, } /*Check for Tertiary TX port*/ - if (!strcmp(kcontrol->id.name, mad_audio_mux_text[7])) { + if (strnstr(kcontrol->id.name, lsm_port_text[7], + strlen(lsm_port_text[7]))) { port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; mad_type = MAD_SW_AUDIO; } + if (strnstr(kcontrol->id.name, lsm_port_text[8], + strlen(lsm_port_text[8]))) + port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); return afe_port_set_mad_type(port_id, mad_type); @@ -2253,6 +2466,144 @@ static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol, return 1; } +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 const char *const ec_ref_ch_text[] = {"Zero", "One", "Two", "Three", + "Four", "Five", "Six", "Seven", "Eight"}; + +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) +{ + u16 bit_width = 0; + + 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; + } + + if (msm_ec_ref_bit_format == SNDRV_PCM_FORMAT_S16_LE) + bit_width = 16; + else if (msm_ec_ref_bit_format == SNDRV_PCM_FORMAT_S24_LE) + bit_width = 24; + + pr_debug("%s: msm_ec_ref_bit_format = %d\n", + __func__, msm_ec_ref_bit_format); + adm_ec_ref_rx_bit_width(bit_width); + return 0; +} + +static char const *ec_ref_bit_format_text[] = {"0", "S16_LE", "S24_LE"}; + +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 = 8000; + break; + case 2: + msm_ec_ref_sampling_rate = 16000; + break; + case 3: + msm_ec_ref_sampling_rate = 32000; + break; + case 4: + msm_ec_ref_sampling_rate = 44100; + break; + case 5: + msm_ec_ref_sampling_rate = 48000; + break; + case 6: + msm_ec_ref_sampling_rate = 96000; + break; + case 7: + msm_ec_ref_sampling_rate = 192000; + break; + case 8: + msm_ec_ref_sampling_rate = 384000; + break; + default: + msm_ec_ref_sampling_rate = 48000; + 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 const char *const ec_ref_rate_text[] = {"0", "8000", "16000", + "32000", "44100", "48000", "96000", "192000", "384000"}; + +static const struct soc_enum msm_route_ec_ref_params_enum[] = { + 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 ec_ref_param_controls[] = { + SOC_ENUM_EXT("EC Reference Channels", msm_route_ec_ref_params_enum[0], + msm_ec_ref_ch_get, msm_ec_ref_ch_put), + SOC_ENUM_EXT("EC Reference Bit Format", msm_route_ec_ref_params_enum[1], + msm_ec_ref_bit_format_get, msm_ec_ref_bit_format_put), + SOC_ENUM_EXT("EC Reference SampleRate", msm_route_ec_ref_params_enum[2], + msm_ec_ref_rate_get, msm_ec_ref_rate_put), +}; + static int msm_routing_ec_ref_rx_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -4164,6 +4515,159 @@ static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, @@ -4266,6 +4770,159 @@ static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, @@ -4894,6 +5551,30 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -4966,6 +5647,30 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -5038,6 +5743,30 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = { SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -5089,6 +5818,30 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = { SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -5170,6 +5923,30 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -5248,6 +6025,30 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -5317,6 +6118,30 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -7146,6 +7971,542 @@ static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, @@ -7721,6 +9082,198 @@ static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new lsm1_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm2_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm3_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm4_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm5_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm6_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm7_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm8_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, msm_routing_get_switch_mixer, @@ -7806,53 +9359,17 @@ static const struct snd_kcontrol_new usb_switch_mixer_controls = 0, 1, 0, msm_routing_get_usb_switch_mixer, msm_routing_put_usb_switch_mixer); -static const struct soc_enum lsm_mux_enum = - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mad_audio_mux_text), mad_audio_mux_text); - -static const struct snd_kcontrol_new lsm1_mux = - SOC_DAPM_ENUM_EXT("LSM1 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); - -static const struct snd_kcontrol_new lsm2_mux = - SOC_DAPM_ENUM_EXT("LSM2 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); -static const struct snd_kcontrol_new lsm3_mux = - SOC_DAPM_ENUM_EXT("LSM3 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); - -static const struct snd_kcontrol_new lsm4_mux = - SOC_DAPM_ENUM_EXT("LSM4 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); -static const struct snd_kcontrol_new lsm5_mux = - SOC_DAPM_ENUM_EXT("LSM5 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); - -static const struct snd_kcontrol_new lsm6_mux = - SOC_DAPM_ENUM_EXT("LSM6 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); -static const struct snd_kcontrol_new lsm7_mux = - SOC_DAPM_ENUM_EXT("LSM7 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); - -static const struct snd_kcontrol_new lsm8_mux = - SOC_DAPM_ENUM_EXT("LSM8 MUX", lsm_mux_enum, - msm_routing_lsm_mux_get, - msm_routing_lsm_mux_put); - +static const struct soc_enum lsm_port_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); static const char * const lsm_func_text[] = { "None", "AUDIO", "BEACON", "ULTRASOUND", "SWAUDIO", }; static const struct soc_enum lsm_func_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_func_text), lsm_func_text); -static const struct snd_kcontrol_new lsm_function[] = { + +static const struct snd_kcontrol_new lsm_controls[] = { + /* kcontrol of lsm_function */ SOC_ENUM_EXT(SLIMBUS_0_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, msm_routing_lsm_func_get, msm_routing_lsm_func_put), SOC_ENUM_EXT(SLIMBUS_1_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, @@ -7867,6 +9384,33 @@ static const struct snd_kcontrol_new lsm_function[] = { msm_routing_lsm_func_get, msm_routing_lsm_func_put), SOC_ENUM_EXT(TERT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(QUAT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + /* kcontrol of lsm_port */ + SOC_ENUM_EXT("LSM1 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM2 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM3 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM4 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM5 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM6 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM7 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM8 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), }; static const char * const aanc_slim_0_rx_text[] = { @@ -7923,7 +9467,7 @@ static int msm_routing_put_stereo_to_custom_stereo_control( (port_id != AFE_PORT_ID_INT4_MI2S_RX)) continue; - for_each_set_bit(i, &msm_bedais[be_index].fe_sessions, + for_each_set_bit(i, &msm_bedais[be_index].fe_sessions[0], MSM_FRONTEND_DAI_MM_SIZE) { if (fe_dai_map[i][SESSION_TYPE_RX].perf_mode != LEGACY_PCM_MODE) @@ -8029,6 +9573,45 @@ static const struct snd_kcontrol_new app_type_cfg_controls[] = { msm_routing_put_app_type_cfg_control), }; +static int msm_routing_get_lsm_app_type_cfg_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int msm_routing_put_lsm_app_type_cfg_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i = 0, j; + int num_app_types = ucontrol->value.integer.value[i++]; + + memset(lsm_app_type_cfg, 0, MAX_APP_TYPES* + sizeof(struct msm_pcm_routing_app_type_data)); + if (num_app_types > MAX_APP_TYPES) { + pr_err("%s: number of app types exceed the max supported\n", + __func__); + return -EINVAL; + } + for (j = 0; j < num_app_types; j++) { + lsm_app_type_cfg[j].app_type = + ucontrol->value.integer.value[i++]; + lsm_app_type_cfg[j].sample_rate = + ucontrol->value.integer.value[i++]; + lsm_app_type_cfg[j].bit_width = + ucontrol->value.integer.value[i++]; + } + + return 0; +} + +static const struct snd_kcontrol_new lsm_app_type_cfg_controls[] = { + SOC_SINGLE_MULTI_EXT("Listen App Type Config", SND_SOC_NOPM, 0, + 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, + msm_routing_put_lsm_app_type_cfg_control), +}; + static int msm_routing_get_use_ds1_or_ds2_control( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -8224,7 +9807,7 @@ static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, goto done; } - for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions, + for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], MSM_FRONTEND_DAI_MM_SIZE) { for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { copp = session_copp_map[i] @@ -9298,16 +10881,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0, &usb_switch_mixer_controls), - /* Mux Definitions */ - SND_SOC_DAPM_MUX("LSM1 MUX", SND_SOC_NOPM, 0, 0, &lsm1_mux), - SND_SOC_DAPM_MUX("LSM2 MUX", SND_SOC_NOPM, 0, 0, &lsm2_mux), - SND_SOC_DAPM_MUX("LSM3 MUX", SND_SOC_NOPM, 0, 0, &lsm3_mux), - SND_SOC_DAPM_MUX("LSM4 MUX", SND_SOC_NOPM, 0, 0, &lsm4_mux), - SND_SOC_DAPM_MUX("LSM5 MUX", SND_SOC_NOPM, 0, 0, &lsm5_mux), - SND_SOC_DAPM_MUX("LSM6 MUX", SND_SOC_NOPM, 0, 0, &lsm6_mux), - SND_SOC_DAPM_MUX("LSM7 MUX", SND_SOC_NOPM, 0, 0, &lsm7_mux), - SND_SOC_DAPM_MUX("LSM8 MUX", SND_SOC_NOPM, 0, 0, &lsm8_mux), - /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)), @@ -9356,12 +10929,30 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, pri_tdm_rx_0_mixer_controls, ARRAY_SIZE(pri_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_1_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_2_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_3_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_3_mixer_controls)), SND_SOC_DAPM_MIXER("PRI_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, pri_tdm_tx_0_mixer_controls, ARRAY_SIZE(pri_tdm_tx_0_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, sec_tdm_rx_0_mixer_controls, ARRAY_SIZE(sec_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_1_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_2_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_3_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_3_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, sec_tdm_tx_0_mixer_controls, ARRAY_SIZE(sec_tdm_tx_0_mixer_controls)), @@ -9626,6 +11217,30 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, quat_mi2s_rx_port_mixer_controls, ARRAY_SIZE(quat_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_0_port_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_1_port_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_2 Port Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_2_port_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_2_port_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_3_port_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_3_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_0_port_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_1_port_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Port Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_2_port_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_2_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_3_port_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_3_port_mixer_controls)), SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, tert_tdm_rx_0_port_mixer_controls, ARRAY_SIZE(tert_tdm_rx_0_port_mixer_controls)), @@ -9665,6 +11280,23 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("USB_AUDIO_RX Port Mixer", SND_SOC_NOPM, 0, 0, usb_rx_port_mixer_controls, ARRAY_SIZE(usb_rx_port_mixer_controls)), + /* lsm mixer definitions */ + SND_SOC_DAPM_MIXER("LSM1 Mixer", SND_SOC_NOPM, 0, 0, + lsm1_mixer_controls, ARRAY_SIZE(lsm1_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM2 Mixer", SND_SOC_NOPM, 0, 0, + lsm2_mixer_controls, ARRAY_SIZE(lsm2_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM3 Mixer", SND_SOC_NOPM, 0, 0, + lsm3_mixer_controls, ARRAY_SIZE(lsm3_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM4 Mixer", SND_SOC_NOPM, 0, 0, + lsm4_mixer_controls, ARRAY_SIZE(lsm4_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM5 Mixer", SND_SOC_NOPM, 0, 0, + lsm5_mixer_controls, ARRAY_SIZE(lsm5_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM6 Mixer", SND_SOC_NOPM, 0, 0, + lsm6_mixer_controls, ARRAY_SIZE(lsm6_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM7 Mixer", SND_SOC_NOPM, 0, 0, + lsm7_mixer_controls, ARRAY_SIZE(lsm7_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM8 Mixer", SND_SOC_NOPM, 0, 0, + lsm8_mixer_controls, ARRAY_SIZE(lsm8_mixer_controls)), /* Virtual Pins to force backends ON atm */ SND_SOC_DAPM_OUTPUT("BE_OUT"), SND_SOC_DAPM_INPUT("BE_IN"), @@ -10109,6 +11741,60 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"}, + + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"}, + + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -10145,6 +11831,60 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"}, + + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"}, + + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -10392,6 +12132,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, {"MultiMedia1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia1 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, {"MultiMedia1 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, @@ -10401,6 +12149,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, {"MultiMedia2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia2 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, {"MultiMedia2 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, @@ -10410,6 +12166,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, {"MultiMedia3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia3 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, {"MultiMedia3 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, @@ -10419,6 +12183,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, {"MultiMedia4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia4 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, {"MultiMedia4 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, @@ -10428,6 +12200,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia4 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia4 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, {"MultiMedia5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia5 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, {"MultiMedia5 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, @@ -10437,6 +12217,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, {"MultiMedia6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia6 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, {"MultiMedia6 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, @@ -10446,6 +12234,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, {"MultiMedia8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia8 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, {"MultiMedia8 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, @@ -11124,70 +12920,77 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM4_UL_HL", NULL, "SLIMBUS_4_TX"}, {"SLIM8_UL_HL", NULL, "SLIMBUS_8_TX"}, - {"LSM1 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM1 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM1 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM1 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM1 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM1_UL_HL", NULL, "LSM1 MUX"}, - - {"LSM2 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM2 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM2 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM2 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM2 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM2 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM2_UL_HL", NULL, "LSM2 MUX"}, - - - {"LSM3 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM3 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM3 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM3 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM3 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM3 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM3_UL_HL", NULL, "LSM3 MUX"}, - - - {"LSM4 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM4 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM4 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM4 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM4 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM4 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM4_UL_HL", NULL, "LSM4 MUX"}, - - {"LSM5 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM5 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM5 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM5 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM5 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM5 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM5_UL_HL", NULL, "LSM5 MUX"}, - - {"LSM6 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM6 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM6 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM6 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM6 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM6_UL_HL", NULL, "LSM6 MUX"}, - - - {"LSM7 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM7 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM7 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM7 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM7 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM7_UL_HL", NULL, "LSM7 MUX"}, - - - {"LSM8 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM8 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM8 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM8 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM8 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM8_UL_HL", NULL, "LSM8 MUX"}, + + {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM1 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM1 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, + + {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM2 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM2 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM2 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM2 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, + + + {"LSM3 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM3 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM3 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM3 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM3 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, + + + {"LSM4 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM4 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM4 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM4 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM4 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, + + {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM5 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM5 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM5 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM5 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, + + {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM6 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM6 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM6 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM6 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, + + {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM7 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM7 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM7 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM7 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, + + {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM8 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM8 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM8 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM8 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, {"CPE_LSM_UL_HL", NULL, "BE_IN"}, @@ -11251,17 +13054,29 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_MI2S_UL_HL", NULL, "QUAT_MI2S_TX"}, {"PRI_TDM_TX_0_UL_HL", NULL, "PRI_TDM_TX_0"}, + {"PRI_TDM_TX_1_UL_HL", NULL, "PRI_TDM_TX_1"}, + {"PRI_TDM_TX_2_UL_HL", NULL, "PRI_TDM_TX_2"}, + {"PRI_TDM_TX_3_UL_HL", NULL, "PRI_TDM_TX_3"}, {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_DL_HL"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_DL_HL"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_DL_HL"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_DL_HL"}, {"SEC_TDM_TX_0_UL_HL", NULL, "SEC_TDM_TX_0"}, + {"SEC_TDM_TX_1_UL_HL", NULL, "SEC_TDM_TX_1"}, + {"SEC_TDM_TX_2_UL_HL", NULL, "SEC_TDM_TX_2"}, + {"SEC_TDM_TX_3_UL_HL", NULL, "SEC_TDM_TX_3"}, {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0_DL_HL"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1_DL_HL"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2_DL_HL"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3_DL_HL"}, {"TERT_TDM_TX_0_UL_HL", NULL, "TERT_TDM_TX_0"}, {"TERT_TDM_TX_1_UL_HL", NULL, "TERT_TDM_TX_1"}, {"TERT_TDM_TX_2_UL_HL", NULL, "TERT_TDM_TX_2"}, {"TERT_TDM_TX_3_UL_HL", NULL, "TERT_TDM_TX_3"}, {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0_DL_HL"}, - {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_0_DL_HL"}, - {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_0_DL_HL"}, - {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_0_DL_HL"}, + {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1_DL_HL"}, + {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2_DL_HL"}, + {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3_DL_HL"}, {"QUAT_TDM_TX_0_UL_HL", NULL, "QUAT_TDM_TX_0"}, {"QUAT_TDM_TX_1_UL_HL", NULL, "QUAT_TDM_TX_1"}, {"QUAT_TDM_TX_2_UL_HL", NULL, "QUAT_TDM_TX_2"}, @@ -11271,6 +13086,150 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_DL_HL"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3_DL_HL"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Port Mixer"}, + + {"PRI_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Port Mixer"}, + + {"PRI_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Port Mixer"}, + + {"PRI_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Port Mixer"}, + + {"SEC_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Port Mixer"}, + + {"SEC_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Port Mixer"}, + + {"SEC_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Port Mixer"}, + + {"SEC_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Port Mixer"}, + {"TERT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"TERT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"TERT_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, @@ -11690,7 +13649,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "VOICE_PLAYBACK_TX"}, {"BE_OUT", NULL, "VOICE2_PLAYBACK_TX"}, {"BE_OUT", NULL, "PRI_TDM_RX_0"}, + {"BE_OUT", NULL, "PRI_TDM_RX_1"}, + {"BE_OUT", NULL, "PRI_TDM_RX_2"}, + {"BE_OUT", NULL, "PRI_TDM_RX_3"}, {"BE_OUT", NULL, "SEC_TDM_RX_0"}, + {"BE_OUT", NULL, "SEC_TDM_RX_1"}, + {"BE_OUT", NULL, "SEC_TDM_RX_2"}, + {"BE_OUT", NULL, "SEC_TDM_RX_3"}, {"BE_OUT", NULL, "TERT_TDM_RX_0"}, {"BE_OUT", NULL, "TERT_TDM_RX_1"}, {"BE_OUT", NULL, "TERT_TDM_RX_2"}, @@ -11746,7 +13711,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_MONO_CH_MUX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_STEREO_CH_MUX"}, {"PRI_TDM_TX_0", NULL, "BE_IN"}, + {"PRI_TDM_TX_1", NULL, "BE_IN"}, + {"PRI_TDM_TX_2", NULL, "BE_IN"}, + {"PRI_TDM_TX_3", NULL, "BE_IN"}, {"SEC_TDM_TX_0", NULL, "BE_IN"}, + {"SEC_TDM_TX_1", NULL, "BE_IN"}, + {"SEC_TDM_TX_2", NULL, "BE_IN"}, + {"SEC_TDM_TX_3", NULL, "BE_IN"}, {"TERT_TDM_TX_0", NULL, "BE_IN"}, {"TERT_TDM_TX_1", NULL, "BE_IN"}, {"TERT_TDM_TX_2", NULL, "BE_IN"}, @@ -11804,7 +13775,9 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream) path_type = ADM_PATH_LIVE_REC; mutex_lock(&routing_lock); - for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) { + for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) { + if (!is_mm_lsm_fe_id(i)) + continue; fdai = &fe_dai_map[i][session_type]; if (fdai->strm_id != INVALID_SESSION) { int idx; @@ -11825,13 +13798,12 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream) clear_bit(idx, &session_copp_map[i][session_type][be_id]); if ((fdai->perf_mode == LEGACY_PCM_MODE) && - (bedai->compr_passthr_mode == LEGACY_PCM)) + (bedai->passthr_mode == LEGACY_PCM)) msm_pcm_routing_deinit_pp(bedai->port_id, topology); } } - bedai->compr_passthr_mode = LEGACY_PCM; bedai->active = 0; bedai->sample_rate = 0; bedai->channel = 0; @@ -11851,6 +13823,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) struct msm_pcm_routing_fdai_data *fdai; u32 session_id; struct media_format_info voc_be_media_format; + bool is_lsm; pr_debug("%s: substream->pcm->id:%s\n", __func__, substream->pcm->id); @@ -11863,7 +13836,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) bedai = &msm_bedais[be_id]; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (bedai->compr_passthr_mode != LEGACY_PCM) + if (bedai->passthr_mode != LEGACY_PCM) path_type = ADM_PATH_COMPRESSED_RX; else path_type = ADM_PATH_PLAYBACK; @@ -11884,7 +13857,13 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) */ bedai->active = 1; - for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) { + for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) { + if (!(is_mm_lsm_fe_id(i) && + route_check_fe_id_adm_support(i))) + continue; + + is_lsm = (i >= MSM_FRONTEND_DAI_LSM1) && + (i <= MSM_FRONTEND_DAI_LSM8); fdai = &fe_dai_map[i][session_type]; if (fdai->strm_id != INVALID_SESSION) { int app_type, app_type_idx, copp_idx, acdb_dev_id; @@ -11906,7 +13885,15 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) app_type = fe_dai_app_type_cfg[i][session_type].app_type; - if (app_type) { + if (app_type && is_lsm) { + app_type_idx = + msm_pcm_routing_get_lsm_app_type_idx(app_type); + sample_rate = + fe_dai_app_type_cfg[i][session_type]. + sample_rate; + bits_per_sample = + lsm_app_type_cfg[app_type_idx].bit_width; + } else if (app_type) { app_type_idx = msm_pcm_routing_get_app_type_idx(app_type); sample_rate = @@ -11951,16 +13938,16 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) bedai->sample_rate); msm_pcm_routing_build_matrix(i, session_type, path_type, - fdai->perf_mode); + fdai->perf_mode, + bedai->passthr_mode); if ((fdai->perf_mode == LEGACY_PCM_MODE) && - (bedai->compr_passthr_mode == - LEGACY_PCM)) + (bedai->passthr_mode == LEGACY_PCM)) msm_pcm_routing_cfg_pp(bedai->port_id, copp_idx, topology, channels); } } - for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MAX) { + for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) { session_id = msm_pcm_routing_get_voc_sessionid(i); if (session_id) { pr_debug("%s voice session_id: 0x%x\n", __func__, @@ -12025,6 +14012,7 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx) unsigned long pp_config = 0; bool mute_on; int latency; + bool compr_passthr_mode = true; pr_debug("%s: port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); @@ -12061,14 +14049,16 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx) return -EINVAL; } + if ((msm_bedais[be_idx].passthr_mode == LEGACY_PCM) || + (msm_bedais[be_idx].passthr_mode == LISTEN)) + compr_passthr_mode = false; + pp_config = msm_bedais_pp_params[index].pp_params_config; if (test_bit(ADM_PP_PARAM_MUTE_BIT, &pp_config)) { pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__); clear_bit(ADM_PP_PARAM_MUTE_BIT, &pp_config); mute_on = msm_bedais_pp_params[index].mute_on; - if ((msm_bedais[be_idx].active) && - (msm_bedais[be_idx].compr_passthr_mode != - LEGACY_PCM)) + if ((msm_bedais[be_idx].active) && compr_passthr_mode) adm_send_compressed_device_mute(port_id, copp_idx, mute_on); @@ -12078,9 +14068,7 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx) clear_bit(ADM_PP_PARAM_LATENCY_BIT, &pp_config); latency = msm_bedais_pp_params[index].latency; - if ((msm_bedais[be_idx].active) && - (msm_bedais[be_idx].compr_passthr_mode != - LEGACY_PCM)) + if ((msm_bedais[be_idx].active) && compr_passthr_mode) adm_send_compressed_device_latency(port_id, copp_idx, latency); @@ -12096,6 +14084,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, int index, be_idx, i, topo_id, idx; bool mute; int latency; + bool compr_passthr_mode = true; pr_debug("%s: pp_id: 0x%x\n", __func__, pp_id); @@ -12120,7 +14109,11 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, return -EINVAL; } - for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions, + if ((msm_bedais[be_idx].passthr_mode == LEGACY_PCM) || + (msm_bedais[be_idx].passthr_mode == LISTEN)) + compr_passthr_mode = false; + + for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], MSM_FRONTEND_DAI_MM_SIZE) { for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { unsigned long copp = @@ -12134,7 +14127,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, continue; pr_debug("%s: port: 0x%x, copp %ld, be active: %d, passt: %d\n", __func__, port_id, copp, msm_bedais[be_idx].active, - msm_bedais[be_idx].compr_passthr_mode); + msm_bedais[be_idx].passthr_mode); switch (pp_id) { case ADM_PP_PARAM_MUTE_ID: pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__); @@ -12142,9 +14135,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, msm_bedais_pp_params[index].mute_on = mute; set_bit(ADM_PP_PARAM_MUTE_BIT, &msm_bedais_pp_params[index].pp_params_config); - if ((msm_bedais[be_idx].active) && - (msm_bedais[be_idx].compr_passthr_mode != - LEGACY_PCM)) + if ((msm_bedais[be_idx].active) && compr_passthr_mode) adm_send_compressed_device_mute(port_id, idx, mute); break; @@ -12156,9 +14147,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, &msm_bedais_pp_params[index].pp_params_config); latency = msm_bedais_pp_params[index].latency = ucontrol->value.integer.value[1]; - if ((msm_bedais[be_idx].active) && - (msm_bedais[be_idx].compr_passthr_mode != - LEGACY_PCM)) + if ((msm_bedais[be_idx].active) && compr_passthr_mode) adm_send_compressed_device_latency(port_id, idx, latency); break; @@ -12228,8 +14217,8 @@ static int msm_routing_probe(struct snd_soc_platform *platform) snd_soc_dapm_new_widgets(platform->component.dapm.card); - snd_soc_add_platform_controls(platform, lsm_function, - ARRAY_SIZE(lsm_function)); + snd_soc_add_platform_controls(platform, lsm_controls, + ARRAY_SIZE(lsm_controls)); snd_soc_add_platform_controls(platform, aanc_slim_0_rx_mux, ARRAY_SIZE(aanc_slim_0_rx_mux)); @@ -12240,10 +14229,16 @@ static int msm_routing_probe(struct snd_soc_platform *platform) snd_soc_add_platform_controls(platform, app_type_cfg_controls, ARRAY_SIZE(app_type_cfg_controls)); + snd_soc_add_platform_controls(platform, lsm_app_type_cfg_controls, + ARRAY_SIZE(lsm_app_type_cfg_controls)); + snd_soc_add_platform_controls(platform, stereo_to_custom_stereo_controls, ARRAY_SIZE(stereo_to_custom_stereo_controls)); + snd_soc_add_platform_controls(platform, ec_ref_param_controls, + ARRAY_SIZE(ec_ref_param_controls)); + msm_qti_pp_add_controls(platform); msm_dts_srs_tm_add_controls(platform); @@ -12326,7 +14321,7 @@ int msm_routing_check_backend_enabled(int fedai_id) return 0; } for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { - if (test_bit(fedai_id, &msm_bedais[i].fe_sessions)) + if (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0])) return msm_bedais[i].active; } return 0; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h index 0bb069154512..a066e9afc9e5 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -392,6 +392,7 @@ enum { #define ADM_PP_PARAM_LATENCY_ID 1 #define ADM_PP_PARAM_LATENCY_BIT 2 #define BE_DAI_PORT_SESSIONS_IDX_MAX 4 +#define BE_DAI_FE_SESSIONS_IDX_MAX 2 struct msm_pcm_routing_evt { void (*event_func)(enum msm_pcm_routing_event, void *); @@ -401,7 +402,9 @@ struct msm_pcm_routing_evt { struct msm_pcm_routing_bdai_data { u16 port_id; /* AFE port ID */ u8 active; /* track if this backend is enabled */ - unsigned long fe_sessions; /* Front-end sessions */ + + /* Front-end sessions */ + unsigned long fe_sessions[BE_DAI_FE_SESSIONS_IDX_MAX]; /* * Track Tx BE ports -> Rx BE ports. * port_sessions[0] used to track BE 0 to BE 63. @@ -415,7 +418,7 @@ struct msm_pcm_routing_bdai_data { unsigned int channel; unsigned int format; unsigned int adm_override_ch; - u32 compr_passthr_mode; + u32 passthr_mode; char *name; }; diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index 32826d38f65a..16ae05034662 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -2574,7 +2574,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, return copp_idx; } - void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) { struct audproc_mfc_output_media_fmt mfc_cfg; @@ -2677,8 +2676,43 @@ fail_cmd: return; } +static void route_set_opcode_matrix_id( + struct adm_cmd_matrix_map_routings_v5 **route_addr, + int path, uint32_t passthr_mode) +{ + struct adm_cmd_matrix_map_routings_v5 *route = *route_addr; -int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode) + switch (path) { + case ADM_PATH_PLAYBACK: + route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_AUDIO_RX; + break; + case ADM_PATH_LIVE_REC: + if (passthr_mode == LISTEN) { + route->hdr.opcode = + ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_LISTEN_TX; + break; + } + /* fall through to set matrix id for non-listen case */ + case ADM_PATH_NONLIVE_REC: + route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_AUDIO_TX; + break; + case ADM_PATH_COMPRESSED_RX: + route->hdr.opcode = ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_COMPRESSED_AUDIO_RX; + break; + default: + pr_err("%s: Wrong path set[%d]\n", __func__, path); + break; + } + pr_debug("%s: opcode 0x%x, matrix id %d\n", + __func__, route->hdr.opcode, route->matrix_id); +} + +int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode, + uint32_t passthr_mode) { struct adm_cmd_matrix_map_routings_v5 *route; struct adm_session_map_node_v5 *node; @@ -2711,32 +2745,9 @@ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode) route->hdr.dest_domain = APR_DOMAIN_ADSP; route->hdr.dest_port = 0; /* Ignored */; route->hdr.token = 0; - if (path == ADM_PATH_COMPRESSED_RX) { - pr_debug("%s: ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5 0x%x\n", - __func__, ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5); - route->hdr.opcode = ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5; - } else { - pr_debug("%s: DM_CMD_MATRIX_MAP_ROUTINGS_V5 0x%x\n", - __func__, ADM_CMD_MATRIX_MAP_ROUTINGS_V5); - route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; - } route->num_sessions = 1; + route_set_opcode_matrix_id(&route, path, passthr_mode); - switch (path) { - case ADM_PATH_PLAYBACK: - route->matrix_id = ADM_MATRIX_ID_AUDIO_RX; - break; - case ADM_PATH_LIVE_REC: - case ADM_PATH_NONLIVE_REC: - route->matrix_id = ADM_MATRIX_ID_AUDIO_TX; - break; - case ADM_PATH_COMPRESSED_RX: - route->matrix_id = ADM_MATRIX_ID_COMPRESSED_AUDIO_RX; - break; - default: - pr_err("%s: Wrong path set[%d]\n", __func__, path); - break; - } payload = ((u8 *)matrix_map + sizeof(struct adm_cmd_matrix_map_routings_v5)); node = (struct adm_session_map_node_v5 *)payload; diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index f1607b8e5d66..9a141a11d002 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -145,7 +145,7 @@ int afe_get_topology(int port_id) int topology; int port_index = afe_get_port_index(port_id); - if ((port_index < 0) || (port_index > AFE_MAX_PORTS)) { + if ((port_index < 0) || (port_index >= AFE_MAX_PORTS)) { pr_err("%s: Invalid port index %d\n", __func__, port_index); topology = -EINVAL; goto done; @@ -726,7 +726,7 @@ static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block) } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); result = -EINVAL; @@ -870,7 +870,7 @@ static int afe_spk_ramp_dn_cfg(int port) goto fail_cmd; } index = q6audio_get_port_index(port); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); ret = -EINVAL; @@ -951,7 +951,7 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, goto fail_cmd; } index = q6audio_get_port_index(src_port); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); ret = -EINVAL; @@ -1196,7 +1196,7 @@ static int afe_send_hw_delay(u16 port_id, u32 rate) } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); ret = -EINVAL; @@ -1318,7 +1318,7 @@ static int afe_send_port_topology_id(u16 port_id) u32 topology_id = 0; index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS - 1) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -1675,7 +1675,7 @@ static int afe_send_slimbus_slave_port_cfg( pr_debug("%s: enter, port_id = 0x%x\n", __func__, port_id); index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -1729,7 +1729,7 @@ static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port) } index = q6audio_get_port_index(tx_port); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -1814,7 +1814,7 @@ static int afe_aanc_mod_enable(void *apr, uint16_t tx_port, uint16_t enable) } index = q6audio_get_port_index(tx_port); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -2036,7 +2036,7 @@ int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg, return ret; } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -2122,7 +2122,7 @@ int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg return ret; } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -2196,7 +2196,7 @@ static int afe_send_cmd_port_start(u16 port_id) pr_debug("%s: enter\n", __func__); index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -2267,7 +2267,7 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, pr_debug("%s: port id: 0x%x\n", __func__, port_id); index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -2342,7 +2342,7 @@ int afe_send_slot_mapping_cfg( pr_debug("%s: port id: 0x%x\n", __func__, port_id); index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -2421,7 +2421,7 @@ int afe_send_custom_tdm_header_cfg( pr_debug("%s: port id: 0x%x\n", __func__, port_id); index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -2501,7 +2501,7 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, pr_debug("%s: port id: 0x%x\n", __func__, port_id); index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -2623,7 +2623,7 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) goto exit; } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid! for port ID 0x%x\n", __func__, index, port_id); ret = -EINVAL; @@ -2824,7 +2824,7 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, pr_debug("%s: port id: 0x%x\n", __func__, port_id); index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -3383,7 +3383,7 @@ int afe_open(u16 port_id, pr_err("%s: port_id 0x%x rate %d\n", __func__, port_id, rate); index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -3551,7 +3551,7 @@ int afe_loopback(u16 enable, u16 rx_port, u16 tx_port) } index = q6audio_get_port_index(rx_port); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -3617,7 +3617,7 @@ int afe_loopback_gain(u16 port_id, u16 volume) goto fail_cmd; } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -3720,7 +3720,7 @@ int afe_start_pseudo_port(u16 port_id) } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -3763,7 +3763,7 @@ int afe_pseudo_port_stop_nowait(u16 port_id) return -EINVAL; } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -3924,7 +3924,7 @@ int afe_stop_pseudo_port(u16 port_id) } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -4213,7 +4213,7 @@ int afe_cmd_memory_map_nowait(int port_id, phys_addr_t dma_addr_p, rtac_set_afe_handle(this_afe.apr); } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -4477,7 +4477,7 @@ int afe_unregister_get_events(u16 port_id) } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -4821,7 +4821,7 @@ int afe_dtmf_generate_rx(int64_t duration_in_ms, goto fail_cmd; } index = q6audio_get_port_index(this_afe.dtmf_gen_rx_portid); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); ret = -EINVAL; @@ -5059,7 +5059,7 @@ int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable) int index; index = q6audio_get_port_index(rx_port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); ret = -EINVAL; @@ -5072,7 +5072,7 @@ int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable) goto done; } index = q6audio_get_port_index(tx_port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); ret = -EINVAL; @@ -5367,7 +5367,7 @@ int afe_close(int port_id) port_id = q6audio_convert_virtual_to_portid(port_id); index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -5525,7 +5525,7 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) return ret; } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -5691,7 +5691,7 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) int ret = 0; index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -5724,7 +5724,7 @@ int afe_set_lpass_internal_digital_codec_clock(u16 port_id, return ret; } index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -5805,7 +5805,7 @@ int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable) int ret = 0; index = q6audio_get_port_index(port_id); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); return -EINVAL; @@ -6084,7 +6084,7 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) goto fail_cmd; } index = q6audio_get_port_index(port); - if (index < 0 || index > AFE_MAX_PORTS) { + if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", __func__, index); ret = -EINVAL; diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 2c501ce3d6ff..74fbe984e6e9 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -8343,14 +8343,17 @@ int q6asm_get_apr_service_id(int session_id) int q6asm_get_asm_topology(int session_id) { - int topology; + int topology = -EINVAL; if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) { pr_err("%s: invalid session_id = %d\n", __func__, session_id); - topology = -EINVAL; goto done; } - + if (session[session_id] == NULL) { + pr_err("%s: session not created for session id = %d\n", + __func__, session_id); + goto done; + } topology = session[session_id]->topology; done: return topology; @@ -8358,14 +8361,17 @@ done: int q6asm_get_asm_app_type(int session_id) { - int app_type; + int app_type = -EINVAL; if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) { pr_err("%s: invalid session_id = %d\n", __func__, session_id); - app_type = -EINVAL; goto done; } - + if (session[session_id] == NULL) { + pr_err("%s: session not created for session id = %d\n", + __func__, session_id); + goto done; + } app_type = session[session_id]->app_type; done: return app_type; diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c index 2bf0c490e834..525ec1c30f48 100644 --- a/sound/soc/msm/qdsp6v2/q6lsm.c +++ b/sound/soc/msm/qdsp6v2/q6lsm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017, 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 @@ -38,6 +38,8 @@ #define LSM_ALIGN_BOUNDARY 512 #define LSM_SAMPLE_RATE 16000 #define QLSM_PARAM_ID_MINOR_VERSION 1 +#define QLSM_PARAM_ID_MINOR_VERSION_2 2 + static int lsm_afe_port; enum { @@ -707,29 +709,28 @@ static int q6lsm_send_confidence_levels( return rc; } -static int q6lsm_send_params(struct lsm_client *client, +static int q6lsm_send_param_opmode(struct lsm_client *client, struct lsm_module_param_ids *opmode_ids, - struct lsm_module_param_ids *connectport_ids, u32 set_param_opcode) { int rc; - struct lsm_cmd_set_opmode_connectport opmode_connectport; + struct lsm_cmd_set_params_opmode opmode_params; struct apr_hdr *msg_hdr; - struct lsm_param_connect_to_port *connect_to_port; + struct lsm_param_op_mode *op_mode; u32 data_payload_size, param_size; - msg_hdr = &opmode_connectport.msg_hdr; + msg_hdr = &opmode_params.msg_hdr; q6lsm_add_hdr(client, msg_hdr, - sizeof(opmode_connectport), true); + sizeof(opmode_params), true); msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(opmode_connectport) - + data_payload_size = sizeof(opmode_params) - sizeof(*msg_hdr) - - sizeof(opmode_connectport.params_hdr); - q6lsm_set_param_hdr_info(&opmode_connectport.params_hdr, + sizeof(opmode_params.params_hdr); + q6lsm_set_param_hdr_info(&opmode_params.params_hdr, data_payload_size, 0, 0, 0); - connect_to_port = &opmode_connectport.connect_to_port; - op_mode = &opmode_connectport.op_mode; + op_mode = &opmode_params.op_mode; + param_size = sizeof(struct lsm_param_op_mode) - sizeof(op_mode->common); @@ -741,10 +742,61 @@ static int q6lsm_send_params(struct lsm_client *client, op_mode->reserved = 0; pr_debug("%s: mode = 0x%x", __func__, op_mode->mode); + rc = q6lsm_apr_send_pkt(client, client->apr, + &opmode_params, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); + + pr_debug("%s: leave %d\n", __func__, rc); + return rc; +} + +void set_lsm_port(int lsm_port) +{ + lsm_afe_port = lsm_port; +} + +int get_lsm_port(void) +{ + return lsm_afe_port; +} + +int q6lsm_set_port_connected(struct lsm_client *client) +{ + int rc; + struct lsm_cmd_set_connectport connectport; + struct lsm_module_param_ids connectport_ids; + struct apr_hdr *msg_hdr; + struct lsm_param_connect_to_port *connect_to_port; + u32 data_payload_size, param_size, set_param_opcode; + + if (client->use_topology) { + set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK; + connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + } else { + set_param_opcode = LSM_SESSION_CMD_SET_PARAMS; + connectport_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; + connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + } + client->connect_to_port = get_lsm_port(); + + msg_hdr = &connectport.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(connectport), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(connectport) - + sizeof(*msg_hdr) - + sizeof(connectport.params_hdr); + q6lsm_set_param_hdr_info(&connectport.params_hdr, + data_payload_size, 0, 0, 0); + connect_to_port = &connectport.connect_to_port; + param_size = (sizeof(struct lsm_param_connect_to_port) - sizeof(connect_to_port->common)); q6lsm_set_param_common(&connect_to_port->common, - connectport_ids, param_size, + &connectport_ids, param_size, set_param_opcode); connect_to_port->minor_version = QLSM_PARAM_ID_MINOR_VERSION; connect_to_port->port_id = client->connect_to_port; @@ -752,23 +804,191 @@ static int q6lsm_send_params(struct lsm_client *client, pr_debug("%s: port= %d", __func__, connect_to_port->port_id); rc = q6lsm_apr_send_pkt(client, client->apr, - &opmode_connectport, true, NULL); + &connectport, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); + + return rc; +} +static int q6lsm_send_param_polling_enable(struct lsm_client *client, + bool poll_en, + struct lsm_module_param_ids *poll_enable_ids, + u32 set_param_opcode) +{ + int rc = 0; + struct lsm_cmd_poll_enable cmd; + struct apr_hdr *msg_hdr; + struct lsm_param_poll_enable *poll_enable; + u32 data_payload_size, param_size; + + msg_hdr = &cmd.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(struct lsm_cmd_poll_enable), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(struct lsm_cmd_poll_enable) - + sizeof(struct apr_hdr) - + sizeof(struct lsm_set_params_hdr); + q6lsm_set_param_hdr_info(&cmd.params_hdr, + data_payload_size, 0, 0, 0); + poll_enable = &cmd.poll_enable; + + param_size = (sizeof(struct lsm_param_poll_enable) - + sizeof(poll_enable->common)); + q6lsm_set_param_common(&poll_enable->common, + poll_enable_ids, param_size, + set_param_opcode); + poll_enable->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + poll_enable->polling_enable = (poll_en) ? 1 : 0; + pr_debug("%s: poll enable= %d", __func__, poll_enable->polling_enable); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &cmd, true, NULL); if (rc) pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", __func__, msg_hdr->opcode, rc); - pr_debug("%s: leave %d\n", __func__, rc); return rc; } -void set_lsm_port(int lsm_port) +int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, + uint32_t event_mode) { - lsm_afe_port = lsm_port; + int rc = 0; + struct lsm_cmd_set_fwk_mode_cfg cmd; + struct lsm_module_param_ids fwk_mode_cfg_ids; + struct apr_hdr *msg_hdr; + struct lsm_param_fwk_mode_cfg *fwk_mode_cfg; + u32 data_payload_size, param_size, set_param_opcode; + + if (client->use_topology) { + set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + fwk_mode_cfg_ids.module_id = LSM_MODULE_ID_FRAMEWORK; + fwk_mode_cfg_ids.param_id = LSM_PARAM_ID_FWK_MODE_CONFIG; + } else { + pr_debug("%s: Ignore sending event mode\n", __func__); + return rc; + } + + msg_hdr = &cmd.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(struct lsm_cmd_set_fwk_mode_cfg), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(struct lsm_cmd_set_fwk_mode_cfg) - + sizeof(struct apr_hdr) - + sizeof(struct lsm_set_params_hdr); + q6lsm_set_param_hdr_info(&cmd.params_hdr, + data_payload_size, 0, 0, 0); + fwk_mode_cfg = &cmd.fwk_mode_cfg; + + param_size = (sizeof(struct lsm_param_fwk_mode_cfg) - + sizeof(fwk_mode_cfg->common)); + q6lsm_set_param_common(&fwk_mode_cfg->common, + &fwk_mode_cfg_ids, param_size, + set_param_opcode); + + fwk_mode_cfg->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + fwk_mode_cfg->mode = event_mode; + pr_debug("%s: mode = %d\n", __func__, fwk_mode_cfg->mode); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &cmd, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); + return rc; } -int get_lsm_port() +static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt, + int channel_count) { - return lsm_afe_port; + int rc = 0; + + memset(media_fmt->channel_mapping, 0, LSM_MAX_NUM_CHANNELS); + + switch (channel_count) { + case 1: + media_fmt->channel_mapping[0] = PCM_CHANNEL_FC; + break; + case 2: + media_fmt->channel_mapping[0] = PCM_CHANNEL_FL; + media_fmt->channel_mapping[1] = PCM_CHANNEL_FR; + break; + case 3: + media_fmt->channel_mapping[0] = PCM_CHANNEL_FL; + media_fmt->channel_mapping[1] = PCM_CHANNEL_FR; + media_fmt->channel_mapping[2] = PCM_CHANNEL_FC; + break; + case 4: + media_fmt->channel_mapping[0] = PCM_CHANNEL_FL; + media_fmt->channel_mapping[1] = PCM_CHANNEL_FR; + media_fmt->channel_mapping[2] = PCM_CHANNEL_LS; + media_fmt->channel_mapping[3] = PCM_CHANNEL_RS; + break; + default: + pr_err("%s: invalid num_chan %d\n", __func__, channel_count); + rc = -EINVAL; + break; + } + return rc; +} + +int q6lsm_set_media_fmt_params(struct lsm_client *client) +{ + int rc = 0; + struct lsm_cmd_set_media_fmt cmd; + struct lsm_module_param_ids media_fmt_ids; + struct apr_hdr *msg_hdr; + struct lsm_param_media_fmt *media_fmt; + u32 data_payload_size, param_size, set_param_opcode; + struct lsm_hw_params param = client->hw_params; + + if (client->use_topology) { + set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + media_fmt_ids.module_id = LSM_MODULE_ID_FRAMEWORK; + media_fmt_ids.param_id = LSM_PARAM_ID_MEDIA_FMT; + } else { + pr_debug("%s: Ignore sending media format\n", __func__); + goto err_ret; + } + + msg_hdr = &cmd.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(struct lsm_cmd_set_media_fmt), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(struct lsm_cmd_set_media_fmt) - + sizeof(struct apr_hdr) - + sizeof(struct lsm_set_params_hdr); + q6lsm_set_param_hdr_info(&cmd.params_hdr, + data_payload_size, 0, 0, 0); + media_fmt = &cmd.media_fmt; + + param_size = (sizeof(struct lsm_param_media_fmt) - + sizeof(media_fmt->common)); + q6lsm_set_param_common(&media_fmt->common, + &media_fmt_ids, param_size, + set_param_opcode); + + media_fmt->minor_version = QLSM_PARAM_ID_MINOR_VERSION_2; + media_fmt->sample_rate = param.sample_rate; + media_fmt->num_channels = param.num_chs; + media_fmt->bit_width = param.sample_size; + + rc = q6lsm_arrange_mch_map(media_fmt, media_fmt->num_channels); + if (rc) + goto err_ret; + + pr_debug("%s: sample rate= %d, channels %d bit width %d\n", + __func__, media_fmt->sample_rate, media_fmt->num_channels, + media_fmt->bit_width); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &cmd, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); +err_ret: + return rc; } int q6lsm_set_data(struct lsm_client *client, @@ -776,7 +996,7 @@ int q6lsm_set_data(struct lsm_client *client, bool detectfailure) { int rc = 0; - struct lsm_module_param_ids opmode_ids, connectport_ids; + struct lsm_module_param_ids opmode_ids; struct lsm_module_param_ids conf_levels_ids; if (!client->confidence_levels) { @@ -800,16 +1020,12 @@ int q6lsm_set_data(struct lsm_client *client, goto err_ret; } client->mode |= detectfailure << 2; - client->connect_to_port = get_lsm_port(); opmode_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; opmode_ids.param_id = LSM_PARAM_ID_OPERATION_MODE; - connectport_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; - connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; - - rc = q6lsm_send_params(client, &opmode_ids, &connectport_ids, - LSM_SESSION_CMD_SET_PARAMS); + rc = q6lsm_send_param_opmode(client, &opmode_ids, + LSM_SESSION_CMD_SET_PARAMS); if (rc) { pr_err("%s: Failed to set lsm config params %d\n", __func__, rc); @@ -1390,7 +1606,7 @@ static int q6lsm_send_param_gain( int q6lsm_set_one_param(struct lsm_client *client, struct lsm_params_info *p_info, void *data, - enum LSM_PARAM_TYPE param_type) + uint32_t param_type) { int rc = 0, pkt_sz; struct lsm_module_param_ids ids; @@ -1409,7 +1625,6 @@ int q6lsm_set_one_param(struct lsm_client *client, case LSM_OPERATION_MODE: { struct snd_lsm_detect_mode *det_mode = data; struct lsm_module_param_ids opmode_ids; - struct lsm_module_param_ids connectport_ids; if (det_mode->mode == LSM_MODE_KEYWORD_ONLY_DETECTION) { client->mode = 0x01; @@ -1422,16 +1637,12 @@ int q6lsm_set_one_param(struct lsm_client *client, } client->mode |= det_mode->detect_failure << 2; - client->connect_to_port = get_lsm_port(); opmode_ids.module_id = p_info->module_id; opmode_ids.param_id = p_info->param_id; - connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK; - connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; - - rc = q6lsm_send_params(client, &opmode_ids, &connectport_ids, - LSM_SESSION_CMD_SET_PARAMS_V2); + rc = q6lsm_send_param_opmode(client, &opmode_ids, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: OPERATION_MODE failed, rc %d\n", __func__, rc); @@ -1458,6 +1669,20 @@ int q6lsm_set_one_param(struct lsm_client *client, pr_err("%s: CONFIDENCE_LEVELS cmd failed, rc %d\n", __func__, rc); break; + case LSM_POLLING_ENABLE: { + struct snd_lsm_poll_enable *lsm_poll_enable = + (struct snd_lsm_poll_enable *) data; + ids.module_id = p_info->module_id; + ids.param_id = p_info->param_id; + rc = q6lsm_send_param_polling_enable(client, + lsm_poll_enable->poll_en, &ids, + LSM_SESSION_CMD_SET_PARAMS_V2); + if (rc) + pr_err("%s: POLLING ENABLE cmd failed, rc %d\n", + __func__, rc); + break; + } + case LSM_REG_SND_MODEL: { struct lsm_cmd_set_params model_param; u32 payload_size; diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c index e7619c0ca0dd..d352133b7c32 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.c +++ b/sound/soc/msm/qdsp6v2/q6voice.c @@ -3990,6 +3990,10 @@ static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v) { int ret; + ret = voice_send_cvp_device_channels_cmd(v); + if (ret < 0) + goto done; + if (voice_get_cvd_int_version(common.cvd_version) >= CVD_INT_VERSION_2_3) { ret = voice_send_cvp_media_format_cmd(v, RX_PATH); @@ -4002,8 +4006,6 @@ static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v) if (common.ec_ref_ext) ret = voice_send_cvp_media_format_cmd(v, EC_REF_PATH); - } else { - ret = voice_send_cvp_device_channels_cmd(v); } done: diff --git a/sound/soc/msm/sdm660-common.c b/sound/soc/msm/sdm660-common.c index 40a9c2065963..3a8fdf8f1256 100644 --- a/sound/soc/msm/sdm660-common.c +++ b/sound/soc/msm/sdm660-common.c @@ -2702,8 +2702,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,cdc-pdm-gpios", 0); pdata->comp_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-comp-gpios", 0); - pdata->sdw_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-sdw-gpios", 0); pdata->dmic_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-dmic-gpios", 0); pdata->ext_spk_gpio_p = of_parse_phandle(pdev->dev.of_node, diff --git a/sound/soc/msm/sdm660-common.h b/sound/soc/msm/sdm660-common.h index 5742c8545b86..bca8cd788a39 100644 --- a/sound/soc/msm/sdm660-common.h +++ b/sound/soc/msm/sdm660-common.h @@ -95,7 +95,6 @@ struct msm_asoc_mach_data { struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ struct device_node *pdm_gpio_p; /* used by pinctrl API */ struct device_node *comp_gpio_p; /* used by pinctrl API */ - struct device_node *sdw_gpio_p; /* used by pinctrl API */ struct device_node *dmic_gpio_p; /* used by pinctrl API */ struct device_node *ext_spk_gpio_p; /* used by pinctrl API */ struct snd_soc_codec *codec; diff --git a/sound/soc/msm/sdm660-internal.c b/sound/soc/msm/sdm660-internal.c index 805ff2335b42..8b0a12a46338 100644 --- a/sound/soc/msm/sdm660-internal.c +++ b/sound/soc/msm/sdm660-internal.c @@ -539,35 +539,6 @@ static int enable_spk_ext_pa(struct snd_soc_codec *codec, int enable) return 0; } -static int msm_config_sdw_gpio(bool enable, struct snd_soc_codec *codec) -{ - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - int ret = 0; - - pr_debug("%s: %s SDW Clk/Data Gpios\n", __func__, - enable ? "Enable" : "Disable"); - - if (enable) { - ret = msm_cdc_pinctrl_select_active_state(pdata->sdw_gpio_p); - if (ret) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "sdw_pin"); - goto done; - } - } else { - ret = msm_cdc_pinctrl_select_sleep_state(pdata->sdw_gpio_p); - if (ret) { - pr_err("%s: gpio set cannot be de-activated %s\n", - __func__, "sdw_pin"); - goto done; - } - } - -done: - return ret; -} - static int int_mi2s_get_idx_from_beid(int32_t be_id) { int idx = 0; @@ -939,9 +910,6 @@ static const struct snd_kcontrol_new msm_sdw_controls[] = { SOC_ENUM_EXT("INT4_MI2S_RX SampleRate", int4_mi2s_rx_sample_rate, int_mi2s_sample_rate_get, int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT4_MI2S_RX SampleRate", int4_mi2s_rx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), SOC_ENUM_EXT("INT4_MI2S_RX Channels", int4_mi2s_rx_chs, int_mi2s_ch_get, int_mi2s_ch_put), SOC_ENUM_EXT("VI_FEED_TX Channels", int5_mi2s_tx_chs, @@ -1386,7 +1354,6 @@ static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_SDW"); snd_soc_dapm_sync(dapm); - msm_sdw_gpio_cb(msm_config_sdw_gpio, codec); card = rtd->card->snd_card; if (!codec_root) codec_root = snd_register_module_info(card->module, "codecs", @@ -2346,7 +2313,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | ASYNC_DPCM_SND_SOC_HW_PARAMS, .be_id = MSM_BACKEND_DAI_INT3_MI2S_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, .ops = &msm_int_mi2s_be_ops, .ignore_suspend = 1, }, |
