mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-16 04:04:06 +00:00
sound:dwc:i2s:Add hibernation about i2srx-3ch
Add runtime pm and system pm in i2srx-3ch driver. Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
This commit is contained in:
parent
a5069304c0
commit
190785d5d8
1 changed files with 58 additions and 88 deletions
|
@ -323,24 +323,12 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
|
|||
return ret;
|
||||
}
|
||||
} else if (txrx == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
ret = clk_prepare_enable(dev->clks[CLK_ADC_BCLK_EXT]);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "%s: failed to enable CLK_ADC_BCLK_EXT\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_set_parent(dev->clks[CLK_ADC_RX_BCLK], dev->clks[CLK_ADC_BCLK_EXT]);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "Can't set clock source for CLK_ADC_RX_BCLK: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dev->clks[CLK_ADC_LRCK_EXT]);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "%s: failed to enable CLK_ADC_LRCK_EXT\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_set_parent(dev->clks[CLK_ADC_RX_LRCK], dev->clks[CLK_ADC_LRCK_EXT]);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "Can't set clock source for CLK_ADC_RX_LRCK: %d\n", ret);
|
||||
|
@ -469,9 +457,14 @@ static int dw_i2s_runtime_suspend(struct device *dev)
|
|||
if (dw_dev->capability & DW_I2S_MASTER)
|
||||
clk_disable(dw_dev->clk);
|
||||
else {
|
||||
clk_disable_unprepare(dw_dev->clks_bclk_mst);
|
||||
clk_disable_unprepare(dw_dev->clks_mclk_out);
|
||||
clk_disable_unprepare(dw_dev->clks_4ch_apb);
|
||||
if (dw_dev->capability & DWC_I2S_PLAY) {
|
||||
clk_disable_unprepare(dw_dev->clks_mclk_out);
|
||||
clk_disable_unprepare(dw_dev->clks_bclk_mst);
|
||||
clk_disable_unprepare(dw_dev->clks_4ch_apb);
|
||||
} else {
|
||||
clk_disable_unprepare(dw_dev->clks[CLK_ADC_BCLK]);
|
||||
clk_disable_unprepare(dw_dev->clks[CLK_ADC_APB]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -484,20 +477,33 @@ static int dw_i2s_runtime_resume(struct device *dev)
|
|||
if (dw_dev->capability & DW_I2S_MASTER)
|
||||
clk_enable(dw_dev->clk);
|
||||
else {
|
||||
ret = clk_prepare_enable(dw_dev->clks_4ch_apb);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable clks_4ch_apb\n");
|
||||
goto failed_enable;
|
||||
}
|
||||
ret = clk_prepare_enable(dw_dev->clks_bclk_mst);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable clks_bclk_mst\n");
|
||||
goto failed_enable;
|
||||
}
|
||||
ret = clk_prepare_enable(dw_dev->clks_mclk_out);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable clks_mclk_out\n");
|
||||
goto failed_enable;
|
||||
if (dw_dev->capability & DWC_I2S_PLAY) {
|
||||
ret = clk_prepare_enable(dw_dev->clks_4ch_apb);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable clks_4ch_apb\n");
|
||||
goto failed_enable;
|
||||
}
|
||||
ret = clk_prepare_enable(dw_dev->clks_bclk_mst);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable clks_bclk_mst\n");
|
||||
goto failed_enable;
|
||||
}
|
||||
ret = clk_prepare_enable(dw_dev->clks_mclk_out);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable clks_mclk_out\n");
|
||||
goto failed_enable;
|
||||
}
|
||||
} else {
|
||||
ret = clk_prepare_enable(dw_dev->clks[CLK_ADC_BCLK]);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable CLK_ADC_BCLK\n");
|
||||
goto failed_enable;
|
||||
}
|
||||
ret = clk_prepare_enable(dw_dev->clks[CLK_ADC_APB]);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable CLK_ADC_APB\n");
|
||||
goto failed_enable;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -590,65 +596,30 @@ static int dw_i2srx_clk_init(struct platform_device *pdev, struct dw_i2s_dev *de
|
|||
dev->clks[CLK_ADC_BCLK_EXT] = clks[9].clk;
|
||||
dev->clks[CLK_ADC_LRCK_EXT] = clks[10].clk;
|
||||
|
||||
ret = clk_prepare_enable(dev->clks[CLK_ADC_APB0]);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_APB0\n", __func__);
|
||||
goto disable_APB0_clk;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dev->clks[CLK_ADC_APB]);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_APB\n", __func__);
|
||||
goto disable_APB_clk;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dev->clks[CLK_ADC_AUDROOT]);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_AUDROOT\n", __func__);
|
||||
goto disable_audroot_clk;
|
||||
}
|
||||
|
||||
ret = clk_set_rate(dev->clks[CLK_ADC_AUDROOT], 204800000);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to set rate for CLK_ADC_MCLK \n");
|
||||
goto disable_audroot_clk;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dev->clks[CLK_ADC_MCLK_INNER]);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_MCLK_INNER\n", __func__);
|
||||
goto disable_inner_clk;
|
||||
}
|
||||
|
||||
ret = clk_set_rate(dev->clks[CLK_ADC_MCLK_INNER], 4096000);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to set rate for CLK_ADC_MCLK \n");
|
||||
goto disable_inner_clk;
|
||||
goto disable_audroot_clk;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dev->clks[CLK_ADC_BCLK]);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_BCLK\n", __func__);
|
||||
goto disable_bclk;
|
||||
goto disable_audroot_clk;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dev->clks[CLK_ADC_LRCLK]);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_LRCLK\n", __func__);
|
||||
goto disable_lrclk;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dev->clks[CLK_ADC_RX_BCLK]);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_RX_BCLK\n", __func__);
|
||||
goto disable_rx_bclk;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dev->clks[CLK_ADC_RX_LRCK]);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_RX_LRCK\n", __func__);
|
||||
goto disable_rx_lrclk;
|
||||
}
|
||||
dev_dbg(&pdev->dev, "dev->clks[CLK_ADC_APB0] = %lu \n", clk_get_rate(dev->clks[CLK_ADC_APB0]));
|
||||
dev_dbg(&pdev->dev, "dev->clks[CLK_ADC_APB] = %lu \n", clk_get_rate(dev->clks[CLK_ADC_APB]));
|
||||
dev_dbg(&pdev->dev, "dev->clks[CLK_ADC_BCLK] = %lu \n", clk_get_rate(dev->clks[CLK_ADC_BCLK]));
|
||||
|
@ -659,19 +630,19 @@ static int dw_i2srx_clk_init(struct platform_device *pdev, struct dw_i2s_dev *de
|
|||
dev->rstc_rx = devm_reset_control_array_get_exclusive(&pdev->dev);
|
||||
if (IS_ERR(dev->rstc_rx)) {
|
||||
dev_err(&pdev->dev, "%s: failed to get rstc_rx reset control\n", __func__);
|
||||
goto disable_rx_lrclk;
|
||||
goto disable_rst;
|
||||
}
|
||||
|
||||
ret = reset_control_assert(dev->rstc_rx);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: failed to reset control assert rstc_rx\n", __func__);
|
||||
goto disable_rx_lrclk;
|
||||
goto disable_rst;
|
||||
}
|
||||
udelay(5);
|
||||
ret = reset_control_deassert(dev->rstc_rx);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: failed to reset control deassert rstc_rx\n", __func__);
|
||||
goto disable_rx_lrclk;
|
||||
goto disable_rst;
|
||||
}
|
||||
|
||||
/*i2srx_3ch_adc_enable*/
|
||||
|
@ -684,22 +655,11 @@ static int dw_i2srx_clk_init(struct platform_device *pdev, struct dw_i2s_dev *de
|
|||
|
||||
return 0;
|
||||
|
||||
disable_rx_lrclk:
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_RX_LRCK]);
|
||||
disable_rx_bclk:
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_RX_BCLK]);
|
||||
disable_lrclk:
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_LRCLK]);
|
||||
disable_bclk:
|
||||
disable_rst:
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_BCLK]);
|
||||
disable_inner_clk:
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_MCLK_INNER]);
|
||||
disable_audroot_clk:
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_AUDROOT]);
|
||||
disable_APB_clk:
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_APB]);
|
||||
disable_APB0_clk:
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_APB0]);
|
||||
disable_APB_clk:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1248,9 +1208,14 @@ static int dw_i2s_probe(struct platform_device *pdev)
|
|||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
clk_disable_unprepare(dev->clks_mclk_out);
|
||||
clk_disable_unprepare(dev->clks_bclk_mst);
|
||||
clk_disable_unprepare(dev->clks_4ch_apb);
|
||||
if (dev->capability & DWC_I2S_PLAY) {
|
||||
clk_disable_unprepare(dev->clks_mclk_out);
|
||||
clk_disable_unprepare(dev->clks_bclk_mst);
|
||||
clk_disable_unprepare(dev->clks_4ch_apb);
|
||||
} else {
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_BCLK]);
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_APB]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -1259,9 +1224,14 @@ err_clk_disable:
|
|||
if (dev->capability & DW_I2S_MASTER)
|
||||
clk_disable_unprepare(dev->clk);
|
||||
else{
|
||||
clk_disable_unprepare(dev->clks_mclk_out);
|
||||
clk_disable_unprepare(dev->clks_bclk_mst);
|
||||
clk_disable_unprepare(dev->clks_4ch_apb);
|
||||
if (dev->capability & DWC_I2S_PLAY) {
|
||||
clk_disable_unprepare(dev->clks_mclk_out);
|
||||
clk_disable_unprepare(dev->clks_bclk_mst);
|
||||
clk_disable_unprepare(dev->clks_4ch_apb);
|
||||
} else {
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_BCLK]);
|
||||
clk_disable_unprepare(dev->clks[CLK_ADC_APB]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Add table
Reference in a new issue