ASoC: tegra-alt: clock cleanup for machine driver

Highlights from current clock handling in machine driver(L4T/Android)
 * Tegra210 and Tegra186/194 have different approaches to update clock
   rates for pll_a, pll_a_out0, mclk and ahub.
   -> Tegra210 uses static method, where base pll_a rate is hardcoded
      in the driver.
   -> Tegra186/194 use DT driven approach, where sound node passes rates
      for above clocks. Two sets of rates are passed, one to support odd
      sample rates and one for even.
 * Some of the functions from tegra_asoc_utils_alt.c are unused
 * clock names are not really generic.

This patch has following updates.
 * Unify clock update approach. Use static array for base pll rates.
   This also helps to get rid of following sound node DT properties.
   "nvidia,num-rates"
   "nvidia,clk-rates"
 * Remove below unused functions.
   tegra_alt_asoc_utils_lock_clk_rate()
   tegra_alt_asoc_utils_register_ctls()
   tegra_alt_asoc_utils_tristate_dap()
 * clk_set_parent() functions are not needed. Instead the relationship
   can be set from DT through "assigned-clocks" binding.
 * update clock handle names to be more meaningful. However, clock names
   that are parsed in devm_clk_get() are not changed because these names
   are used in Automotive DT files under "sound_ref" node. Scope of
   current patch is limited to L4T/Android drivers and DT files.

Bug 200503387
Bug 200516191

Change-Id: Ideaf150e6e200ffbba4dcbdec4c49f1127ea25db
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2164482
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com>
Reviewed-by: Mohan Kumar D <mkumard@nvidia.com>
Reviewed-by: Sharad Gupta <sharadg@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Sameer Pujar
2019-07-28 10:40:50 +05:30
parent 5a727dbebb
commit 18c581a03e
6 changed files with 144 additions and 265 deletions

View File

@@ -205,7 +205,6 @@ struct tegra_soc_bytes {
u32 shift; /* Used as offset for ahub ram related programing */
};
int tegra210_xbar_set_clock(unsigned long rate);
void tegra210_xbar_set_cif(struct regmap *regmap, unsigned int reg,
struct tegra210_xbar_cif_conf *conf);
void tegra210_xbar_write_ahubram(struct regmap *regmap, unsigned int reg_ctrl,

View File

@@ -34,9 +34,7 @@ struct tegra_machine_soc_data {
sfc_dai_link;
bool is_asrc_available,
is_clk_rate_via_dt,
write_cdev1_state,
write_idle_bias_off_state;
write_idle_bias_off_state;
struct snd_soc_codec_conf *ahub_confs;
struct snd_soc_dai_link *ahub_links;

View File

@@ -2,7 +2,7 @@
* tegra_alt_asoc_utils.h - Definitions for MCLK and DAP Utility driver
*
* Author: Stephen Warren <swarren@nvidia.com>
* Copyright (c) 2011-2019 NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2011-2019 NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -32,7 +32,10 @@ enum tegra_asoc_utils_soc {
TEGRA_ASOC_UTILS_SOC_TEGRA194,
};
/* Maintain same order in DT entry */
/*
* Maintain same order in DT entry
* FIXME: (This would be removed going ahead)
*/
enum tegra_asoc_utils_clkrate {
PLLA_x11025_RATE,
AUD_MCLK_x11025_RATE,
@@ -49,36 +52,30 @@ struct tegra_asoc_audio_clock_info {
struct device *dev;
struct snd_soc_card *card;
enum tegra_asoc_utils_soc soc;
struct clk *clk_pll_a;
struct clk *clk_pll_a_out0;
struct clk *clk_cdev1;
struct clk *clk_pll_base;
struct clk *clk_pll_out;
struct clk *clk_aud_mclk;
struct clk *clk_ahub;
struct reset_control *clk_cdev1_rst;
struct clk *clk_pll_p_out1;
int set_mclk;
int lock_count;
int set_baseclock;
int num_clk;
struct clk *clk_mclk_parent;
u32 set_clk_out_rate;
u32 mclk_rate;
unsigned int *pll_base_rate;
u32 set_pll_base_rate;
u32 set_pll_out_rate;
u32 set_aud_mclk_rate;
u32 mclk_scale;
/* fixed MCLK rate from DT */
u32 mclk_rate;
/* FIXME: below would be removed going ahead */
u32 clk_rates[MAX_NUM_RATES];
u32 num_clk;
};
int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data,
int srate,
int mclk,
u32 clk_out_rate);
void tegra_alt_asoc_utils_lock_clk_rate(
struct tegra_asoc_audio_clock_info *data,
int lock);
unsigned int srate, unsigned int mclk,
unsigned int clk_out_rate);
int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
struct device *dev, struct snd_soc_card *card);
struct device *dev, struct snd_soc_card *card);
int tegra_alt_asoc_utils_clk_enable(struct tegra_asoc_audio_clock_info *data);
int tegra_alt_asoc_utils_clk_disable(struct tegra_asoc_audio_clock_info *data);
int tegra_alt_asoc_utils_register_ctls(struct tegra_asoc_audio_clock_info *data);
int tegra_alt_asoc_utils_tristate_dap(int id, bool tristate);
#endif

