@@ -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[] = {