diff --git a/sound/soc/tegra-alt/include/tegra210_i2s_alt.h b/sound/soc/tegra-alt/include/tegra210_i2s_alt.h index 9c579f76..72b682a4 100644 --- a/sound/soc/tegra-alt/include/tegra210_i2s_alt.h +++ b/sound/soc/tegra-alt/include/tegra210_i2s_alt.h @@ -1,7 +1,7 @@ /* * tegra210_i2s_alt.h - Definitions for Tegra210 I2S driver * - * Copyright (c) 2014-2018 NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2019 NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -232,7 +232,7 @@ struct tegra210_i2s { unsigned int fsync_width; unsigned int tx_mask; unsigned int rx_mask; - unsigned int loopback; + bool loopback; unsigned int format; bool enable_cya; unsigned int rx_fifo_th; /* should be programmed interms of frames */ diff --git a/sound/soc/tegra-alt/tegra186_dspk_alt.c b/sound/soc/tegra-alt/tegra186_dspk_alt.c index bc31cf60..3c6ae56f 100644 --- a/sound/soc/tegra-alt/tegra186_dspk_alt.c +++ b/sound/soc/tegra-alt/tegra186_dspk_alt.c @@ -1,7 +1,7 @@ /* * tegra186_dspk_alt.c - Tegra186 DSPK driver * - * Copyright (c) 2015-2018 NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2015-2019 NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -94,21 +94,12 @@ static int tegra186_dspk_put_control(struct snd_kcontrol *kcontrol, static int tegra186_dspk_runtime_suspend(struct device *dev) { struct tegra186_dspk *dspk = dev_get_drvdata(dev); - int ret; regcache_cache_only(dspk->regmap, true); regcache_mark_dirty(dspk->regmap); - if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { - if (!IS_ERR(dspk->pin_idle_state) && dspk->is_pinctrl) { - ret = pinctrl_select_state( - dspk->pinctrl, dspk->pin_idle_state); - if (ret < 0) - dev_err(dev, - "setting dap pinctrl idle state failed\n"); - } + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) clk_disable_unprepare(dspk->clk_dspk); - } return 0; } @@ -118,22 +109,7 @@ static int tegra186_dspk_runtime_resume(struct device *dev) struct tegra186_dspk *dspk = dev_get_drvdata(dev); int ret; - if (dspk->prod_name) { - ret = tegra_pinctrl_config_prod(dev, dspk->prod_name); - if (ret < 0) - dev_warn(dev, "Failed to set %s setting\n", - dspk->prod_name); - } - if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { - if (!IS_ERR(dspk->pin_active_state) && dspk->is_pinctrl) { - ret = pinctrl_select_state(dspk->pinctrl, - dspk->pin_active_state); - if (ret < 0) - dev_err(dev, - "setting dap pinctrl active state failed\n"); - } - ret = clk_prepare_enable(dspk->clk_dspk); if (ret) { dev_err(dev, "clk_enable failed: %d\n", ret); @@ -214,6 +190,53 @@ static int tegra186_dspk_set_dai_bclk_ratio(struct snd_soc_dai *dai, return 0; } +static int tegra186_dspk_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct device *dev = dai->dev; + struct tegra186_dspk *dspk = snd_soc_dai_get_drvdata(dai); + int ret; + + if (dspk->prod_name != NULL) { + ret = tegra_pinctrl_config_prod(dev, dspk->prod_name); + if (ret < 0) + dev_warn(dev, "Failed to set %s setting\n", + dspk->prod_name); + } + + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + if (!IS_ERR(dspk->pin_active_state) && dspk->is_pinctrl) { + ret = pinctrl_select_state(dspk->pinctrl, + dspk->pin_active_state); + if (ret < 0) { + dev_err(dev, + "setting dap pinctrl active state failed\n"); + } + } + } + + return 0; +} + +static void tegra186_dspk_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct device *dev = dai->dev; + struct tegra186_dspk *dspk = snd_soc_dai_get_drvdata(dai); + int ret; + + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + if (!IS_ERR(dspk->pin_idle_state) && dspk->is_pinctrl) { + ret = pinctrl_select_state( + dspk->pinctrl, dspk->pin_idle_state); + if (ret < 0) { + dev_err(dev, + "setting dap pinctrl idle state failed\n"); + } + } + } +} + static int tegra186_dspk_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -273,6 +296,8 @@ static int tegra186_dspk_codec_probe(struct snd_soc_codec *codec) static struct snd_soc_dai_ops tegra186_dspk_dai_ops = { .hw_params = tegra186_dspk_hw_params, .set_bclk_ratio = tegra186_dspk_set_dai_bclk_ratio, + .startup = tegra186_dspk_startup, + .shutdown = tegra186_dspk_shutdown, }; static struct snd_soc_dai_driver tegra186_dspk_dais[] = { diff --git a/sound/soc/tegra-alt/tegra210_dmic_alt.c b/sound/soc/tegra-alt/tegra210_dmic_alt.c index fd0baebe..1e15c146 100644 --- a/sound/soc/tegra-alt/tegra210_dmic_alt.c +++ b/sound/soc/tegra-alt/tegra210_dmic_alt.c @@ -75,22 +75,12 @@ static const struct reg_default tegra210_dmic_reg_defaults[] = { static int tegra210_dmic_runtime_suspend(struct device *dev) { struct tegra210_dmic *dmic = dev_get_drvdata(dev); - int ret; regcache_cache_only(dmic->regmap, true); regcache_mark_dirty(dmic->regmap); - if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { - if (!IS_ERR(dmic->pin_idle_state) && dmic->is_pinctrl) { - ret = pinctrl_select_state( - dmic->pinctrl, dmic->pin_idle_state); - if (ret < 0) - dev_err(dev, - "setting dap pinctrl idle state failed\n"); - } - + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) clk_disable_unprepare(dmic->clk_dmic); - } return 0; } @@ -100,22 +90,7 @@ static int tegra210_dmic_runtime_resume(struct device *dev) struct tegra210_dmic *dmic = dev_get_drvdata(dev); int ret; - if (dmic->prod_name) { - ret = tegra_pinctrl_config_prod(dev, dmic->prod_name); - if (ret < 0) - dev_warn(dev, "Failed to set %s setting\n", - dmic->prod_name); - } - if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { - if (!IS_ERR(dmic->pin_active_state) && dmic->is_pinctrl) { - ret = pinctrl_select_state(dmic->pinctrl, - dmic->pin_active_state); - if (ret < 0) - dev_err(dev, - "setting dap pinctrl active state failed\n"); - } - ret = clk_prepare_enable(dmic->clk_dmic); if (ret) { dev_err(dev, "clk_enable failed: %d\n", ret); @@ -123,7 +98,6 @@ static int tegra210_dmic_runtime_resume(struct device *dev) } } - regcache_cache_only(dmic->regmap, false); if (!dmic->is_shutdown) @@ -251,6 +225,52 @@ int tegra210_dmic_set_start_callback(int id, void (*callback)(void)) } EXPORT_SYMBOL_GPL(tegra210_dmic_set_start_callback); +static int tegra210_dmic_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct device *dev = dai->dev; + struct tegra210_dmic *dmic = snd_soc_dai_get_drvdata(dai); + int ret; + + if (dmic->prod_name != NULL) { + ret = tegra_pinctrl_config_prod(dev, dmic->prod_name); + if (ret < 0) { + dev_warn(dev, "Failed to set %s setting\n", + dmic->prod_name); + } + } + + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + if (!IS_ERR(dmic->pin_active_state) && dmic->is_pinctrl) { + ret = pinctrl_select_state(dmic->pinctrl, + dmic->pin_active_state); + if (ret < 0) { + dev_err(dev, + "setting dap pinctrl active state failed\n"); + } + } + } + return 0; +} + +static void tegra210_dmic_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct device *dev = dai->dev; + struct tegra210_dmic *dmic = snd_soc_dai_get_drvdata(dai); + int ret; + + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + if (!IS_ERR(dmic->pin_idle_state) && dmic->is_pinctrl) { + ret = pinctrl_select_state( + dmic->pinctrl, dmic->pin_idle_state); + if (ret < 0) + dev_err(dev, + "setting dap pinctrl idle state failed\n"); + } + } +} + static int tegra210_dmic_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -468,6 +488,8 @@ static int tegra210_dmic_codec_probe(struct snd_soc_codec *codec) static struct snd_soc_dai_ops tegra210_dmic_dai_ops = { .hw_params = tegra210_dmic_hw_params, .set_bclk_ratio = tegra210_dmic_set_dai_bclk_ratio, + .startup = tegra210_dmic_startup, + .shutdown = tegra210_dmic_shutdown, }; static struct snd_soc_dai_driver tegra210_dmic_dais[] = { diff --git a/sound/soc/tegra-alt/tegra210_i2s_alt.c b/sound/soc/tegra-alt/tegra210_i2s_alt.c index 2503b033..eac063c9 100644 --- a/sound/soc/tegra-alt/tegra210_i2s_alt.c +++ b/sound/soc/tegra-alt/tegra210_i2s_alt.c @@ -220,29 +220,12 @@ static int tegra210_i2s_tx_stop(struct snd_soc_dapm_widget *w, static int tegra210_i2s_runtime_suspend(struct device *dev) { struct tegra210_i2s *i2s = dev_get_drvdata(dev); - int ret; + regcache_cache_only(i2s->regmap, true); if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { - if (!IS_ERR(i2s->pin_idle_state)) { - ret = pinctrl_select_state( - i2s->pinctrl, i2s->pin_idle_state); - if (ret < 0) - dev_err(dev, "setting dap pinctrl idle state failed\n"); - } - - if (i2s->num_supplies > 0) { - ret = regulator_bulk_disable(i2s->num_supplies, - i2s->supplies); - if (ret < 0) - dev_err(dev, "failed to disable i2s io regulator\n"); - } - - regcache_cache_only(i2s->regmap, true); regcache_mark_dirty(i2s->regmap); - clk_disable_unprepare(i2s->clk_i2s); - } else - regcache_cache_only(i2s->regmap, true); + } return 0; } @@ -253,27 +236,6 @@ static int tegra210_i2s_runtime_resume(struct device *dev) int ret; if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { - if (i2s->prod_name) { - ret = tegra_pinctrl_config_prod(dev, i2s->prod_name); - if (ret < 0) - dev_warn(dev, "Failed to set %s setting\n", - i2s->prod_name); - } - - if (!IS_ERR(i2s->pin_default_state)) { - ret = pinctrl_select_state(i2s->pinctrl, - i2s->pin_default_state); - if (ret < 0) - dev_err(dev, "setting dap pinctrl default state failed\n"); - } - - if (i2s->num_supplies > 0) { - ret = regulator_bulk_enable(i2s->num_supplies, - i2s->supplies); - if (ret < 0) - dev_err(dev, "failed to enable i2s io regulator\n"); - } - ret = clk_prepare_enable(i2s->clk_i2s); if (ret) { dev_err(dev, "clk_enable failed: %d\n", ret); @@ -281,7 +243,6 @@ static int tegra210_i2s_runtime_resume(struct device *dev) } } - regcache_cache_only(i2s->regmap, false); if (!i2s->is_shutdown) regcache_sync(i2s->regmap); @@ -536,6 +497,69 @@ static const struct soc_enum tegra210_i2s_format_enum = ARRAY_SIZE(tegra210_i2s_format_text), tegra210_i2s_format_text); +static int tegra210_i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct device *dev = dai->dev; + struct tegra210_i2s *i2s = dev_get_drvdata(dev); + int ret; + + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga()) && + !i2s->loopback) { + if (i2s->prod_name != NULL) { + ret = tegra_pinctrl_config_prod(dev, i2s->prod_name); + if (ret < 0) { + dev_warn(dev, "Failed to set %s setting\n", + i2s->prod_name); + } + } + + if (!IS_ERR(i2s->pin_default_state)) { + ret = pinctrl_select_state(i2s->pinctrl, + i2s->pin_default_state); + if (ret < 0) + dev_err(dev, "setting dap pinctrl default state failed\n"); + } + + if (i2s->num_supplies > 0) { + ret = regulator_bulk_enable(i2s->num_supplies, + i2s->supplies); + if (ret < 0) + dev_err(dev, "failed to enable i2s io regulator\n"); + } + } + + return 0; +} + +static void tegra210_i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct device *dev = dai->dev; + struct tegra210_i2s *i2s = dev_get_drvdata(dev); + int ret; + + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + if (!IS_ERR(i2s->pin_idle_state)) { + ret = pinctrl_select_state( + i2s->pinctrl, i2s->pin_idle_state); + if (ret < 0) { + dev_err(dev, + "setting dap pinctrl idle state failed\n"); + } + } + + if (i2s->num_supplies > 0) { + ret = regulator_bulk_disable(i2s->num_supplies, + i2s->supplies); + if (ret < 0) { + dev_err(dev, + "failed to disable i2s io regulator\n"); + } + } + } +} + static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -717,6 +741,8 @@ static struct snd_soc_dai_ops tegra210_i2s_dai_ops = { .hw_params = tegra210_i2s_hw_params, .set_bclk_ratio = tegra210_i2s_set_dai_bclk_ratio, .set_tdm_slot = tegra210_i2s_set_tdm_slot, + .startup = tegra210_i2s_startup, + .shutdown = tegra210_i2s_shutdown, }; static struct snd_soc_dai_driver tegra210_i2s_dais[] = {