diff --git a/sound/soc/tegra-alt/include/tegra_asoc_utils_alt.h b/sound/soc/tegra-alt/include/tegra_asoc_utils_alt.h index dbb0e3db..4428a220 100644 --- a/sound/soc/tegra-alt/include/tegra_asoc_utils_alt.h +++ b/sound/soc/tegra-alt/include/tegra_asoc_utils_alt.h @@ -59,17 +59,18 @@ struct tegra_asoc_audio_clock_info { int set_mclk; int lock_count; int set_baseclock; - int set_clk_out_rate; int num_clk; - unsigned int clk_out_rate; - unsigned int mclk_scale; + struct clk *clk_mclk_parent; + u32 set_clk_out_rate; + u32 mclk_rate; + u32 mclk_scale; u32 clk_rates[MAX_NUM_RATES]; }; int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data, int srate, int mclk, - int clk_out_rate); + u32 clk_out_rate); void tegra_alt_asoc_utils_lock_clk_rate( struct tegra_asoc_audio_clock_info *data, int lock); 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 88dc5235..bf96a788 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 @@ -514,10 +514,11 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime, } if (machine->soc_data->is_clk_rate_via_dt) - clk_out_rate = machine->audio_clock.clk_out_rate; + clk_out_rate = machine->audio_clock.set_clk_out_rate; pr_debug("pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n", - machine->audio_clock.set_mclk, clk_out_rate, clk_rate); + machine->audio_clock.set_mclk, + machine->audio_clock.set_clk_out_rate, clk_rate); /* TODO: should we pass here clk_rate ? */ err = tegra_machine_set_params(card, machine, rate, channels, formats); @@ -1075,6 +1076,16 @@ static int tegra_machine_driver_probe(struct platform_device *pdev) if (ret) goto err; + if (of_property_read_u32(np, "nvidia,mclk-rate", + &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 = 256; + dev_dbg(&pdev->dev, "Missing property mclk-fs\n"); + } + if (machine->soc_data->is_clk_rate_via_dt) { if (of_property_read_u32(np, "nvidia,num-clk", &machine->audio_clock.num_clk) < 0) { diff --git a/sound/soc/tegra-alt/utils/tegra_asoc_utils_alt.c b/sound/soc/tegra-alt/utils/tegra_asoc_utils_alt.c index d84cc2a8..0bbbdcaa 100644 --- a/sound/soc/tegra-alt/utils/tegra_asoc_utils_alt.c +++ b/sound/soc/tegra-alt/utils/tegra_asoc_utils_alt.c @@ -40,7 +40,7 @@ int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data, int srate, int mclk, - int clk_out_rate) + u32 clk_out_rate) { int new_baseclock; int ahub_rate = 0; @@ -67,9 +67,7 @@ int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data, mclk = mclk >> 1; ahub_rate = ahub_rate >> 1; } - clk_out_rate = srate * data->mclk_scale; - data->clk_out_rate = clk_out_rate; } break; case 8000: @@ -93,15 +91,15 @@ int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data, mclk = mclk >> 1; ahub_rate = ahub_rate >> 1; } - clk_out_rate = srate * data->mclk_scale; - data->clk_out_rate = clk_out_rate; } break; default: return -EINVAL; } + clk_out_rate = data->mclk_rate ? data->mclk_rate : clk_out_rate; + clk_change = ((new_baseclock != data->set_baseclock) || (mclk != data->set_mclk) || (clk_out_rate != data->set_clk_out_rate)); @@ -191,7 +189,6 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data, { data->dev = dev; data->card = card; - data->mclk_scale = 256; if (of_machine_is_compatible("nvidia,tegra210") || of_machine_is_compatible("nvidia,tegra210b01")) @@ -228,6 +225,14 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data, return PTR_ERR(data->clk_cdev1); } + /* 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)) + dev_dbg(data->dev, "Can't retrieve mclk parent clk\n"); + if (data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA210) { data->clk_ahub = devm_clk_get(dev, "ahub"); if (IS_ERR(data->clk_ahub)) { @@ -255,21 +260,19 @@ int tegra_alt_asoc_utils_set_extern_parent( struct tegra_asoc_audio_clock_info *data, const char *parent) { unsigned long rate; - int err; + int err = 0; rate = clk_get_rate(data->clk_cdev1); - if (!strcmp(parent, "clk_m")) { + if (!IS_ERR(data->clk_mclk_parent)) + err = clk_set_parent(data->clk_cdev1, data->clk_mclk_parent); + else if (!strcmp(parent, "clk_m")) err = clk_set_parent(data->clk_cdev1, data->clk_m); - if (err) { - dev_err(data->dev, "Can't set clk extern1 parent"); - return err; - } - } else if (!strcmp(parent, "pll_a_out0")) { + else if (!strcmp(parent, "pll_a_out0")) err = clk_set_parent(data->clk_cdev1, data->clk_pll_a_out0); - if (err) { - dev_err(data->dev, "Can't set clk cdev1/extern1 parent"); - return err; - } + + if (err) { + dev_err(data->dev, "Can't set aud mclk clock parent"); + return err; } err = clk_set_rate(data->clk_cdev1, rate);