diff --git a/sound/soc/tegra-alt/tegra186_dspk_alt.c b/sound/soc/tegra-alt/tegra186_dspk_alt.c index 0c2d111d..587762b2 100644 --- a/sound/soc/tegra-alt/tegra186_dspk_alt.c +++ b/sound/soc/tegra-alt/tegra186_dspk_alt.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "tegra210_xbar_alt.h" @@ -62,11 +63,21 @@ static const struct reg_default tegra186_dspk_reg_defaults[] = { 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 (!(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"); + } clk_disable_unprepare(dspk->clk_dspk); + } pm_runtime_put_sync(dev->parent); return 0; @@ -84,6 +95,14 @@ static int tegra186_dspk_runtime_resume(struct device *dev) } 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); @@ -461,9 +480,46 @@ static int tegra186_dspk_platform_probe(struct platform_device *pdev) goto err_suspend; } - if (of_property_read_string(np, "prod-name", &prod_name) == 0) - tegra_pinctrl_config_prod(&pdev->dev, prod_name); + if (of_property_read_string(np, "prod-name", &prod_name) == 0) { + ret = tegra_pinctrl_config_prod(&pdev->dev, prod_name); + if (ret < 0) + dev_warn(&pdev->dev, "Failed to set %s setting\n", + prod_name); + } + if (of_property_read_u32(np, "nvidia,is-pinctrl", + &dspk->is_pinctrl) < 0) + dspk->is_pinctrl = 0; + + if (dspk->is_pinctrl) { + dspk->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(dspk->pinctrl)) { + dev_warn(&pdev->dev, "Missing pinctrl device\n"); + goto err_dap; + } + + dspk->pin_active_state = pinctrl_lookup_state(dspk->pinctrl, + "dap_active"); + if (IS_ERR(dspk->pin_active_state)) { + dev_warn(&pdev->dev, "Missing dap-active state\n"); + goto err_dap; + } + + dspk->pin_idle_state = pinctrl_lookup_state(dspk->pinctrl, + "dap_inactive"); + if (IS_ERR(dspk->pin_idle_state)) { + dev_warn(&pdev->dev, "Missing dap-inactive state\n"); + goto err_dap; + } + + ret = pinctrl_select_state(dspk->pinctrl, dspk->pin_idle_state); + if (ret < 0) { + dev_err(&pdev->dev, "setting state failed\n"); + goto err_dap; + } + } + +err_dap: dev_set_drvdata(&pdev->dev, dspk); return 0;