From 3b4c46e6f1fbeeaa80b5ee4ee351cc238a9437bd Mon Sep 17 00:00:00 2001 From: Mohan Kumar Date: Fri, 15 Jul 2016 11:29:56 +0530 Subject: [PATCH] ASoC: tegra-alt: Support dynamic pinmux for spdif Support dynamic pinmux settings for dspk, this change will help to runtime configure the pinmux register to use pinmuxed path. Change-Id: Ice8236e17e55f9fb58566f65a638b750fc7bdd00 Signed-off-by: Mohan Kumar Reviewed-on: http://git-master/r/1181863 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Sameer Pujar Reviewed-by: Ravindra Lokhande --- sound/soc/tegra-alt/tegra210_spdif_alt.c | 60 +++++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/sound/soc/tegra-alt/tegra210_spdif_alt.c b/sound/soc/tegra-alt/tegra210_spdif_alt.c index e6ed0e99..3ac5b85f 100644 --- a/sound/soc/tegra-alt/tegra210_spdif_alt.c +++ b/sound/soc/tegra-alt/tegra210_spdif_alt.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "tegra210_xbar_alt.h" @@ -59,10 +60,19 @@ static const struct reg_default tegra210_spdif_reg_defaults[] = { static int tegra210_spdif_runtime_suspend(struct device *dev) { struct tegra210_spdif *spdif = dev_get_drvdata(dev); + int ret; regcache_cache_only(spdif->regmap, true); regcache_mark_dirty(spdif->regmap); if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + if (!IS_ERR(spdif->pin_idle_state) && spdif->is_pinctrl) { + ret = pinctrl_select_state( + spdif->pinctrl, spdif->pin_idle_state); + if (ret < 0) + dev_err(dev, + "setting dap pinctrl idle state failed\n"); + } + clk_disable_unprepare(spdif->clk_spdif_out); clk_disable_unprepare(spdif->clk_spdif_in); } @@ -84,6 +94,14 @@ static int tegra210_spdif_runtime_resume(struct device *dev) } if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + if (!IS_ERR(spdif->pin_active_state) && spdif->is_pinctrl) { + ret = pinctrl_select_state(spdif->pinctrl, + spdif->pin_active_state); + if (ret < 0) + dev_err(dev, + "setting dap pinctrl active state failed\n"); + } + ret = clk_prepare_enable(spdif->clk_spdif_out); if (ret) { dev_err(dev, "spdif_out_clk_enable failed: %d\n", ret); @@ -540,9 +558,47 @@ static int tegra210_spdif_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", + &spdif->is_pinctrl) < 0) + spdif->is_pinctrl = 0; + + if (spdif->is_pinctrl) { + spdif->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(spdif->pinctrl)) { + dev_warn(&pdev->dev, "Missing pinctrl device\n"); + goto err_dap; + } + + spdif->pin_active_state = pinctrl_lookup_state(spdif->pinctrl, + "dap_active"); + if (IS_ERR(spdif->pin_active_state)) { + dev_warn(&pdev->dev, "Missing dap-active state\n"); + goto err_dap; + } + + spdif->pin_idle_state = pinctrl_lookup_state(spdif->pinctrl, + "dap_inactive"); + if (IS_ERR(spdif->pin_idle_state)) { + dev_warn(&pdev->dev, "Missing dap-inactive state\n"); + goto err_dap; + } + + ret = pinctrl_select_state(spdif->pinctrl, + spdif->pin_idle_state); + if (ret < 0) { + dev_err(&pdev->dev, "setting state failed\n"); + goto err_dap; + } + } + +err_dap: dev_set_drvdata(&pdev->dev, spdif); return 0;