Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 80 additions & 76 deletions sound/soc/codecs/lpass-rx-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,53 @@ struct rx_macro {
};
#define to_rx_macro(_hw) container_of(_hw, struct rx_macro, hw)

static void rx_macro_disable_clocks(struct rx_macro *rx)
{
clk_disable_unprepare(rx->fsgen);
clk_disable_unprepare(rx->npl);
clk_disable_unprepare(rx->mclk);
clk_disable_unprepare(rx->dcodec);
clk_disable_unprepare(rx->macro);
}

static int rx_macro_enable_clocks(struct rx_macro *rx)
{
int ret;

ret = clk_prepare_enable(rx->macro);
if (ret)
return ret;

ret = clk_prepare_enable(rx->dcodec);
if (ret)
goto err_dcodec;

ret = clk_prepare_enable(rx->mclk);
if (ret)
goto err_mclk;

ret = clk_prepare_enable(rx->npl);
if (ret)
goto err_npl;

ret = clk_prepare_enable(rx->fsgen);
if (ret)
goto err_fsgen;

return 0;

err_fsgen:
clk_disable_unprepare(rx->npl);
err_npl:
clk_disable_unprepare(rx->mclk);
err_mclk:
clk_disable_unprepare(rx->dcodec);
err_dcodec:
clk_disable_unprepare(rx->macro);

return ret;
}

struct wcd_iir_filter_ctl {
unsigned int iir_idx;
unsigned int band_idx;
Expand Down Expand Up @@ -3686,11 +3733,9 @@ static int swclk_gate_enable(struct clk_hw *hw)
struct rx_macro *rx = to_rx_macro(hw);
int ret;

ret = clk_prepare_enable(rx->mclk);
if (ret) {
dev_err(rx->dev, "unable to prepare mclk\n");
ret = pm_runtime_resume_and_get(rx->dev);
if (ret < 0)
return ret;
}

rx_macro_mclk_enable(rx, true);

Expand All @@ -3708,7 +3753,7 @@ static void swclk_gate_disable(struct clk_hw *hw)
CDC_RX_SWR_CLK_EN_MASK, 0);

rx_macro_mclk_enable(rx, false);
clk_disable_unprepare(rx->mclk);
pm_runtime_put_autosuspend(rx->dev);
}

static int swclk_gate_is_enabled(struct clk_hw *hw)
Expand Down Expand Up @@ -3881,28 +3926,23 @@ static int rx_macro_probe(struct platform_device *pdev)
rx->dev = dev;

/* set MCLK and NPL rates */
clk_set_rate(rx->mclk, MCLK_FREQ);
clk_set_rate(rx->npl, MCLK_FREQ);

ret = clk_prepare_enable(rx->macro);
ret = clk_set_rate(rx->mclk, MCLK_FREQ);
if (ret)
return ret;

ret = clk_prepare_enable(rx->dcodec);
ret = clk_set_rate(rx->npl, MCLK_FREQ);
if (ret)
goto err_dcodec;

ret = clk_prepare_enable(rx->mclk);
if (ret)
goto err_mclk;
return ret;

ret = clk_prepare_enable(rx->npl);
pm_runtime_set_autosuspend_delay(dev, 100);
pm_runtime_use_autosuspend(dev);
ret = devm_pm_runtime_enable(dev);
if (ret)
goto err_npl;
return ret;

ret = clk_prepare_enable(rx->fsgen);
ret = pm_runtime_resume_and_get(dev);
if (ret)
goto err_fsgen;
return ret;

/* reset swr block */
regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
Expand All @@ -3919,46 +3959,25 @@ static int rx_macro_probe(struct platform_device *pdev)
rx_macro_dai,
ARRAY_SIZE(rx_macro_dai));
if (ret)
goto err_clkout;


