From 2cae54a567619268b68a8e48e8bf1876a07097a9 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 17 Nov 2017 11:17:22 +0000 Subject: [PATCH] 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 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 Tested-by: mobile promotions --- .../tegra_machine_driver_mobile.c | 61 +++++++++++++++---- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c b/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c index 0d7188a6..1e833e40 100644 --- a/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c +++ b/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c @@ -68,6 +68,7 @@ struct tegra_machine { int rate_via_kcontrol; bool is_hs_supported; int fmt_via_kcontrol; + unsigned int bclk_ratio_override; struct tegra_machine_soc_data *soc_data; struct regulator *digital_reg; struct regulator *spk_reg; @@ -136,6 +137,10 @@ static int tegra_machine_codec_get_format(struct snd_kcontrol *, struct snd_ctl_elem_value *); static int tegra_machine_codec_put_format(struct snd_kcontrol *, 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 *, struct snd_ctl_elem_value *); 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), SOC_ENUM_EXT("codec-x format", tegra_machine_codec_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 SOC_ENUM_EXT("Jack-state", tegra_machine_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; } +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 static int tegra_machine_codec_get_jack_state(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -621,6 +651,23 @@ end: 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, struct tegra_machine *machine, 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) && (idx < num_of_dai_links)) { unsigned int fmt; - int bclk_ratio; err = 0; /* 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; - err = machine->soc_data->get_bclk_ratio(rtd, - &bclk_ratio); - 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); + err = tegra_machine_set_bclk_ratio(machine, + rtd); if (err < 0) { dev_err(card->dev, "Failed to set cpu dai bclk ratio for %s\n",