Skip to content

Commit 3324809

Browse files
Sugar Zhangrkhuangtao
authored andcommitted
ASoC: rockchip: i2s-tdm: Fix register write failed on QUIRKS_ALWAYS_ON
CLK_ALWAYS_ON should be placed after all registers write done, because this situation will enable XFER bit which will make some registers(depend on XFER) write failed. Fixes: 3644caf ("ASoC: rockchip: i2s-tdm: Add support for clk always-on") Signed-off-by: Sugar Zhang <[email protected]> Change-Id: Iffcfed18d3805ee575df4e8cf267d4ef6a3fa866
1 parent bd3108e commit 3324809

File tree

1 file changed

+49
-30
lines changed

1 file changed

+49
-30
lines changed

sound/soc/rockchip/rockchip_i2s_tdm.c

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,6 +2212,44 @@ static irqreturn_t rockchip_i2s_tdm_isr(int irq, void *devid)
22122212
return IRQ_HANDLED;
22132213
}
22142214

2215+
static int rockchip_i2s_tdm_keep_clk_always_on(struct rk_i2s_tdm_dev *i2s_tdm)
2216+
{
2217+
unsigned int mclk_rate = DEFAULT_FS * DEFAULT_MCLK_FS;
2218+
unsigned int bclk_rate = i2s_tdm->frame_width * DEFAULT_FS;
2219+
unsigned int div_lrck = i2s_tdm->frame_width;
2220+
unsigned int div_bclk;
2221+
int ret;
2222+
2223+
div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
2224+
2225+
/* assign generic freq */
2226+
clk_set_rate(i2s_tdm->mclk_rx, mclk_rate);
2227+
clk_set_rate(i2s_tdm->mclk_tx, mclk_rate);
2228+
2229+
ret = rockchip_i2s_tdm_mclk_reparent(i2s_tdm);
2230+
if (ret)
2231+
return ret;
2232+
2233+
regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
2234+
I2S_CLKDIV_RXM_MASK | I2S_CLKDIV_TXM_MASK,
2235+
I2S_CLKDIV_RXM(div_bclk) | I2S_CLKDIV_TXM(div_bclk));
2236+
regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
2237+
I2S_CKR_RSD_MASK | I2S_CKR_TSD_MASK,
2238+
I2S_CKR_RSD(div_lrck) | I2S_CKR_TSD(div_lrck));
2239+
2240+
if (i2s_tdm->clk_trcm)
2241+
rockchip_i2s_tdm_xfer_trcm_start(i2s_tdm);
2242+
else
2243+
rockchip_i2s_tdm_xfer_start(i2s_tdm, SNDRV_PCM_STREAM_PLAYBACK);
2244+
2245+
pm_runtime_forbid(i2s_tdm->dev);
2246+
2247+
dev_info(i2s_tdm->dev, "CLK-ALWAYS-ON: mclk: %d, bclk: %d, fsync: %d\n",
2248+
mclk_rate, bclk_rate, DEFAULT_FS);
2249+
2250+
return 0;
2251+
}
2252+
22152253
static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
22162254
{
22172255
struct device_node *node = pdev->dev.of_node;
@@ -2404,36 +2442,6 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
24042442

24052443
pm_runtime_enable(&pdev->dev);
24062444

2407-
if (i2s_tdm->quirks & QUIRK_ALWAYS_ON) {
2408-
unsigned int rate = DEFAULT_FS * DEFAULT_MCLK_FS;
2409-
unsigned int div_bclk = DEFAULT_FS * DEFAULT_MCLK_FS;
2410-
unsigned int div_lrck = i2s_tdm->frame_width;
2411-
2412-
div_bclk = DIV_ROUND_CLOSEST(rate, div_lrck * DEFAULT_FS);
2413-
2414-
/* assign generic freq */
2415-
clk_set_rate(i2s_tdm->mclk_rx, rate);
2416-
clk_set_rate(i2s_tdm->mclk_tx, rate);
2417-
2418-
ret = rockchip_i2s_tdm_mclk_reparent(i2s_tdm);
2419-
if (ret)
2420-
goto err_suspend;
2421-
2422-
regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
2423-
I2S_CLKDIV_RXM_MASK | I2S_CLKDIV_TXM_MASK,
2424-
I2S_CLKDIV_RXM(div_bclk) | I2S_CLKDIV_TXM(div_bclk));
2425-
regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
2426-
I2S_CKR_RSD_MASK | I2S_CKR_TSD_MASK,
2427-
I2S_CKR_RSD(div_lrck) | I2S_CKR_TSD(div_lrck));
2428-
2429-
if (i2s_tdm->clk_trcm)
2430-
rockchip_i2s_tdm_xfer_trcm_start(i2s_tdm);
2431-
else
2432-
rockchip_i2s_tdm_xfer_start(i2s_tdm, SNDRV_PCM_STREAM_PLAYBACK);
2433-
2434-
pm_runtime_forbid(&pdev->dev);
2435-
}
2436-
24372445
regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
24382446
I2S_DMACR_TDL(16));
24392447
regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
@@ -2444,6 +2452,17 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
24442452
if (i2s_tdm->soc_data && i2s_tdm->soc_data->init)
24452453
i2s_tdm->soc_data->init(&pdev->dev, res->start);
24462454

2455+
/*
2456+
* CLK_ALWAYS_ON should be placed after all registers write done,
2457+
* because this situation will enable XFER bit which will make
2458+
* some registers(depend on XFER) write failed.
2459+
*/
2460+
if (i2s_tdm->quirks & QUIRK_ALWAYS_ON) {
2461+
ret = rockchip_i2s_tdm_keep_clk_always_on(i2s_tdm);
2462+
if (ret)
2463+
goto err_suspend;
2464+
}
2465+
24472466
ret = devm_snd_soc_register_component(&pdev->dev,
24482467
&rockchip_i2s_tdm_component,
24492468
i2s_tdm->dai, 1);

0 commit comments

Comments
 (0)