diff --git a/asoc/sdm845.c b/asoc/sdm845.c index 5721c323e0b5..72948823db92 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 @@ 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[] = { @@ -431,8 +419,8 @@ static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "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", @@ -1614,23 +1602,14 @@ static int tdm_get_sample_rate(int value) 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; @@ -1668,26 +1647,17 @@ static int tdm_get_sample_rate_val(int sample_rate) 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; @@ -4491,15 +4461,46 @@ static int sdm845_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; + 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; @@ -4523,7 +4524,6 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream, 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; @@ -4568,14 +4568,19 @@ static int sdm845_tdm_snd_startup(struct snd_pcm_substream *substream) { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 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; } @@ -4584,15 +4589,19 @@ static void sdm845_tdm_snd_shutdown(struct snd_pcm_substream *substream) { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 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 = { @@ -4726,157 +4735,6 @@ static struct snd_soc_ops msm_aux_pcm_be_ops = { .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, }; @@ -4889,9 +4747,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[] = { @@ -5670,7 +5525,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .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, }, { @@ -5684,7 +5539,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .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, }, { @@ -5698,7 +5553,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .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, }, { @@ -5712,7 +5567,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .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, }, { @@ -5726,7 +5581,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .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, }, { @@ -5740,7 +5595,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .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, }, {