Merge "ASoC: codecs: sdm660_cdc: Fix mute if compander is disabled"
diff --git a/asoc/Makefile b/asoc/Makefile
index cc28148..4d3839d 100644
--- a/asoc/Makefile
+++ b/asoc/Makefile
@@ -15,19 +15,9 @@
snd-soc-msm8998-objs := msm8998.o
obj-$(CONFIG_SND_SOC_MACHINE_MSM8998) += snd-soc-msm8998.o
-# for SDM660 sound card driver
-snd-soc-sdm660-common-objs := sdm660-common.o
-obj-$(CONFIG_SND_SOC_SDM670) += snd-soc-sdm660-common.o
-
-# for SDM660 sound card driver
-snd-soc-int-codec-objs := sdm660-internal.o
-obj-$(CONFIG_SND_SOC_INT_CODEC) += snd-soc-sdm660-common.o
-obj-$(CONFIG_SND_SOC_INT_CODEC) += snd-soc-int-codec.o
-
-# for SDM660 sound card driver
-snd-soc-ext-codec-objs := sdm660-external.o sdm660-ext-dai-links.o
-obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-sdm660-common.o
-obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-ext-codec.o
+# for SDM670 sound card driver
+snd-soc-sdm670-objs := sdm660-common.o sdm660-internal.o sdm660-external.o sdm660-ext-dai-links.o
+obj-$(CONFIG_SND_SOC_SDM670) += snd-soc-sdm670.o
# for SDM845 sound card driver
snd-soc-sdm845-objs := sdm845.o
diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c
index eeaddf6..4ab2037 100644
--- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c
+++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c
@@ -55,6 +55,11 @@
MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN,
};
+#define SDM660_TX_UNMUTE_DELAY_MS 40
+static int tx_unmute_delay = SDM660_TX_UNMUTE_DELAY_MS;
+module_param(tx_unmute_delay, int, 0664);
+MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
+
static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
struct snd_soc_codec *registered_digcodec;
@@ -924,6 +929,9 @@
/* enable HPF */
snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x00);
+ schedule_delayed_work(
+ &msm_dig_cdc->tx_mute_dwork[decimator - 1].dwork,
+ msecs_to_jiffies(tx_unmute_delay));
if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
CF_MIN_3DB_150HZ) {
@@ -937,20 +945,14 @@
snd_soc_read(codec,
tx_digital_gain_reg[w->shift + offset])
);
- if (pdata->lb_mode) {
- pr_debug("%s: loopback mode unmute the DEC\n",
- __func__);
- snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
- }
- snd_soc_update_bits(codec, tx_vol_ctl_reg,
- 0x01, 0x00);
-
break;
case SND_SOC_DAPM_PRE_PMD:
snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
msleep(20);
snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
+ cancel_delayed_work_sync(
+ &msm_dig_cdc->tx_mute_dwork[decimator - 1].dwork);
break;
case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
@@ -1191,6 +1193,35 @@
}
EXPORT_SYMBOL(msm_dig_codec_info_create_codec_entry);
+static void sdm660_tx_mute_update_callback(struct work_struct *work)
+{
+ struct tx_mute_work *tx_mute_dwork;
+ struct snd_soc_codec *codec = NULL;
+ struct msm_dig_priv *dig_cdc;
+ struct delayed_work *delayed_work;
+ u16 tx_vol_ctl_reg = 0;
+ u8 decimator = 0, i;
+
+ delayed_work = to_delayed_work(work);
+ tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
+ dig_cdc = tx_mute_dwork->dig_cdc;
+ codec = dig_cdc->codec;
+
+ for (i = 0; i < (NUM_DECIMATORS - 1); i++) {
+ if (dig_cdc->dec_active[i])
+ decimator = i + 1;
+ if (decimator && decimator < NUM_DECIMATORS) {
+ /* unmute decimators corresponding to Tx DAI's*/
+ tx_vol_ctl_reg =
+ MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG +
+ 32 * (decimator - 1);
+ snd_soc_update_bits(codec, tx_vol_ctl_reg,
+ 0x01, 0x00);
+ }
+ decimator = 0;
+ }
+}
+
static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec)
{
struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev);
@@ -1207,6 +1238,10 @@
tx_hpf_work[i].decimator = i + 1;
INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
tx_hpf_corner_freq_callback);
+ msm_dig_cdc->tx_mute_dwork[i].dig_cdc = msm_dig_cdc;
+ msm_dig_cdc->tx_mute_dwork[i].decimator = i + 1;
+ INIT_DELAYED_WORK(&msm_dig_cdc->tx_mute_dwork[i].dwork,
+ sdm660_tx_mute_update_callback);
}
for (i = 0; i < MSM89XX_RX_MAX; i++)
@@ -1891,63 +1926,8 @@
MSM89XX_CDC_CORE_TX5_MUX_CTL, 3, 1, 0),
};
-static int msm_dig_cdc_digital_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = NULL;
- u16 tx_vol_ctl_reg = 0;
- u8 decimator = 0, i;
- struct msm_dig_priv *dig_cdc;
-
- pr_debug("%s: Digital Mute val = %d\n", __func__, mute);
-
- if (!dai || !dai->codec) {
- pr_err("%s: Invalid params\n", __func__);
- return -EINVAL;
- }
- codec = dai->codec;
- dig_cdc = snd_soc_codec_get_drvdata(codec);
-
- if (dai->id == AIF1_PB) {
- dev_dbg(codec->dev, "%s: Not capture use case skip\n",
- __func__);
- return 0;
- }
-
- mute = (mute) ? 1 : 0;
- if (!mute) {
- /*
- * 15 ms is an emperical value for the mute time
- * that was arrived by checking the pop level
- * to be inaudible
- */
- usleep_range(15000, 15010);
- }
-
- if (dai->id == AIF3_SVA) {
- snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG, 0x01, mute);
- goto ret;
- }
- for (i = 0; i < (NUM_DECIMATORS - 1); i++) {
- if (dig_cdc->dec_active[i])
- decimator = i + 1;
- if (decimator && decimator < NUM_DECIMATORS) {
- /* mute/unmute decimators corresponding to Tx DAI's */
- tx_vol_ctl_reg =
- MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG +
- 32 * (decimator - 1);
- snd_soc_update_bits(codec, tx_vol_ctl_reg,
- 0x01, mute);
- }
- decimator = 0;
- }
-ret:
- return 0;
-}
-
static struct snd_soc_dai_ops msm_dig_dai_ops = {
.hw_params = msm_dig_cdc_hw_params,
- .digital_mute = msm_dig_cdc_digital_mute,
};
diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h
index f0e7a9c..42c31d5 100644
--- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h
+++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h
@@ -32,6 +32,12 @@
MSM89XX_RX_MAX,
};
+struct tx_mute_work {
+ struct msm_dig_priv *dig_cdc;
+ u32 decimator;
+ struct delayed_work dwork;
+};
+
struct msm_dig_priv {
struct snd_soc_codec *codec;
u32 comp_enabled[MSM89XX_RX_MAX];
@@ -54,6 +60,7 @@
int (*register_notifier)(void *handle,
struct notifier_block *nblock,
bool enable);
+ struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
};
struct dig_ctrl_platform_data {
diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c
index 19877b9..8ade82b 100644
--- a/asoc/codecs/wcd9335.c
+++ b/asoc/codecs/wcd9335.c
@@ -87,6 +87,8 @@
#define TASHA_NUM_INTERPOLATORS 9
#define TASHA_NUM_DECIMATORS 9
+#define WCD9335_CHILD_DEVICES_MAX 6
+
#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE))
#define TASHA_MAD_AUDIO_FIRMWARE_PATH "wcd9335/wcd9335_mad_audio.bin"
#define TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS (1 << 0)
@@ -829,6 +831,10 @@
u32 ref_count;
/* Lock to protect mclk enablement */
struct mutex mclk_lock;
+
+ struct platform_device *pdev_child_devices
+ [WCD9335_CHILD_DEVICES_MAX];
+ int child_count;
};
static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
@@ -13576,11 +13582,14 @@
struct wcd9xxx *control;
control = dev_get_drvdata(codec->dev->parent);
+ control->num_rx_port = 0;
+ control->num_tx_port = 0;
control->rx_chs = NULL;
control->tx_chs = NULL;
tasha_cleanup_irqs(tasha);
/* Cleanup MBHC */
+ wcd_mbhc_deinit(&tasha->mbhc);
/* Cleanup resmgr */
return 0;
@@ -13920,6 +13929,7 @@
}
platdata = &tasha->swr_plat_data;
+ tasha->child_count = 0;
for_each_child_of_node(wcd9xxx->dev->of_node, node) {
if (!strcmp(node->name, "swr_master"))
@@ -13980,6 +13990,11 @@
tasha->nr = ctrl_num;
tasha->swr_ctrl_data = swr_ctrl_data;
}
+
+ if (tasha->child_count < WCD9335_CHILD_DEVICES_MAX)
+ tasha->pdev_child_devices[tasha->child_count++] = pdev;
+ else
+ goto err;
}
return;
@@ -14179,17 +14194,25 @@
static int tasha_remove(struct platform_device *pdev)
{
struct tasha_priv *tasha;
+ int count = 0;
tasha = platform_get_drvdata(pdev);
+ if (!tasha)
+ return -EINVAL;
+
+ for (count = 0; count < tasha->child_count &&
+ count < WCD9335_CHILD_DEVICES_MAX; count++)
+ platform_device_unregister(tasha->pdev_child_devices[count]);
+
mutex_destroy(&tasha->codec_mutex);
clk_put(tasha->wcd_ext_clk);
if (tasha->wcd_native_clk)
clk_put(tasha->wcd_native_clk);
mutex_destroy(&tasha->mclk_lock);
- devm_kfree(&pdev->dev, tasha);
- snd_soc_unregister_codec(&pdev->dev);
mutex_destroy(&tasha->sb_clk_gear_lock);
+ snd_soc_unregister_codec(&pdev->dev);
+ devm_kfree(&pdev->dev, tasha);
return 0;
}
diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c
index 2802a4f..cfe47ed 100644
--- a/asoc/msm-dai-q6-v2.c
+++ b/asoc/msm-dai-q6-v2.c
@@ -2249,6 +2249,10 @@
sizeof(struct asm_aac_enc_cfg_v2_t));
break;
case ENC_FMT_APTX:
+ memcpy(ucontrol->value.bytes.data + format_size,
+ &dai_data->enc_config.data,
+ sizeof(struct asm_aptx_enc_cfg_t));
+ break;
case ENC_FMT_APTX_HD:
memcpy(ucontrol->value.bytes.data + format_size,
&dai_data->enc_config.data,
@@ -2298,6 +2302,10 @@
sizeof(struct asm_aac_enc_cfg_v2_t));
break;
case ENC_FMT_APTX:
+ memcpy(&dai_data->enc_config.data,
+ ucontrol->value.bytes.data + format_size,
+ sizeof(struct asm_aptx_enc_cfg_t));
+ break;
case ENC_FMT_APTX_HD:
memcpy(&dai_data->enc_config.data,
ucontrol->value.bytes.data + format_size,
@@ -6535,26 +6543,12 @@
struct msm_dai_q6_tdm_dai_data *dai_data =
dev_get_drvdata(dai->dev);
- switch (dai->id) {
- case AFE_PORT_ID_QUATERNARY_TDM_RX:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
- case AFE_PORT_ID_QUATERNARY_TDM_TX:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
+ if ((dai->id >= AFE_PORT_ID_PRIMARY_TDM_RX) &&
+ (dai->id <= AFE_PORT_ID_QUINARY_TDM_TX_7)) {
dai_data->clk_set.clk_freq_in_hz = freq;
- break;
- default:
+ } else {
+ dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
+ __func__, dai->id);
return -EINVAL;
}
diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c
index e6b82df..1874cfa 100644
--- a/asoc/sdm660-common.c
+++ b/asoc/sdm660-common.c
@@ -17,6 +17,7 @@
#include <linux/of_device.h>
#include <sound/pcm_params.h>
#include <dsp/q6afe-v2.h>
+#include <dsp/audio_notifier.h>
#include "msm-pcm-routing-v2.h"
#include "sdm660-common.h"
#include "sdm660-internal.h"
@@ -3134,20 +3135,6 @@
return ret;
}
-static void msm_free_auxdev_mem(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
- int i;
-
- if (card->num_aux_devs > 0) {
- for (i = 0; i < card->num_aux_devs; i++) {
- kfree(msm_aux_dev[i].codec_name);
- kfree(msm_codec_conf[i].dev_name);
- kfree(msm_codec_conf[i].name_prefix);
- }
- }
-}
-
static void i2s_auxpcm_init(struct platform_device *pdev)
{
int count;
@@ -3366,10 +3353,22 @@
if (pdata->snd_card_val == INT_SND_CARD)
mutex_destroy(&pdata->cdc_int_mclk0_mutex);
- msm_free_auxdev_mem(pdev);
- gpio_free(pdata->us_euro_gpio);
- gpio_free(pdata->hph_en1_gpio);
- gpio_free(pdata->hph_en0_gpio);
+ if (gpio_is_valid(pdata->us_euro_gpio)) {
+ gpio_free(pdata->us_euro_gpio);
+ pdata->us_euro_gpio = 0;
+ }
+ if (gpio_is_valid(pdata->hph_en1_gpio)) {
+ gpio_free(pdata->hph_en1_gpio);
+ pdata->hph_en1_gpio = 0;
+ }
+ if (gpio_is_valid(pdata->hph_en0_gpio)) {
+ gpio_free(pdata->hph_en0_gpio);
+ pdata->hph_en0_gpio = 0;
+ }
+
+ if (pdata->snd_card_val != INT_SND_CARD)
+ audio_notifier_deregister("sdm660");
+
snd_soc_unregister_card(card);
return 0;
}
diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c
index 4777a5f..a331135 100644
--- a/asoc/sdm660-ext-dai-links.c
+++ b/asoc/sdm660-ext-dai-links.c
@@ -1573,7 +1573,7 @@
{
.name = LPASS_BE_QUIN_TDM_RX_0,
.stream_name = "Quinary TDM0 Playback",
- .cpu_dai_name = "msm-dai-q6-tdm.37184",
+ .cpu_dai_name = "msm-dai-q6-tdm.36928",
.platform_name = "msm-pcm-routing",
.codec_name = "msm-stub-codec.1",
.codec_dai_name = "msm-stub-rx",
@@ -1587,7 +1587,7 @@
{
.name = LPASS_BE_QUIN_TDM_TX_0,
.stream_name = "Quinary TDM0 Capture",
- .cpu_dai_name = "msm-dai-q6-tdm.37185",
+ .cpu_dai_name = "msm-dai-q6-tdm.36929",
.platform_name = "msm-pcm-routing",
.codec_name = "msm-stub-codec.1",
.codec_dai_name = "msm-stub-tx",
diff --git a/asoc/sdm660-external.h b/asoc/sdm660-external.h
index 0648c01..b81e158 100644
--- a/asoc/sdm660-external.h
+++ b/asoc/sdm660-external.h
@@ -32,7 +32,7 @@
struct snd_pcm_hw_params *params);
int msm_snd_card_tavil_late_probe(struct snd_soc_card *card);
int msm_snd_card_tasha_late_probe(struct snd_soc_card *card);
-#ifdef CONFIG_SND_SOC_EXT_CODEC
+#if IS_ENABLED(CONFIG_SND_SOC_EXT_CODEC)
int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *,
struct snd_soc_card **, struct wcd_mbhc_config *);
void msm_ext_register_audio_notifier(struct platform_device *pdev);
diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c
index 713da55..a1536fe 100644
--- a/asoc/sdm660-internal.c
+++ b/asoc/sdm660-internal.c
@@ -2612,7 +2612,7 @@
{
.name = LPASS_BE_QUIN_TDM_RX_0,
.stream_name = "Quinary TDM0 Playback",
- .cpu_dai_name = "msm-dai-q6-tdm.37184",
+ .cpu_dai_name = "msm-dai-q6-tdm.36928",
.platform_name = "msm-pcm-routing",
.codec_name = "msm-stub-codec.1",
.codec_dai_name = "msm-stub-rx",
@@ -2626,7 +2626,7 @@
{
.name = LPASS_BE_QUIN_TDM_TX_0,
.stream_name = "Quinary TDM0 Capture",
- .cpu_dai_name = "msm-dai-q6-tdm.37185",
+ .cpu_dai_name = "msm-dai-q6-tdm.36929",
.platform_name = "msm-pcm-routing",
.codec_name = "msm-stub-codec.1",
.codec_dai_name = "msm-stub-tx",
diff --git a/asoc/sdm660-internal.h b/asoc/sdm660-internal.h
index ccc62b8..6918231 100644
--- a/asoc/sdm660-internal.h
+++ b/asoc/sdm660-internal.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
@@ -15,7 +15,7 @@
#include <sound/soc.h>
-#ifdef CONFIG_SND_SOC_INT_CODEC
+#if IS_ENABLED(CONFIG_SND_SOC_INT_CODEC)
int msm_int_cdc_init(struct platform_device *pdev,
struct msm_asoc_mach_data *pdata,
struct snd_soc_card **card,
diff --git a/asoc/sdm845.c b/asoc/sdm845.c
index 0506636..f8c0444 100644
--- a/asoc/sdm845.c
+++ b/asoc/sdm845.c
@@ -70,7 +70,6 @@
#define WCN_CDC_SLIM_TX_CH_MAX 3
#define TDM_CHANNEL_MAX 8
-#define TDM_SLOT_OFFSET_MAX 8
#define MSM_HIFI_ON 1
@@ -311,17 +310,6 @@
}
};
-/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */
-static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = {
- {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */
- {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */
- {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */
- {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */
- {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */
- {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */
- {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */
- {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */
-};
/* Default configuration of slimbus channels */
static struct dev_config slim_rx_cfg[] = {
@@ -432,8 +420,8 @@
"Five", "Six", "Seven", "Eight"};
static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
- "KHZ_44P1", "KHZ_48", "KHZ_96",
- "KHZ_192", "KHZ_352P8", "KHZ_384"};
+ "KHZ_48", "KHZ_176P4",
+ "KHZ_352P8"};
static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
"KHZ_32", "KHZ_44P1", "KHZ_48",
@@ -1620,23 +1608,14 @@
sample_rate = SAMPLING_RATE_32KHZ;
break;
case 3:
- sample_rate = SAMPLING_RATE_44P1KHZ;
- break;
- case 4:
sample_rate = SAMPLING_RATE_48KHZ;
break;
+ case 4:
+ sample_rate = SAMPLING_RATE_176P4KHZ;
+ break;
case 5:
- sample_rate = SAMPLING_RATE_96KHZ;
- break;
- case 6:
- sample_rate = SAMPLING_RATE_192KHZ;
- break;
- case 7:
sample_rate = SAMPLING_RATE_352P8KHZ;
break;
- case 8:
- sample_rate = SAMPLING_RATE_384KHZ;
- break;
default:
sample_rate = SAMPLING_RATE_48KHZ;
break;
@@ -1674,26 +1653,17 @@
case SAMPLING_RATE_32KHZ:
sample_rate_val = 2;
break;
- case SAMPLING_RATE_44P1KHZ:
+ case SAMPLING_RATE_48KHZ:
sample_rate_val = 3;
break;
- case SAMPLING_RATE_48KHZ:
+ case SAMPLING_RATE_176P4KHZ:
sample_rate_val = 4;
break;
- case SAMPLING_RATE_96KHZ:
- sample_rate_val = 5;
- break;
- case SAMPLING_RATE_192KHZ:
- sample_rate_val = 6;
- break;
case SAMPLING_RATE_352P8KHZ:
- sample_rate_val = 7;
- break;
- case SAMPLING_RATE_384KHZ:
- sample_rate_val = 8;
+ sample_rate_val = 5;
break;
default:
- sample_rate_val = 4;
+ sample_rate_val = 3;
break;
}
return sample_rate_val;
@@ -4497,15 +4467,46 @@
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret = 0;
- int channels, slot_width, slots;
+ int slot_width = 32;
+ int channels, slots;
unsigned int slot_mask, rate, clk_freq;
unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
- slot_width = 32;
pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ /* currently only supporting TDM_RX_0 and TDM_TX_0 */
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_RX:
+ slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX:
+ slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX:
slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX:
+ slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX:
+ slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX:
+ slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
+ break;
+ default:
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
/*2 slot config - bits 0 and 1 set for the first two slots */
slot_mask = 0x0000FFFF >> (16-slots);
channels = slots;
@@ -4529,7 +4530,6 @@
goto end;
}
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
/*2 slot config - bits 0 and 1 set for the first two slots */
slot_mask = 0x0000FFFF >> (16-slots);
channels = slots;
@@ -4574,14 +4574,19 @@
{
int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_card *card = rtd->card;
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
- ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
- if (ret)
- pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
- __func__, ret);
+ /* currently only supporting TDM_RX_0 and TDM_TX_0 */
+ if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
+ (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
+ ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
+ if (ret)
+ pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+ }
return ret;
}
@@ -4590,15 +4595,19 @@
{
int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_card *card = rtd->card;
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
- ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
- if (ret)
- pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
- __func__, ret);
-
+ /* currently only supporting TDM_RX_0 and TDM_TX_0 */
+ if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
+ (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
+ ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
+ if (ret)
+ pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+ }
}
static struct snd_soc_ops sdm845_tdm_be_ops = {
@@ -4732,157 +4741,6 @@
.shutdown = msm_aux_pcm_snd_shutdown,
};
-static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width,
- int slots)
-{
- unsigned int slot_mask = 0;
- int i, j;
- unsigned int *slot_offset;
-
- for (i = TDM_0; i < TDM_PORT_MAX; i++) {
- slot_offset = tdm_slot_offset[i];
-
- for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
- if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
- slot_mask |=
- (1 << ((slot_offset[j] * 8) / slot_width));
- else
- break;
- }
- }
-
- return slot_mask;
-}
-
-static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
- int channels, slot_width, slots;
- unsigned int slot_mask;
- unsigned int *slot_offset;
- int offset_channels = 0;
- int i;
-
- pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
-
- channels = params_channels(params);
- switch (channels) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S32_LE:
- case SNDRV_PCM_FORMAT_S24_LE:
- case SNDRV_PCM_FORMAT_S16_LE:
- /*
- * Up to 8 channels HW config should
- * use 32 bit slot width for max support of
- * stream bit width. (slot_width > bit_width)
- */
- slot_width = 32;
- break;
- default:
- pr_err("%s: invalid param format 0x%x\n",
- __func__, params_format(params));
- return -EINVAL;
- }
- slots = 8;
- slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
- slot_width,
- slots);
- if (!slot_mask) {
- pr_err("%s: invalid slot_mask 0x%x\n",
- __func__, slot_mask);
- return -EINVAL;
- }
- break;
- default:
- pr_err("%s: invalid param channels %d\n",
- __func__, channels);
- return -EINVAL;
- }
- /* currently only supporting TDM_RX_0 and TDM_TX_0 */
- switch (cpu_dai->id) {
- case AFE_PORT_ID_PRIMARY_TDM_RX:
- case AFE_PORT_ID_SECONDARY_TDM_RX:
- case AFE_PORT_ID_TERTIARY_TDM_RX:
- case AFE_PORT_ID_QUATERNARY_TDM_RX:
- case AFE_PORT_ID_PRIMARY_TDM_TX:
- case AFE_PORT_ID_SECONDARY_TDM_TX:
- case AFE_PORT_ID_TERTIARY_TDM_TX:
- case AFE_PORT_ID_QUATERNARY_TDM_TX:
- slot_offset = tdm_slot_offset[TDM_0];
- break;
- default:
- pr_err("%s: dai id 0x%x not supported\n",
- __func__, cpu_dai->id);
- return -EINVAL;
- }
-
- for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
- if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
- offset_channels++;
- else
- break;
- }
-
- if (offset_channels == 0) {
- pr_err("%s: slot offset not supported, offset_channels %d\n",
- __func__, offset_channels);
- return -EINVAL;
- }
-
- if (channels > offset_channels) {
- pr_err("%s: channels %d exceed offset_channels %d\n",
- __func__, channels, offset_channels);
- return -EINVAL;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
- slots, slot_width);
- if (ret < 0) {
- pr_err("%s: failed to set tdm slot, err:%d\n",
- __func__, ret);
- goto err;
- }
-
- ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
- channels, slot_offset);
- if (ret < 0) {
- pr_err("%s: failed to set channel map, err:%d\n",
- __func__, ret);
- goto err;
- }
- } else {
- ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
- slots, slot_width);
- if (ret < 0) {
- pr_err("%s: failed to set tdm slot, err:%d\n",
- __func__, ret);
- goto err;
- }
-
- ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
- slot_offset, 0, NULL);
- if (ret < 0) {
- pr_err("%s: failed to set channel map, err:%d\n",
- __func__, ret);
- goto err;
- }
- }
-err:
- return ret;
-}
-
static struct snd_soc_ops msm_be_ops = {
.hw_params = msm_snd_hw_params,
};
@@ -4895,9 +4753,6 @@
.hw_params = msm_wcn_hw_params,
};
-static struct snd_soc_ops msm_tdm_be_ops = {
- .hw_params = msm_tdm_snd_hw_params
-};
/* Digital audio interface glue - connects codec <---> CPU */
static struct snd_soc_dai_link msm_common_dai_links[] = {
@@ -5676,7 +5531,7 @@
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
.be_hw_params_fixup = msm_be_hw_params_fixup,
- .ops = &msm_tdm_be_ops,
+ .ops = &sdm845_tdm_be_ops,
.ignore_suspend = 1,
},
{
@@ -5690,7 +5545,7 @@
.dpcm_capture = 1,
.id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
.be_hw_params_fixup = msm_be_hw_params_fixup,
- .ops = &msm_tdm_be_ops,
+ .ops = &sdm845_tdm_be_ops,
.ignore_suspend = 1,
},
{
@@ -5704,7 +5559,7 @@
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_SEC_TDM_RX_0,
.be_hw_params_fixup = msm_be_hw_params_fixup,
- .ops = &msm_tdm_be_ops,
+ .ops = &sdm845_tdm_be_ops,
.ignore_suspend = 1,
},
{
@@ -5718,7 +5573,7 @@
.dpcm_capture = 1,
.id = MSM_BACKEND_DAI_SEC_TDM_TX_0,
.be_hw_params_fixup = msm_be_hw_params_fixup,
- .ops = &msm_tdm_be_ops,
+ .ops = &sdm845_tdm_be_ops,
.ignore_suspend = 1,
},
{
@@ -5732,7 +5587,7 @@
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_TERT_TDM_RX_0,
.be_hw_params_fixup = msm_be_hw_params_fixup,
- .ops = &msm_tdm_be_ops,
+ .ops = &sdm845_tdm_be_ops,
.ignore_suspend = 1,
},
{
@@ -5746,7 +5601,7 @@
.dpcm_capture = 1,
.id = MSM_BACKEND_DAI_TERT_TDM_TX_0,
.be_hw_params_fixup = msm_be_hw_params_fixup,
- .ops = &msm_tdm_be_ops,
+ .ops = &sdm845_tdm_be_ops,
.ignore_suspend = 1,
},
{
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index a91e119..b6a7aa3 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -2894,6 +2894,24 @@
goto exit;
}
+ if (format == ASM_MEDIA_FMT_APTX) {
+ config.param.payload_size =
+ payload_size + sizeof(config.port.sync_mode_param);
+ pr_debug("%s: sending AFE_PARAM_ID_APTX_SYNC_MODE to DSP",
+ __func__);
+ config.pdata.param_id = AFE_PARAM_ID_APTX_SYNC_MODE;
+ config.pdata.param_size = sizeof(config.port.sync_mode_param);
+ config.port.sync_mode_param.sync_mode =
+ config.port.enc_blk_param.enc_blk_config.aptx_config.
+ aptx_v2_cfg.sync_mode;
+ ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ if (ret) {
+ pr_err("%s: AFE_PARAM_ID_APTX_SYNC_MODE for port 0x%x failed %d\n",
+ __func__, port_id, ret);
+ goto exit;
+ }
+ }
+
config.param.payload_size =
payload_size + sizeof(config.port.enc_pkt_id_param);
pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP payload = %d",
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index df635cc..be56d74 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -3074,6 +3074,16 @@
u32 topology_id;
} __packed;
+#define AFE_PARAM_ID_APTX_SYNC_MODE 0x00013205
+
+struct afe_param_id_aptx_sync_mode {
+ /*
+ * sync mode: 0x0 = stereo sync mode (default)
+ * 0x01 = dual mono sync mode
+ * 0x02 = dual mono with no sync on either L or R
+ */
+ uint32_t sync_mode;
+} __packed;
/*
* Generic encoder module ID.
@@ -3305,6 +3315,21 @@
uint8_t channel_mapping[8];
uint32_t custom_size;
} __packed;
+
+struct asm_aptx_v2_enc_cfg_ext_t {
+ /*
+ * sync mode: 0x0 = stereo sync mode (default)
+ * 0x01 = dual mono sync mode
+ * 0x02 = dual mono with no sync on either L or R
+ */
+ uint32_t sync_mode;
+} __packed;
+
+struct asm_aptx_enc_cfg_t {
+ struct asm_custom_enc_cfg_t custom_cfg;
+ struct asm_aptx_v2_enc_cfg_ext_t aptx_v2_cfg;
+} __packed;
+
#define ASM_MEDIA_FMT_CELT 0x00013221
struct asm_celt_specific_enc_cfg_t {
/*
@@ -3421,6 +3446,7 @@
struct asm_aac_enc_cfg_v2_t aac_config;
struct asm_custom_enc_cfg_t custom_config;
struct asm_celt_enc_cfg_t celt_config;
+ struct asm_aptx_enc_cfg_t aptx_config;
};
struct afe_enc_config {
@@ -3461,6 +3487,7 @@
struct afe_param_id_set_topology_cfg topology;
struct afe_param_id_tdm_cfg tdm;
struct afe_param_id_usb_audio_cfg usb_audio;
+ struct afe_param_id_aptx_sync_mode sync_mode_param;
struct afe_enc_fmt_id_param_t enc_fmt;
struct afe_port_media_type_t media_type;
struct afe_enc_cfg_blk_param_t enc_blk_param;
diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c
index 1e7ead8..07a582e 100644
--- a/soc/pinctrl-lpi.c
+++ b/soc/pinctrl-lpi.c
@@ -81,7 +81,7 @@
* @function: See lpi_gpio_functions[]
*/
struct lpi_gpio_pad {
- u16 offset;
+ u32 offset;
bool output_enabled;
bool value;
char __iomem *base;
@@ -622,6 +622,7 @@
{
struct lpi_gpio_state *state = platform_get_drvdata(pdev);
+ audio_notifier_deregister("lpi_tlmm");
gpiochip_remove(&state->chip);
return 0;
}