diff options
Diffstat (limited to 'sound/soc/tegra/tegra_asoc_utils.c')
| -rw-r--r-- | sound/soc/tegra/tegra_asoc_utils.c | 82 |
1 files changed, 69 insertions, 13 deletions
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index 6872c77a119..1be311c51a1 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -43,8 +43,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, case 88200: if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) new_baseclock = 56448000; - else + else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30) new_baseclock = 564480000; + else + new_baseclock = 282240000; break; case 8000: case 16000: @@ -54,8 +56,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, case 96000: if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) new_baseclock = 73728000; - else + else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30) new_baseclock = 552960000; + else + new_baseclock = 368640000; break; default: return -EINVAL; @@ -112,6 +116,59 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, } EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate); +int tegra_asoc_utils_set_ac97_rate(struct tegra_asoc_utils_data *data) +{ + const int pll_rate = 73728000; + const int ac97_rate = 24576000; + int err; + + clk_disable_unprepare(data->clk_cdev1); + clk_disable_unprepare(data->clk_pll_a_out0); + clk_disable_unprepare(data->clk_pll_a); + + /* + * AC97 rate is fixed at 24.576MHz and is used for both the host + * controller and the external codec + */ + err = clk_set_rate(data->clk_pll_a, pll_rate); + if (err) { + dev_err(data->dev, "Can't set pll_a rate: %d\n", err); + return err; + } + + err = clk_set_rate(data->clk_pll_a_out0, ac97_rate); + if (err) { + dev_err(data->dev, "Can't set pll_a_out0 rate: %d\n", err); + return err; + } + + /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */ + + err = clk_prepare_enable(data->clk_pll_a); + if (err) { + dev_err(data->dev, "Can't enable pll_a: %d\n", err); + return err; + } + + err = clk_prepare_enable(data->clk_pll_a_out0); + if (err) { + dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err); + return err; + } + + err = clk_prepare_enable(data->clk_cdev1); + if (err) { + dev_err(data->dev, "Can't enable cdev1: %d\n", err); + return err; + } + + data->set_baseclock = pll_rate; + data->set_mclk = ac97_rate; + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_ac97_rate); + int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, struct device *dev) { @@ -123,31 +180,30 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; else if (of_machine_is_compatible("nvidia,tegra30")) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; - else if (!dev->of_node) - /* non-DT is always Tegra20 */ - data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; - else - /* DT boot, but unknown SoC */ + else if (of_machine_is_compatible("nvidia,tegra114")) + data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114; + else if (of_machine_is_compatible("nvidia,tegra124")) + data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA124; + else { + dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n"); return -EINVAL; + } - data->clk_pll_a = clk_get_sys(NULL, "pll_a"); + data->clk_pll_a = clk_get(dev, "pll_a"); if (IS_ERR(data->clk_pll_a)) { dev_err(data->dev, "Can't retrieve clk pll_a\n"); ret = PTR_ERR(data->clk_pll_a); goto err; } - data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); + data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0"); if (IS_ERR(data->clk_pll_a_out0)) { dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); ret = PTR_ERR(data->clk_pll_a_out0); goto err_put_pll_a; } - if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) - data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); - else - data->clk_cdev1 = clk_get_sys("extern1", NULL); + data->clk_cdev1 = clk_get(dev, "mclk"); if (IS_ERR(data->clk_cdev1)) { dev_err(data->dev, "Can't retrieve clk cdev1\n"); ret = PTR_ERR(data->clk_cdev1); |
