From b42a9e0cf6b0ca78b4ef5310de967d515a3cca03 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 13 Jun 2021 23:53:16 -0500 Subject: [PATCH 070/117] ASoC: sun4i-spdif: Add support for separate RX/TX clocks On older variants of the hardware, the RX and TX blocks share a single module clock, named "spdif" in the DT binding. The D1 variant has separate RX and TX clocks, so the TX module clock is named "tx" in the binding. To support this, supply the clock name in the quirks structure. Since the driver supports only TX, only the TX clock name is needed. Signed-off-by: Samuel Holland --- sound/soc/sunxi/sun4i-spdif.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) --- a/sound/soc/sunxi/sun4i-spdif.c +++ b/sound/soc/sunxi/sun4i-spdif.c @@ -169,18 +169,20 @@ /** * struct sun4i_spdif_quirks - Differences between SoC variants. * + * @tx_clk_name: firmware name for the TX clock reference. * @reg_dac_txdata: TX FIFO offset for DMA config. * @val_fctl_ftx: TX FIFO flush bitmask. */ struct sun4i_spdif_quirks { + const char *tx_clk_name; unsigned int reg_dac_txdata; unsigned int val_fctl_ftx; }; struct sun4i_spdif_dev { struct platform_device *pdev; - struct clk *spdif_clk; struct clk *apb_clk; + struct clk *tx_clk; struct reset_control *rst; struct snd_soc_dai_driver cpu_dai_drv; struct regmap *regmap; @@ -313,7 +315,7 @@ static int sun4i_spdif_hw_params(struct return -EINVAL; } - ret = clk_set_rate(host->spdif_clk, mclk); + ret = clk_set_rate(host->tx_clk, mclk); if (ret < 0) { dev_err(&pdev->dev, "Setting SPDIF clock rate for %d Hz failed!\n", mclk); @@ -537,21 +539,25 @@ static struct snd_soc_dai_driver sun4i_s }; static const struct sun4i_spdif_quirks sun4i_a10_spdif_quirks = { + .tx_clk_name = "spdif", .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, }; static const struct sun4i_spdif_quirks sun6i_a31_spdif_quirks = { + .tx_clk_name = "spdif", .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, }; static const struct sun4i_spdif_quirks sun8i_h3_spdif_quirks = { + .tx_clk_name = "spdif", .reg_dac_txdata = SUN8I_SPDIF_TXFIFO, .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, }; static const struct sun4i_spdif_quirks sun50i_h6_spdif_quirks = { + .tx_clk_name = "spdif", .reg_dac_txdata = SUN8I_SPDIF_TXFIFO, .val_fctl_ftx = SUN50I_H6_SPDIF_FCTL_FTX, }; @@ -591,7 +597,7 @@ static int sun4i_spdif_runtime_suspend(s { struct sun4i_spdif_dev *host = dev_get_drvdata(dev); - clk_disable_unprepare(host->spdif_clk); + clk_disable_unprepare(host->tx_clk); clk_disable_unprepare(host->apb_clk); return 0; @@ -602,12 +608,12 @@ static int sun4i_spdif_runtime_resume(st struct sun4i_spdif_dev *host = dev_get_drvdata(dev); int ret; - ret = clk_prepare_enable(host->spdif_clk); + ret = clk_prepare_enable(host->tx_clk); if (ret) return ret; ret = clk_prepare_enable(host->apb_clk); if (ret) - clk_disable_unprepare(host->spdif_clk); + clk_disable_unprepare(host->tx_clk); return ret; } @@ -655,10 +661,10 @@ static int sun4i_spdif_probe(struct plat return PTR_ERR(host->apb_clk); } - host->spdif_clk = devm_clk_get(&pdev->dev, "spdif"); - if (IS_ERR(host->spdif_clk)) { - dev_err(&pdev->dev, "failed to get a spdif clock.\n"); - return PTR_ERR(host->spdif_clk); + host->tx_clk = devm_clk_get(&pdev->dev, quirks->tx_clk_name); + if (IS_ERR(host->tx_clk)) { + dev_err(&pdev->dev, "failed to get TX module clock.\n"); + return PTR_ERR(host->tx_clk); } host->dma_params_tx.addr = res->start + quirks->reg_dac_txdata;