diff options
author | Venkataadiseshu Jidugu <cvjidug@codeaurora.org> | 2020-05-14 13:10:04 +0530 |
---|---|---|
committer | Venkataadiseshu Jidugu <cvjidug@codeaurora.org> | 2020-05-15 18:38:29 +0530 |
commit | 55544dfe99343829e29e4b70045f39b83d7cf851 (patch) | |
tree | cf532280e82e2b3141c9d4e7cd95f3753c6f275a | |
parent | 460e8d10e88cbba45baf76ccfdfa23ceacc6d600 (diff) |
asoc: msm-8998: TDM device grouping changes for capture path
Add support for multi port in Quat TDM capture interface.
Add front end functionality to support TDM group device capture.
Change-Id: I7d2a75a30ceabe7730d21452afd50581f20e3620
Signed-off-by: Venkataadiseshu Jidugu <cvjidug@codeaurora.org>
-rw-r--r--[-rwxr-xr-x] | sound/soc/codecs/msm_stub.c | 17 | ||||
-rw-r--r-- | sound/soc/msm/msm-dai-fe.c | 7 | ||||
-rw-r--r-- | sound/soc/msm/msm8998.c | 412 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c | 22 |
4 files changed, 290 insertions, 168 deletions
diff --git a/sound/soc/codecs/msm_stub.c b/sound/soc/codecs/msm_stub.c index 9a9c54e4a74f..ffb3f84c0927 100755..100644 --- a/sound/soc/codecs/msm_stub.c +++ b/sound/soc/codecs/msm_stub.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2020, 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 @@ -24,9 +24,12 @@ static struct snd_soc_dai_driver msm_stub_dais[] = { .playback = { /* Support maximum range */ .stream_name = "Playback", .channels_min = 1, - .channels_max = 8, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_max = 16, + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), }, }, { @@ -34,10 +37,12 @@ static struct snd_soc_dai_driver msm_stub_dais[] = { .capture = { /* Support maximum range */ .stream_name = "Record", .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rates = SNDRV_PCM_RATE_8000_48000, .formats = (SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE), + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), }, }, }; diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c index c9178fb3b8a3..729c29606a67 100644 --- a/sound/soc/msm/msm-dai-fe.c +++ b/sound/soc/msm/msm-dai-fe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 2020, 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 @@ -2164,7 +2164,10 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .aif_name = "MM_UL9", .rates = (SNDRV_PCM_RATE_8000_48000| SNDRV_PCM_RATE_KNOT), - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = (SNDRV_PCM_FMTBIT_S16_LE| + SNDRV_PCM_FMTBIT_S24_LE| + SNDRV_PCM_FMTBIT_S24_3LE| + SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, .channels_max = 32, .rate_min = 8000, diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c index 1c1f65fb3f5c..c613002d8646 100644 --- a/sound/soc/msm/msm8998.c +++ b/sound/soc/msm/msm8998.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, 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,30 @@ #define MSM_HIFI_ON 1 enum { + PRIMARY_TDM_RX_0, + PRIMARY_TDM_RX_1, + PRIMARY_TDM_RX_2, + PRIMARY_TDM_RX_3, + PRIMARY_TDM_RX_4, + PRIMARY_TDM_RX_5, + PRIMARY_TDM_RX_6, + PRIMARY_TDM_RX_7, + TDM_MAX_RX, +}; + +enum { + PRIMARY_TDM_TX_0, + PRIMARY_TDM_TX_1, + PRIMARY_TDM_TX_2, + PRIMARY_TDM_TX_3, + PRIMARY_TDM_TX_4, + PRIMARY_TDM_TX_5, + PRIMARY_TDM_TX_6, + PRIMARY_TDM_TX_7, + TDM_MAX_TX, +}; + +enum { SLIM_RX_0 = 0, SLIM_RX_1, SLIM_RX_2, @@ -306,18 +330,6 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { } }; -/*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[] = { [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, @@ -3264,18 +3276,45 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, tdm_tx_sample_rate_get, tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, tdm_rx_format_get, tdm_rx_format_put), SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, tdm_tx_format_get, tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, tdm_rx_ch_get, tdm_rx_ch_put), SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, tdm_tx_ch_get, tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), SOC_ENUM_EXT("PRI_TDM SlotNumber", tdm_slot_num, tdm_slot_num_get, tdm_slot_num_put), SOC_ENUM_EXT("PRI_TDM SlotWidth", tdm_slot_width, @@ -5663,19 +5702,84 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } -static unsigned int tdm_param_set_slot_mask(int slots) +static unsigned int msm8998_tdm_param_set_slot_mask(u16 port_id, int slot_width, + int slots, int tdm_interface) { unsigned int slot_mask = 0; - int i = 0; + int upper, lower, i, j, rx_path = 0; + unsigned int *slot_offset; - if ((slots <= 0) || (slots > 32)) { - pr_err("%s: invalid slot number %d\n", __func__, slots); - return -EINVAL; - } + switch (port_id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + lower = PRIMARY_TDM_RX_0; + upper = PRIMARY_TDM_RX_7; + rx_path = 1; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + lower = PRIMARY_TDM_RX_0; + upper = PRIMARY_TDM_RX_7; + rx_path = 1; + break; - for (i = 0; i < slots ; i++) - slot_mask |= 1 << i; + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + lower = PRIMARY_TDM_TX_0; + upper = PRIMARY_TDM_TX_7; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + lower = PRIMARY_TDM_TX_0; + upper = PRIMARY_TDM_TX_7; + break; + default: + return slot_mask; + } + for (i = lower; i <= upper; i++) { + if (rx_path) + slot_offset = tdm_rx_slot_offset[tdm_interface][i]; + else + slot_offset = tdm_tx_slot_offset[tdm_interface][i]; + + for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { + if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) { + /* + * set the mask of active slot according to + * the offset table for the group of devices + */ + slot_mask |= + (1 << ((slot_offset[j] * 8) / slot_width)); + } else { + break; + } + } + } return slot_mask; } @@ -5685,7 +5789,7 @@ static int msm8998_tdm_snd_hw_params(struct snd_pcm_substream *substream, 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, rate, format; + int channels, slot_width, slots, rate, format, tdm_interface; unsigned int slot_mask; unsigned int *slot_offset; int offset_channels = 0; @@ -5720,321 +5824,385 @@ static int msm8998_tdm_snd_hw_params(struct snd_pcm_substream *substream, slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_0]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_RX_1: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_1]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_RX_2: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_2]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_RX_3: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_3]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_RX_4: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_4]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_RX_5: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_5]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_RX_6: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_6]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_RX_7: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_7]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_TX: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_0]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_TX_1: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_1]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_TX_2: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_2]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_TX_3: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_3]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_TX_4: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_4]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_TX_5: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_5]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_TX_6: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_6]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_PRIMARY_TDM_TX_7: slots = tdm_slot[TDM_PRI].num; slot_width = tdm_slot[TDM_PRI].width; slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_7]; + tdm_interface = TDM_PRI; break; case AFE_PORT_ID_SECONDARY_TDM_RX: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_0]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_RX_1: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_1]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_RX_2: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_2]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_RX_3: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_3]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_RX_4: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_4]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_RX_5: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_5]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_RX_6: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_6]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_RX_7: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_7]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_TX: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_0]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_TX_1: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_1]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_TX_2: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_2]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_TX_3: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_3]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_TX_4: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_4]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_TX_5: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_5]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_TX_6: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_6]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_SECONDARY_TDM_TX_7: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_7]; + tdm_interface = TDM_SEC; break; case AFE_PORT_ID_TERTIARY_TDM_RX: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_0]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_RX_1: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_1]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_RX_2: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_2]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_RX_3: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_3]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_RX_4: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_4]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_RX_5: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_5]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_RX_6: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_6]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_RX_7: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_7]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_TX: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_0]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_TX_1: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_1]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_TX_2: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_2]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_TX_3: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_3]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_TX_4: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_4]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_TX_5: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_5]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_TX_6: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_6]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_TERTIARY_TDM_TX_7: slots = tdm_slot[TDM_TERT].num; slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_7]; + tdm_interface = TDM_TERT; break; case AFE_PORT_ID_QUATERNARY_TDM_RX: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_0]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_RX_1: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_1]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_RX_2: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_2]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_RX_3: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_3]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_RX_4: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_4]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_RX_5: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_5]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_RX_6: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_6]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_RX_7: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_7]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_TX: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_0]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_TX_1: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_1]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_TX_2: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_2]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_TX_3: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_3]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_TX_4: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_4]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_TX_5: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_5]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_TX_6: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_6]; + tdm_interface = TDM_QUAT; break; case AFE_PORT_ID_QUATERNARY_TDM_TX_7: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_7]; + tdm_interface = TDM_QUAT; break; default: pr_err("%s: dai id 0x%x not supported\n", @@ -6061,7 +6229,10 @@ static int msm8998_tdm_snd_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - slot_mask = tdm_param_set_slot_mask(slots); + slot_mask = msm8998_tdm_param_set_slot_mask(cpu_dai->id, + slot_width, slots, tdm_interface); + pr_debug("%s: slot_mask :%x\n", __func__, slot_mask); + if (!slot_mask) { pr_err("%s: invalid slot_mask 0x%x\n", __func__, slot_mask); @@ -6282,133 +6453,6 @@ static struct snd_soc_ops msm_aux_pcm_be_ops = { .shutdown = msm_aux_pcm_snd_shutdown, }; -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(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 end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, - channels, slot_offset); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto end; - } - } else { - ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", - __func__, ret); - goto end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, channels, - slot_offset, 0, NULL); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto end; - } - } -end: - return ret; -} - static struct snd_soc_ops msm_be_ops = { .hw_params = msm_snd_hw_params, }; @@ -6425,10 +6469,6 @@ static struct snd_soc_ops msm_wcn_ops = { .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[] = { /* FrontEnd DAI Links */ @@ -7434,7 +7474,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_playback = 1, .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &msm8998_tdm_be_ops, .ignore_suspend = 1, }, { @@ -7448,7 +7488,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_capture = 1, .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &msm8998_tdm_be_ops, .ignore_suspend = 1, }, { @@ -7462,7 +7502,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_playback = 1, .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &msm8998_tdm_be_ops, .ignore_suspend = 1, }, { @@ -7476,7 +7516,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_capture = 1, .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &msm8998_tdm_be_ops, .ignore_suspend = 1, }, { @@ -8201,6 +8241,51 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_ext_tdm_tx_group_be_dai[] = { + { + .name = LPASS_BE_QUAT_TDM_TX_1, + .stream_name = "Quaternary TDM1 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36915", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8998_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_2, + .stream_name = "Quaternary TDM2 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36917", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8998_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_3, + .stream_name = "Quaternary TDM3 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36919", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8998_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link msm_tasha_dai_links[ ARRAY_SIZE(msm_common_dai_links) + ARRAY_SIZE(msm_tasha_fe_dai_links) + @@ -8210,7 +8295,8 @@ static struct snd_soc_dai_link msm_tasha_dai_links[ ARRAY_SIZE(msm_wcn_be_dai_links) + ARRAY_SIZE(ext_disp_be_dai_link) + ARRAY_SIZE(msm_mi2s_be_dai_links) + - ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + ARRAY_SIZE(msm_auxpcm_be_dai_links) + + ARRAY_SIZE(msm_ext_tdm_tx_group_be_dai)]; static struct snd_soc_dai_link msm_tavil_dai_links[ ARRAY_SIZE(msm_common_dai_links) + @@ -8615,6 +8701,14 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) sizeof(msm_auxpcm_be_dai_links)); total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); } + if (of_property_read_bool(dev->of_node, + "qcom,tdm-tx-group-enable")) { + dev_dbg(dev, "%s(): TDM Tx group enable\n", __func__); + memcpy(msm_tasha_dai_links + total_links, + msm_ext_tdm_tx_group_be_dai, + sizeof(msm_ext_tdm_tx_group_be_dai)); + total_links += ARRAY_SIZE(msm_ext_tdm_tx_group_be_dai); + } dailink = msm_tasha_dai_links; } else if (!strcmp(match->data, "tavil_codec")) { card = &snd_soc_card_tavil_msm; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index ed3ee03553b3..975ef01434a9 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, 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 @@ -10504,6 +10504,22 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, @@ -18508,6 +18524,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia9 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia9 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia9 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia9 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, |