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 <sheetal@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.10/+/2571687
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
sheetal
2021-08-06 10:29:46 +05:30
committed by Sameer Pujar
parent 85258fddea
commit 78f655e85e
4 changed files with 52 additions and 9 deletions

View File

@@ -40,6 +40,16 @@
chip ## _ADMAIF_TX_BASE, \ chip ## _ADMAIF_TX_BASE, \
chip ## _ADMAIF_RX_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[] = { static const struct reg_default tegra186_admaif_reg_defaults[] = {
{(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA186_ADMAIF_GLOBAL_BASE), 0x00000003}, {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA186_ADMAIF_GLOBAL_BASE), 0x00000003},
ADMAIF_REG_DEFAULTS(1, TEGRA186), 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 = { static const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
.hw_params = tegra_admaif_hw_params, .hw_params = tegra_admaif_hw_params,
.startup = tegra_admaif_startup,
.trigger = tegra_admaif_trigger, .trigger = tegra_admaif_trigger,
.shutdown = tegra_admaif_shutdown, .shutdown = tegra_admaif_shutdown,
.prepare = tegra_admaif_prepare, .prepare = tegra_admaif_prepare,
@@ -595,7 +613,7 @@ static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
.stream_name = dai_name " Playback", \ .stream_name = dai_name " Playback", \
.channels_min = 1, \ .channels_min = 1, \
.channels_max = 16, \ .channels_max = 16, \
.rates = SNDRV_PCM_RATE_8000_192000, \ .rates = SNDRV_PCM_RATE_KNOT, \
.formats = SNDRV_PCM_FMTBIT_S8 | \ .formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_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", \ .stream_name = dai_name " Capture", \
.channels_min = 1, \ .channels_min = 1, \
.channels_max = 16, \ .channels_max = 16, \
.rates = SNDRV_PCM_RATE_8000_192000, \ .rates = SNDRV_PCM_RATE_KNOT, \
.formats = SNDRV_PCM_FMTBIT_S8 | \ .formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_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", \ .stream_name = "ADMAIF" #id " FIFO Transmit", \
.channels_min = 1, \ .channels_min = 1, \
.channels_max = 16, \ .channels_max = 16, \
.rates = SNDRV_PCM_RATE_8000_192000, \ .rates = SNDRV_PCM_RATE_KNOT, \
.formats = SNDRV_PCM_FMTBIT_S8 | \ .formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_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", \ .stream_name = "ADMAIF" #id " FIFO Receive", \
.channels_min = 1, \ .channels_min = 1, \
.channels_max = 16, \ .channels_max = 16, \
.rates = SNDRV_PCM_RATE_8000_192000, \ .rates = SNDRV_PCM_RATE_KNOT, \
.formats = SNDRV_PCM_FMTBIT_S8 | \ .formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_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", \ .stream_name = "ADMAIF" #id " CIF Transmit", \
.channels_min = 1, \ .channels_min = 1, \
.channels_max = 16, \ .channels_max = 16, \
.rates = SNDRV_PCM_RATE_8000_192000, \ .rates = SNDRV_PCM_RATE_KNOT, \
.formats = SNDRV_PCM_FMTBIT_S8 | \ .formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_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", \ .stream_name = "ADMAIF" #id " CIF Receive", \
.channels_min = 1, \ .channels_min = 1, \
.channels_max = 16, \ .channels_max = 16, \
.rates = SNDRV_PCM_RATE_8000_192000, \ .rates = SNDRV_PCM_RATE_KNOT, \
.formats = SNDRV_PCM_FMTBIT_S8 | \ .formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \

View File

@@ -14,6 +14,16 @@
#include <sound/soc.h> #include <sound/soc.h>
#include "tegra210_ahub.h" #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, static int tegra_ahub_get_value_enum(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *uctl) 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); 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[] = { static struct snd_soc_dai_driver tegra210_ahub_dais[] = {
DAI(ADMAIF1), DAI(ADMAIF1),
DAI(ADMAIF2), DAI(ADMAIF2),

View File

@@ -2,7 +2,7 @@
/* /*
* tegra210_ahub.h - TEGRA210 AHUB * 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", \ .stream_name = #sname " XBAR-Playback", \
.channels_min = 1, \ .channels_min = 1, \
.channels_max = 16, \ .channels_max = 16, \
.rates = SNDRV_PCM_RATE_8000_192000, \ .rates = SNDRV_PCM_RATE_KNOT, \
.formats = SNDRV_PCM_FMTBIT_S8 | \ .formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \
@@ -112,12 +112,13 @@
.stream_name = #sname " XBAR-Capture", \ .stream_name = #sname " XBAR-Capture", \
.channels_min = 1, \ .channels_min = 1, \
.channels_max = 16, \ .channels_max = 16, \
.rates = SNDRV_PCM_RATE_8000_192000, \ .rates = SNDRV_PCM_RATE_KNOT, \
.formats = SNDRV_PCM_FMTBIT_S8 | \ .formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE, \ SNDRV_PCM_FMTBIT_S32_LE, \
}, \ }, \
.ops = &tegra_ahub_dai_ops, \
} }
struct tegra_ahub_soc_data { struct tegra_ahub_soc_data {

View File

@@ -50,6 +50,7 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
break; break;
case 8000: case 8000:
case 16000: case 16000:
case 24000:
case 32000: case 32000:
case 48000: case 48000:
case 64000: case 64000:
@@ -189,8 +190,10 @@ int tegra_asoc_utils_set_tegra210_rate(struct tegra_asoc_utils_data *data,
break; break;
case 8000: case 8000:
case 16000: case 16000:
case 24000:
case 32000: case 32000:
case 48000: case 48000:
case 64000:
case 96000: case 96000:
case 192000: case 192000:
new_pll_base = data->pll_base_rate[EVEN_RATE]; new_pll_base = data->pll_base_rate[EVEN_RATE];