View File

@@ -70,9 +70,9 @@ static int tegra_machine_suspend_pre(struct snd_soc_card *);
static int tegra_machine_pcm_hw_params(struct snd_pcm_substream *,
struct snd_pcm_hw_params *);
static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *,
int, int, u64, bool);
unsigned int, unsigned int, u64, bool);
static int tegra_machine_set_params(struct snd_soc_card *,
struct tegra_machine *, int, int, u64);
struct tegra_machine *, unsigned int, unsigned int, u64);
static int tegra_machine_codec_get_rate(struct snd_kcontrol *,
struct snd_ctl_elem_value *);
static int tegra_machine_codec_put_rate(struct snd_kcontrol *,
@@ -94,7 +94,6 @@ static const struct tegra_machine_soc_data soc_data_tegra210 = {
#endif
.sfc_dai_link = TEGRA210_DAI_LINK_SFC1_RX,
.is_clk_rate_via_dt = false,
.write_idle_bias_off_state = false,
.ahub_links = tegra210_xbar_dai_links,
@@ -115,7 +114,6 @@ static const struct tegra_machine_soc_data soc_data_tegra186 = {
#endif
.sfc_dai_link = TEGRA186_DAI_LINK_SFC1_RX,
.is_clk_rate_via_dt = true,
.write_idle_bias_off_state = true,
.ahub_links = tegra186_xbar_dai_links,
@@ -293,10 +291,10 @@ static int tegra_machine_codec_put_format(struct snd_kcontrol *kcontrol,
}
static int tegra_machine_set_params(struct snd_soc_card *card,
struct tegra_machine *machine,
int rate,
int channels,
u64 formats)
struct tegra_machine *machine,
unsigned int rate,
unsigned int channels,
u64 formats)
{
unsigned int mask = (1 << channels) - 1;
int idx = 0, err = 0;
@@ -352,72 +350,31 @@ static int tegra_machine_set_params(struct snd_soc_card *card,
return 0;
}
static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
int rate,
int channels,
u64 formats,
bool is_playback)
unsigned int rate, unsigned int channels,
u64 formats, bool is_playback)
{
struct snd_soc_card *card = runtime->card;
struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
struct snd_soc_pcm_stream *dai_params;
unsigned int clk_out_rate = 0, mclk = 0;
int err, codec_rate, clk_rate;
unsigned int aud_mclk, srate;
int err;
struct snd_soc_pcm_runtime *rtd;
codec_rate = tegra_machine_srate_values[machine->rate_via_kcontrol];
clk_rate = (machine->rate_via_kcontrol) ? codec_rate : rate;
srate = (machine->rate_via_kcontrol) ?
tegra_machine_srate_values[machine->rate_via_kcontrol] :
rate;
if (!machine->soc_data->is_clk_rate_via_dt) {
/* TODO remove this hardcoding */
/* aud_mclk, 256 times the sample rate */
clk_out_rate = clk_rate << 8;
switch (clk_rate) {
case 11025:
mclk = 22579200;
break;
case 22050:
case 44100:
case 88200:
case 176400:
mclk = 45158400;
break;
case 8000:
mclk = 24576000;
break;
case 16000:
case 32000:
case 48000:
case 64000:
case 96000:
case 192000:
default:
mclk = 49152000;
break;
}
err = tegra210_xbar_set_clock(mclk);
if (err < 0) {
dev_err(card->dev,
"Can't configure xbar clock = %d Hz\n", mclk);
return err;
}
}
err = tegra_alt_asoc_utils_set_rate(&machine->audio_clock, clk_rate,
mclk, clk_out_rate);
err = tegra_alt_asoc_utils_set_rate(&machine->audio_clock, srate, 0, 0);
if (err < 0) {
dev_err(card->dev, "Can't configure clocks\n");
return err;
}
if (machine->soc_data->is_clk_rate_via_dt)
clk_out_rate = machine->audio_clock.set_clk_out_rate;
aud_mclk = machine->audio_clock.set_aud_mclk_rate;
pr_debug("pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n",
machine->audio_clock.set_mclk,
machine->audio_clock.set_clk_out_rate, clk_rate);
pr_debug("pll_a_out0 = %u Hz, aud_mclk = %u Hz, sample rate = %u Hz\n",
machine->audio_clock.set_pll_out_rate, aud_mclk, srate);
/* TODO: should we pass here clk_rate ? */
err = tegra_machine_set_params(card, machine, rate, channels, formats);
if (err < 0)
return err;
@@ -427,12 +384,12 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->rate_min = srate;
dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
(1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
err = snd_soc_dai_set_sysclk(rtd->codec_dai, RT5659_SCLK_S_MCLK,
clk_out_rate, SND_SOC_CLOCK_IN);
aud_mclk, SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
@@ -446,22 +403,22 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->rate_min = srate;
dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
(1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
switch (dai_params->formats) {
case SNDRV_PCM_FMTBIT_S8:
bclk_rate = clk_rate * channels * 8;
bclk_rate = srate * channels * 8;
break;
case SNDRV_PCM_FMTBIT_S16_LE:
bclk_rate = clk_rate * channels * 16;
bclk_rate = srate * channels * 16;
break;
case SNDRV_PCM_FMTBIT_S24_LE:
bclk_rate = clk_rate * channels * 24;
bclk_rate = srate * channels * 24;
break;
case SNDRV_PCM_FMTBIT_S32_LE:
bclk_rate = clk_rate * channels * 32;
bclk_rate = srate * channels * 32;
break;
default:
dev_err(card->dev, "invalid format %llu\n",
@@ -471,29 +428,26 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
err = snd_soc_dai_set_pll(rtd->codec_dai, 0,
RT5659_PLL1_S_BCLK1,
bclk_rate, clk_rate * 256);
bclk_rate, srate * 256);
if (err < 0) {
dev_err(card->dev, "failed to set codec pll\n");
return err;
}
err = snd_soc_dai_set_sysclk(rtd->codec_dai, RT5659_SCLK_S_PLL1,
clk_rate * 256, SND_SOC_CLOCK_IN);
srate * 256, SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
}
}
/* TODO: remove below spdif links if clk_rate is passed
* in tegra_machine_set_params
*/
rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-0");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->rate_min = srate;
}
rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-1");
@@ -501,7 +455,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->rate_min = srate;
}
/* set clk rate for i2s3 dai link*/
@@ -510,7 +464,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->rate_min = srate;
}
rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-3");
@@ -518,7 +472,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->rate_min = srate;
}
rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-5");
@@ -527,7 +481,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
/* update link_param to update hw_param for DAPM */
dai_params->rate_min = clk_rate;
dai_params->rate_min = srate;
dai_params->channels_min = channels;
dai_params->formats = formats;
}
@@ -539,7 +493,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
if (!strcmp(rtd->codec_dai->name, "tas2552-amplifier")) {
err = snd_soc_dai_set_sysclk(rtd->codec_dai,
TAS2552_PDM_CLK_IVCLKIN, clk_out_rate,
TAS2552_PDM_CLK_IVCLKIN, aud_mclk,
SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
@@ -555,7 +509,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
if (!strcmp(rtd->codec_dai->name, "tas2552-amplifier")) {
err = snd_soc_dai_set_sysclk(rtd->codec_dai,
TAS2552_PDM_CLK_IVCLKIN, clk_out_rate,
TAS2552_PDM_CLK_IVCLKIN, aud_mclk,
SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
@@ -569,7 +523,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->rate_min = srate;
dai_params->channels_min = channels;
dai_params->formats = formats;
}
@@ -888,35 +842,18 @@ static int tegra_machine_driver_probe(struct platform_device *pdev)
if (ret)
return ret;
memset(&machine->audio_clock, 0, sizeof(machine->audio_clock));
if (of_property_read_u32(np, "nvidia,mclk-rate",
&machine->audio_clock.mclk_rate) < 0)
&machine->audio_clock.mclk_rate) < 0)
dev_dbg(&pdev->dev, "Missing property nvidia,mclk-rate\n");
if (of_property_read_u32(np, "mclk-fs",
&machine->audio_clock.mclk_scale) < 0) {
&machine->audio_clock.mclk_scale) < 0) {
/* TODO: fix clock in DT and remove usage of default scale */
machine->audio_clock.mclk_scale = 256;
dev_dbg(&pdev->dev, "Missing property mclk-fs\n");
}
if (machine->soc_data->is_clk_rate_via_dt) {
ret = of_property_read_u32(np, "nvidia,num-clk",
&machine->audio_clock.num_clk);
if (ret < 0) {
dev_err(&pdev->dev,
"Missing property 'nvidia,num-clk'\n");
return ret;
}
ret = of_property_read_u32_array(np, "nvidia,clk-rates",
(u32 *)&machine->audio_clock.clk_rates,
machine->audio_clock.num_clk);
if (ret < 0) {
dev_err(&pdev->dev,
"Missing property 'nvidia,clk-rates'\n");
return ret;
}
}
tegra_machine_dma_set_mask(pdev);
ret = add_dai_links(pdev);

