From 78f655e85e6a1062f803e31722096f4458bf2c22 Mon Sep 17 00:00:00 2001 From: sheetal Date: Fri, 6 Aug 2021 10:29:46 +0530 Subject: [PATCH] ASoC: tegra: Add support for 24KHz and 64KHz rate - Fix the issues with 24KHz and 64KHz sample rate. - In machine driver, 24KHz and 64KHz were not supported, add the rates into the list. - 24KHz is not supported by ALSA, to support it mentioned dai rates as SNDRV_PCM_RATE_KNOT. Using KNOT chip can support unconventional rates, defined in hw constraints list. - The change is added for FE links only, for BE links its not required as it will be taken care by FE links. Bug 200757915 Change-Id: I348368420316ba78b303cd27a413048b6cab2dd7 Signed-off-by: sheetal Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.10/+/2571687 Tested-by: mobile promotions Reviewed-by: mobile promotions --- sound/soc/tegra/tegra210_admaif.c | 30 ++++++++++++++++++++++++------ sound/soc/tegra/tegra210_ahub.c | 21 +++++++++++++++++++++ sound/soc/tegra/tegra210_ahub.h | 7 ++++--- sound/soc/tegra/tegra_asoc_utils.c | 3 +++ 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c index 9d52f24c..b53f5bb1 100644 --- a/sound/soc/tegra/tegra210_admaif.c +++ b/sound/soc/tegra/tegra210_admaif.c @@ -40,6 +40,16 @@ chip ## _ADMAIF_TX_BASE, \ chip ## _ADMAIF_RX_BASE) +static unsigned int tegra_supported_admaif_rate[] = { + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, + 64000, 88200, 96000, 176400, 192000, +}; + +static struct snd_pcm_hw_constraint_list tegra_admaif_rate_constraints = { + .count = ARRAY_SIZE(tegra_supported_admaif_rate), + .list = tegra_supported_admaif_rate, +}; + static const struct reg_default tegra186_admaif_reg_defaults[] = { {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA186_ADMAIF_GLOBAL_BASE), 0x00000003}, ADMAIF_REG_DEFAULTS(1, TEGRA186), @@ -445,8 +455,16 @@ static int tegra_admaif_trigger(struct snd_pcm_substream *substream, int cmd, } } +static int tegra_admaif_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &tegra_admaif_rate_constraints); +} + static const struct snd_soc_dai_ops tegra_admaif_dai_ops = { .hw_params = tegra_admaif_hw_params, + .startup = tegra_admaif_startup, .trigger = tegra_admaif_trigger, .shutdown = tegra_admaif_shutdown, .prepare = tegra_admaif_prepare, @@ -595,7 +613,7 @@ static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) .stream_name = dai_name " Playback", \ .channels_min = 1, \ .channels_max = 16, \ - .rates = SNDRV_PCM_RATE_8000_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ @@ -605,7 +623,7 @@ static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) .stream_name = dai_name " Capture", \ .channels_min = 1, \ .channels_max = 16, \ - .rates = SNDRV_PCM_RATE_8000_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ @@ -621,7 +639,7 @@ static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) .stream_name = "ADMAIF" #id " FIFO Transmit", \ .channels_min = 1, \ .channels_max = 16, \ - .rates = SNDRV_PCM_RATE_8000_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ @@ -631,7 +649,7 @@ static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) .stream_name = "ADMAIF" #id " FIFO Receive", \ .channels_min = 1, \ .channels_max = 16, \ - .rates = SNDRV_PCM_RATE_8000_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ @@ -647,7 +665,7 @@ static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) .stream_name = "ADMAIF" #id " CIF Transmit", \ .channels_min = 1, \ .channels_max = 16, \ - .rates = SNDRV_PCM_RATE_8000_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ @@ -657,7 +675,7 @@ static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) .stream_name = "ADMAIF" #id " CIF Receive", \ .channels_min = 1, \ .channels_max = 16, \ - .rates = SNDRV_PCM_RATE_8000_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c index 5aad1d31..27e98f4d 100644 --- a/sound/soc/tegra/tegra210_ahub.c +++ b/sound/soc/tegra/tegra210_ahub.c @@ -14,6 +14,16 @@ #include #include "tegra210_ahub.h" +static unsigned int tegra_supported_ahub_rate[] = { + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, + 64000, 88200, 96000, 176400, 192000, +}; + +static struct snd_pcm_hw_constraint_list tegra_ahub_rate_constraints = { + .count = ARRAY_SIZE(tegra_supported_ahub_rate), + .list = tegra_supported_ahub_rate, +}; + static int tegra_ahub_get_value_enum(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) { @@ -136,6 +146,17 @@ void tegra210_ahub_read_ram(struct regmap *regmap, unsigned int reg_ctrl, } EXPORT_SYMBOL_GPL(tegra210_ahub_read_ram); +static int tegra_ahub_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &tegra_ahub_rate_constraints); +} + +static struct snd_soc_dai_ops tegra_ahub_dai_ops = { + .startup = tegra_ahub_startup, +}; + static struct snd_soc_dai_driver tegra210_ahub_dais[] = { DAI(ADMAIF1), DAI(ADMAIF2), diff --git a/sound/soc/tegra/tegra210_ahub.h b/sound/soc/tegra/tegra210_ahub.h index a6631824..8a4b8a66 100644 --- a/sound/soc/tegra/tegra210_ahub.h +++ b/sound/soc/tegra/tegra210_ahub.h @@ -2,7 +2,7 @@ /* * tegra210_ahub.h - TEGRA210 AHUB * - * Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-2021 NVIDIA CORPORATION. All rights reserved. * */ @@ -102,7 +102,7 @@ .stream_name = #sname " XBAR-Playback", \ .channels_min = 1, \ .channels_max = 16, \ - .rates = SNDRV_PCM_RATE_8000_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ @@ -112,12 +112,13 @@ .stream_name = #sname " XBAR-Capture", \ .channels_min = 1, \ .channels_max = 16, \ - .rates = SNDRV_PCM_RATE_8000_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE, \ }, \ + .ops = &tegra_ahub_dai_ops, \ } struct tegra_ahub_soc_data { diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index 4c98e6d0..e0e83ad0 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -50,6 +50,7 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, break; case 8000: case 16000: + case 24000: case 32000: case 48000: case 64000: @@ -189,8 +190,10 @@ int tegra_asoc_utils_set_tegra210_rate(struct tegra_asoc_utils_data *data, break; case 8000: case 16000: + case 24000: case 32000: case 48000: + case 64000: case 96000: case 192000: new_pll_base = data->pll_base_rate[EVEN_RATE];