mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
ASoC: tegra-alt: Add support for overriding the bclk ratio
To test internal loopback on any I2S interface using various different sampling frequencies, it is necessary to be able to override the bit clock ratio. However, rather than adding a kcontrol for each audio link supported by the machine driver, add a global kcontrol that when set will control the bit clock ratio for all I2S links. Bug 2025176 Change-Id: I46ec949d36f0fe34967b9ed718d2189b539a1a37 Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1602528 (cherry picked from commit 08afde21c1041db7d926b094cc9822402b73524f) Reviewed-on: https://git-master.nvidia.com/r/1655983 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
@@ -68,6 +68,7 @@ struct tegra_machine {
|
|||||||
int rate_via_kcontrol;
|
int rate_via_kcontrol;
|
||||||
bool is_hs_supported;
|
bool is_hs_supported;
|
||||||
int fmt_via_kcontrol;
|
int fmt_via_kcontrol;
|
||||||
|
unsigned int bclk_ratio_override;
|
||||||
struct tegra_machine_soc_data *soc_data;
|
struct tegra_machine_soc_data *soc_data;
|
||||||
struct regulator *digital_reg;
|
struct regulator *digital_reg;
|
||||||
struct regulator *spk_reg;
|
struct regulator *spk_reg;
|
||||||
@@ -136,6 +137,10 @@ static int tegra_machine_codec_get_format(struct snd_kcontrol *,
|
|||||||
struct snd_ctl_elem_value *);
|
struct snd_ctl_elem_value *);
|
||||||
static int tegra_machine_codec_put_format(struct snd_kcontrol *,
|
static int tegra_machine_codec_put_format(struct snd_kcontrol *,
|
||||||
struct snd_ctl_elem_value *);
|
struct snd_ctl_elem_value *);
|
||||||
|
static int tegra_machine_codec_get_bclk_ratio(struct snd_kcontrol *,
|
||||||
|
struct snd_ctl_elem_value *);
|
||||||
|
static int tegra_machine_codec_put_bclk_ratio(struct snd_kcontrol *,
|
||||||
|
struct snd_ctl_elem_value *);
|
||||||
static int tegra_machine_codec_get_jack_state(struct snd_kcontrol *,
|
static int tegra_machine_codec_get_jack_state(struct snd_kcontrol *,
|
||||||
struct snd_ctl_elem_value *);
|
struct snd_ctl_elem_value *);
|
||||||
static int tegra_machine_codec_put_jack_state(struct snd_kcontrol *,
|
static int tegra_machine_codec_put_jack_state(struct snd_kcontrol *,
|
||||||
@@ -368,6 +373,9 @@ static const struct snd_kcontrol_new tegra_machine_controls[] = {
|
|||||||
tegra_machine_codec_get_rate, tegra_machine_codec_put_rate),
|
tegra_machine_codec_get_rate, tegra_machine_codec_put_rate),
|
||||||
SOC_ENUM_EXT("codec-x format", tegra_machine_codec_format,
|
SOC_ENUM_EXT("codec-x format", tegra_machine_codec_format,
|
||||||
tegra_machine_codec_get_format, tegra_machine_codec_put_format),
|
tegra_machine_codec_get_format, tegra_machine_codec_put_format),
|
||||||
|
SOC_SINGLE_EXT("bclk ratio override", SND_SOC_NOPM, 0, INT_MAX, 0,
|
||||||
|
tegra_machine_codec_get_bclk_ratio,
|
||||||
|
tegra_machine_codec_put_bclk_ratio),
|
||||||
#ifdef CONFIG_SWITCH
|
#ifdef CONFIG_SWITCH
|
||||||
SOC_ENUM_EXT("Jack-state", tegra_machine_jack_state,
|
SOC_ENUM_EXT("Jack-state", tegra_machine_jack_state,
|
||||||
tegra_machine_codec_get_jack_state,
|
tegra_machine_codec_get_jack_state,
|
||||||
@@ -528,6 +536,28 @@ static int tegra_machine_codec_put_format(struct snd_kcontrol *kcontrol,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tegra_machine_codec_get_bclk_ratio(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||||
|
struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
|
||||||
|
|
||||||
|
ucontrol->value.integer.value[0] = machine->bclk_ratio_override;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tegra_machine_codec_put_bclk_ratio(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
||||||
|
struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
|
||||||
|
|
||||||
|
machine->bclk_ratio_override = ucontrol->value.integer.value[0];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SWITCH
|
#ifdef CONFIG_SWITCH
|
||||||
static int tegra_machine_codec_get_jack_state(struct snd_kcontrol *kcontrol,
|
static int tegra_machine_codec_get_jack_state(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
@@ -621,6 +651,23 @@ end:
|
|||||||
return rtd;
|
return rtd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tegra_machine_set_bclk_ratio(struct tegra_machine *machine,
|
||||||
|
struct snd_soc_pcm_runtime *rtd)
|
||||||
|
{
|
||||||
|
unsigned int bclk_ratio;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (machine->bclk_ratio_override) {
|
||||||
|
bclk_ratio = machine->bclk_ratio_override;
|
||||||
|
} else {
|
||||||
|
err = machine->soc_data->get_bclk_ratio(rtd, &bclk_ratio);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return snd_soc_dai_set_bclk_ratio(rtd->cpu_dai, bclk_ratio);
|
||||||
|
}
|
||||||
|
|
||||||
static int tegra_machine_set_params(struct snd_soc_card *card,
|
static int tegra_machine_set_params(struct snd_soc_card *card,
|
||||||
struct tegra_machine *machine,
|
struct tegra_machine *machine,
|
||||||
int rate,
|
int rate,
|
||||||
@@ -661,7 +708,6 @@ static int tegra_machine_set_params(struct snd_soc_card *card,
|
|||||||
if ((idx >= machine->soc_data->num_xbar_dai_links)
|
if ((idx >= machine->soc_data->num_xbar_dai_links)
|
||||||
&& (idx < num_of_dai_links)) {
|
&& (idx < num_of_dai_links)) {
|
||||||
unsigned int fmt;
|
unsigned int fmt;
|
||||||
int bclk_ratio;
|
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
/* TODO: why below overrite is needed */
|
/* TODO: why below overrite is needed */
|
||||||
@@ -669,17 +715,8 @@ static int tegra_machine_set_params(struct snd_soc_card *card,
|
|||||||
|
|
||||||
fmt = rtd->dai_link->dai_fmt;
|
fmt = rtd->dai_link->dai_fmt;
|
||||||
|
|
||||||
err = machine->soc_data->get_bclk_ratio(rtd,
|
err = tegra_machine_set_bclk_ratio(machine,
|
||||||
&bclk_ratio);
|
rtd);
|
||||||
if (err < 0) {
|
|
||||||
dev_err(card->dev,
|
|
||||||
"Failed to get bclk ratio for %s\n",
|
|
||||||
rtd->dai_link->name);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = snd_soc_dai_set_bclk_ratio(rtd->cpu_dai,
|
|
||||||
bclk_ratio);
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_err(card->dev,
|
dev_err(card->dev,
|
||||||
"Failed to set cpu dai bclk ratio for %s\n",
|
"Failed to set cpu dai bclk ratio for %s\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user