View File

@@ -32,22 +32,6 @@
static struct tegra_xbar *xbar;
int tegra210_xbar_set_clock(unsigned long rate)
{
int ret = 0;
ret = clk_set_rate(xbar->clk_parent, rate);
if (ret)
pr_info("Failed to set clock rate of pll_a_out0\n");
ret = clk_set_rate(xbar->clk, rate);
if (ret)
pr_info("Failed to set clock rate of ahub\n");
return 0;
}
EXPORT_SYMBOL_GPL(tegra210_xbar_set_clock);
void tegra210_xbar_set_cif(struct regmap *regmap, unsigned int reg,
struct tegra210_xbar_cif_conf *conf)
{

View File

@@ -26,25 +26,37 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/clk/tegra.h>
#include <linux/reset.h>
#include <sound/soc.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinconf-tegra.h>
#include "tegra_asoc_utils_alt.h"
enum rate_type {
ODD_RATE,
EVEN_RATE,
NUM_RATE_TYPE,
};
unsigned int tegra210_pll_base_rate[NUM_RATE_TYPE] = {
338688000,
368640000,
};
unsigned int tegra186_pll_base_rate[NUM_RATE_TYPE] = {
270950400,
245760000,
};
unsigned int default_pll_out_rate[NUM_RATE_TYPE] = {
45158400,
49152000,
};
int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data,
int srate,
int mclk,
u32 clk_out_rate)
unsigned int srate, unsigned int pll_out,
unsigned int aud_mclk)
{
int new_baseclock;
int ahub_rate = 0;
bool clk_change;
unsigned int new_pll_base;
int err;
switch (srate) {
@@ -53,22 +65,8 @@ int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data,
case 44100:
case 88200:
case 176400:
if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA186)
new_baseclock = 338688000;
else {
new_baseclock = data->clk_rates[PLLA_x11025_RATE];
mclk = data->clk_rates[PLLA_OUT0_x11025_RATE];
ahub_rate = data->clk_rates[AHUB_x11025_RATE];
if (srate <= 11025) {
/* half the pll_a_out0 to support lower
* sampling rate divider
*/
mclk = mclk >> 1;
ahub_rate = ahub_rate >> 1;
}
clk_out_rate = srate * data->mclk_scale;
}
new_pll_base = data->pll_base_rate[ODD_RATE];
pll_out = default_pll_out_rate[ODD_RATE];
break;
case 8000:
case 16000:
@@ -77,88 +75,67 @@ int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data,
case 64000:
case 96000:
case 192000:
if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA186)
new_baseclock = 368640000;
else {
new_baseclock = data->clk_rates[PLLA_x8000_RATE];
mclk = data->clk_rates[PLLA_OUT0_x8000_RATE];
ahub_rate = data->clk_rates[AHUB_x8000_RATE];
if (srate <= 8000) {
/* half the pll_a_out0 to support lower
* sampling rate divider
*/
mclk = mclk >> 1;
ahub_rate = ahub_rate >> 1;
}
clk_out_rate = srate * data->mclk_scale;
}
new_pll_base = data->pll_base_rate[EVEN_RATE];
pll_out = default_pll_out_rate[EVEN_RATE];
break;
default:
return -EINVAL;
}
clk_out_rate = data->mclk_rate ? data->mclk_rate : clk_out_rate;
/* reduce pll_out rate to support lower sampling rates */
if (srate <= 11025)
pll_out = pll_out >> 1;
if (data->mclk_scale)
aud_mclk = srate * data->mclk_scale;
/*
* mclk_rate is the fixed clock from DT, this overrides mclk_scale.
* TODO: manage MCLK fixed or dynamic rate from a single DT property.
*/
aud_mclk = data->mclk_rate ? data->mclk_rate : aud_mclk;
clk_change = ((new_baseclock != data->set_baseclock) ||
(mclk != data->set_mclk) ||
(clk_out_rate != data->set_clk_out_rate));
if (!clk_change)
return 0;
/* Don't change rate if already one dai-link is using it */
if (data->lock_count)
return -EINVAL;
data->set_baseclock = 0;
data->set_mclk = 0;
err = clk_set_rate(data->clk_pll_a, new_baseclock);
if (err) {
dev_err(data->dev, "Can't set pll_a rate: %d\n", err);
return err;
if (data->set_pll_base_rate != new_pll_base) {
err = clk_set_rate(data->clk_pll_base, new_pll_base);
if (err) {
dev_err(data->dev, "Can't set clk_pll_base rate: %d\n",
err);
return err;
}
data->set_pll_base_rate = new_pll_base;
}
err = clk_set_rate(data->clk_pll_a_out0, mclk);
if (err) {
dev_err(data->dev, "Can't set clk_pll_a_out0 rate: %d\n", err);
return err;
if (data->set_pll_out_rate != pll_out) {
err = clk_set_rate(data->clk_pll_out, pll_out);
if (err) {
dev_err(data->dev, "Can't set clk_pll_out rate: %d\n",
err);
return err;
}
/* TODO: remove below once ahub rate is fixed from DT */
err = clk_set_rate(data->clk_ahub, pll_out);
if (err) {
dev_err(data->dev, "Can't set ahub rate: %d\n",
err);
return err;
}
data->set_pll_out_rate = pll_out;
}
if (data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA210) {
err = clk_set_rate(data->clk_ahub, ahub_rate);
if (data->set_aud_mclk_rate != aud_mclk) {
err = clk_set_rate(data->clk_aud_mclk, aud_mclk);
if (err) {
dev_err(data->dev, "Can't set clk_cdev1 rate: %d\n",
err);
return err;
}
data->set_aud_mclk_rate = aud_mclk;
}
err = clk_set_rate(data->clk_cdev1, clk_out_rate);
if (err) {
dev_err(data->dev, "Can't set clk_cdev1 rate: %d\n", err);
return err;
}
data->set_baseclock = new_baseclock;
data->set_mclk = mclk;
data->set_clk_out_rate = clk_out_rate;
return 0;
}
EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_set_rate);
void tegra_alt_asoc_utils_lock_clk_rate(struct tegra_asoc_audio_clock_info *data,
int lock)
{
if (lock)
data->lock_count++;
else if (data->lock_count)
data->lock_count--;
}
EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_lock_clk_rate);
int tegra_alt_asoc_utils_clk_enable(struct tegra_asoc_audio_clock_info *data)
{
int err;
@@ -166,7 +143,7 @@ int tegra_alt_asoc_utils_clk_enable(struct tegra_asoc_audio_clock_info *data)
if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA186)
reset_control_reset(data->clk_cdev1_rst);
err = clk_prepare_enable(data->clk_cdev1);
err = clk_prepare_enable(data->clk_aud_mclk);
if (err) {
dev_err(data->dev, "Can't enable cdev1: %d\n", err);
return err;
@@ -178,7 +155,7 @@ EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_clk_enable);
int tegra_alt_asoc_utils_clk_disable(struct tegra_asoc_audio_clock_info *data)
{
clk_disable_unprepare(data->clk_cdev1);
clk_disable_unprepare(data->clk_aud_mclk);
return 0;
}
@@ -187,8 +164,6 @@ EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_clk_disable);
int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
struct device *dev, struct snd_soc_card *card)
{
int ret;
data->dev = dev;
data->card = card;
@@ -203,38 +178,28 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
/* DT boot, but unknown SoC */
return -EINVAL;
data->clk_pll_a = devm_clk_get(dev, "pll_a");
if (IS_ERR(data->clk_pll_a)) {
data->clk_pll_base = devm_clk_get(dev, "pll_a");
if (IS_ERR(data->clk_pll_base)) {
dev_err(data->dev, "Can't retrieve clk pll_a\n");
return PTR_ERR(data->clk_pll_a);
return PTR_ERR(data->clk_pll_base);
}
data->clk_pll_a_out0 = devm_clk_get(dev, "pll_a_out0");
if (IS_ERR(data->clk_pll_a_out0)) {
data->clk_pll_out = devm_clk_get(dev, "pll_a_out0");
if (IS_ERR(data->clk_pll_out)) {
dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
return PTR_ERR(data->clk_pll_a_out0);
return PTR_ERR(data->clk_pll_out);
}
data->clk_cdev1 = devm_clk_get(dev, "extern1");
if (IS_ERR(data->clk_cdev1)) {
data->clk_aud_mclk = devm_clk_get(dev, "extern1");
if (IS_ERR(data->clk_aud_mclk)) {
dev_err(data->dev, "Can't retrieve clk cdev1\n");
return PTR_ERR(data->clk_cdev1);
return PTR_ERR(data->clk_aud_mclk);
}
/* Control the aud mclk rate and parent for usecases which might
* need fixed rate and needs to be derived from other possible
* parents of aud mclk clk source
*/
data->clk_mclk_parent = devm_clk_get(dev, "mclk_parent");
if (IS_ERR(data->clk_mclk_parent))
data->clk_mclk_parent = data->clk_pll_a_out0;
if (data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA210) {
data->clk_ahub = devm_clk_get(dev, "ahub");
if (IS_ERR(data->clk_ahub)) {
dev_err(data->dev, "Can't retrieve clk ahub\n");
return PTR_ERR(data->clk_ahub);
}
data->clk_ahub = devm_clk_get(dev, "ahub");
if (IS_ERR(data->clk_ahub)) {
dev_err(data->dev, "Can't retrieve clk ahub\n");
return PTR_ERR(data->clk_ahub);
}
if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA186) {
@@ -248,11 +213,10 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
reset_control_reset(data->clk_cdev1_rst);
}
ret = clk_set_parent(data->clk_cdev1, data->clk_mclk_parent);
if (ret < 0) {
dev_err(card->dev, "Failed to set extern clk parent\n");
return ret;
}
if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA186)
data->pll_base_rate = tegra210_pll_base_rate;
else
data->pll_base_rate = tegra186_pll_base_rate;
return 0;
}