diff options
-rw-r--r-- | sound/soc/sunxi/sun8i-codec.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 7b45ddffe9900..2a46b96b03cce 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -177,12 +177,14 @@ struct sun8i_codec_aif { }; struct sun8i_codec_quirks { - bool legacy_widgets : 1; - bool lrck_inversion : 1; + bool bus_clock : 1; + bool legacy_widgets : 1; + bool lrck_inversion : 1; }; struct sun8i_codec { struct regmap *regmap; + struct clk *clk_bus; struct clk *clk_module; const struct sun8i_codec_quirks *quirks; struct sun8i_codec_aif aifs[SUN8I_CODEC_NAIFS]; @@ -197,6 +199,14 @@ static int sun8i_codec_runtime_resume(struct device *dev) struct sun8i_codec *scodec = dev_get_drvdata(dev); int ret; + if (scodec->clk_bus) { + ret = clk_prepare_enable(scodec->clk_bus); + if (ret) { + dev_err(dev, "Failed to enable the bus clock\n"); + return ret; + } + } + regcache_cache_only(scodec->regmap, false); ret = regcache_sync(scodec->regmap); @@ -215,6 +225,9 @@ static int sun8i_codec_runtime_suspend(struct device *dev) regcache_cache_only(scodec->regmap, true); regcache_mark_dirty(scodec->regmap); + if (scodec->clk_bus) + clk_disable_unprepare(scodec->clk_bus); + return 0; } @@ -1277,6 +1290,7 @@ static const struct snd_soc_component_driver sun8i_soc_component = { .num_dapm_routes = ARRAY_SIZE(sun8i_codec_dapm_routes), .probe = sun8i_codec_component_probe, .idle_bias_on = 1, + .suspend_bias_off = 1, .endianness = 1, }; @@ -1299,6 +1313,18 @@ static int sun8i_codec_probe(struct platform_device *pdev) if (!scodec) return -ENOMEM; + scodec->quirks = of_device_get_match_data(&pdev->dev); + + platform_set_drvdata(pdev, scodec); + + if (scodec->quirks->bus_clock) { + scodec->clk_bus = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(scodec->clk_bus)) { + dev_err(&pdev->dev, "Failed to get the bus clock\n"); + return PTR_ERR(scodec->clk_bus); + } + } + scodec->clk_module = devm_clk_get(&pdev->dev, "mod"); if (IS_ERR(scodec->clk_module)) { dev_err(&pdev->dev, "Failed to get the module clock\n"); @@ -1311,17 +1337,14 @@ static int sun8i_codec_probe(struct platform_device *pdev) return PTR_ERR(base); } - scodec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "bus", base, - &sun8i_codec_regmap_config); + scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base, + &sun8i_codec_regmap_config); if (IS_ERR(scodec->regmap)) { dev_err(&pdev->dev, "Failed to create our regmap\n"); return PTR_ERR(scodec->regmap); } - scodec->quirks = of_device_get_match_data(&pdev->dev); - - platform_set_drvdata(pdev, scodec); - + regcache_cache_only(scodec->regmap, true); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = sun8i_codec_runtime_resume(&pdev->dev); @@ -1357,11 +1380,13 @@ static void sun8i_codec_remove(struct platform_device *pdev) } static const struct sun8i_codec_quirks sun8i_a33_quirks = { + .bus_clock = true, .legacy_widgets = true, .lrck_inversion = true, }; static const struct sun8i_codec_quirks sun50i_a64_quirks = { + .bus_clock = true, }; static const struct of_device_id sun8i_codec_of_match[] = { |