pm_runtime_set_autosuspend_delay(dev, 3000);
pm_runtime_use_autosuspend(dev);
pm_runtime_mark_last_busy(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
goto err_rpm_put;

ret = rx_macro_register_mclk_output(rx);
if (ret)
goto err_clkout;
goto err_rpm_put;

ret = pm_runtime_put_autosuspend(dev);
if (ret < 0)
dev_warn(dev, "runtime PM put failed after probe: %d\n", ret);

return 0;

err_clkout:
clk_disable_unprepare(rx->fsgen);
err_fsgen:
clk_disable_unprepare(rx->npl);
err_npl:
clk_disable_unprepare(rx->mclk);
err_mclk:
clk_disable_unprepare(rx->dcodec);
err_dcodec:
clk_disable_unprepare(rx->macro);
err_rpm_put:
if (pm_runtime_put_sync_suspend(dev) < 0)
dev_warn(dev, "runtime PM sync suspend failed in probe unwind\n");

return ret;
}

static void rx_macro_remove(struct platform_device *pdev)
{
struct rx_macro *rx = dev_get_drvdata(&pdev->dev);

clk_disable_unprepare(rx->mclk);
clk_disable_unprepare(rx->npl);
clk_disable_unprepare(rx->fsgen);
clk_disable_unprepare(rx->macro);
clk_disable_unprepare(rx->dcodec);
}

static const struct of_device_id rx_macro_dt_match[] = {
{
.compatible = "qcom,sc7280-lpass-rx-macro",
Expand Down Expand Up @@ -3989,12 +4008,9 @@ static int rx_macro_runtime_suspend(struct device *dev)
struct rx_macro *rx = dev_get_drvdata(dev);

regcache_cache_only(rx->regmap, true);
rx_macro_disable_clocks(rx);
regcache_mark_dirty(rx->regmap);

clk_disable_unprepare(rx->fsgen);
clk_disable_unprepare(rx->npl);
clk_disable_unprepare(rx->mclk);

return 0;
}

Expand All @@ -4003,38 +4019,27 @@ static int rx_macro_runtime_resume(struct device *dev)
struct rx_macro *rx = dev_get_drvdata(dev);
int ret;

ret = clk_prepare_enable(rx->mclk);
ret = rx_macro_enable_clocks(rx);
if (ret) {
dev_err(dev, "unable to prepare mclk\n");
regcache_cache_only(rx->regmap, true);
regcache_mark_dirty(rx->regmap);
return ret;
}

ret = clk_prepare_enable(rx->npl);
if (ret) {
dev_err(dev, "unable to prepare mclkx2\n");
goto err_npl;
}

ret = clk_prepare_enable(rx->fsgen);
regcache_cache_only(rx->regmap, false);
ret = regcache_sync(rx->regmap);
if (ret) {
dev_err(dev, "unable to prepare fsgen\n");
goto err_fsgen;
regcache_cache_only(rx->regmap, true);
regcache_mark_dirty(rx->regmap);
rx_macro_disable_clocks(rx);
return ret;
}
regcache_cache_only(rx->regmap, false);
regcache_sync(rx->regmap);

return 0;
err_fsgen:
clk_disable_unprepare(rx->npl);
err_npl:
clk_disable_unprepare(rx->mclk);

return ret;
}

static const struct dev_pm_ops rx_macro_pm_ops = {
RUNTIME_PM_OPS(rx_macro_runtime_suspend, rx_macro_runtime_resume, NULL)
};
static DEFINE_RUNTIME_DEV_PM_OPS(rx_macro_pm_ops, rx_macro_runtime_suspend,
rx_macro_runtime_resume, NULL);

static struct platform_driver rx_macro_driver = {
.driver = {
Expand All @@ -4044,7 +4049,6 @@ static struct platform_driver rx_macro_driver = {
.pm = pm_ptr(&rx_macro_pm_ops),
},
.probe = rx_macro_probe,
.remove = rx_macro_remove,
};

module_platform_driver(rx_macro_driver);
Expand Down
Loading