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:
Jon Hunter
2017-11-17 11:17:22 +00:00
committed by Sameer Pujar
parent 6191131ae7
commit 2cae54a567

View File

@@ -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",