diff options
Diffstat (limited to 'sound/soc/stm/stm32_sai.c')
-rw-r--r-- | sound/soc/stm/stm32_sai.c | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index b45ee7e24f22..bc8180fc8462 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c @@ -19,26 +19,42 @@ #include "stm32_sai.h" +static int stm32_sai_get_parent_clk(struct stm32_sai_data *sai); + static const struct stm32_sai_conf stm32_sai_conf_f4 = { .version = STM_SAI_STM32F4, .fifo_size = 8, .has_spdif_pdm = false, + .get_sai_ck_parent = stm32_sai_get_parent_clk, }; /* - * Default settings for stm32 H7 socs and next. + * Default settings for STM32H7x socs and STM32MP1x. * These default settings will be overridden if the soc provides * support of hardware configuration registers. + * - STM32H7: rely on default settings + * - STM32MP1: retrieve settings from registers */ static const struct stm32_sai_conf stm32_sai_conf_h7 = { .version = STM_SAI_STM32H7, .fifo_size = 8, .has_spdif_pdm = true, + .get_sai_ck_parent = stm32_sai_get_parent_clk, +}; + +/* + * STM32MP2x: + * - do not use SAI parent clock source selection + * - do not use DMA burst mode + */ +static const struct stm32_sai_conf stm32_sai_conf_mp25 = { + .no_dma_burst = true, }; static const struct of_device_id stm32_sai_ids[] = { { .compatible = "st,stm32f4-sai", .data = (void *)&stm32_sai_conf_f4 }, { .compatible = "st,stm32h7-sai", .data = (void *)&stm32_sai_conf_h7 }, + { .compatible = "st,stm32mp25-sai", .data = (void *)&stm32_sai_conf_mp25 }, {} }; @@ -148,6 +164,29 @@ error: return ret; } +static int stm32_sai_get_parent_clk(struct stm32_sai_data *sai) +{ + struct device *dev = &sai->pdev->dev; + + sai->clk_x8k = devm_clk_get(dev, "x8k"); + if (IS_ERR(sai->clk_x8k)) { + if (PTR_ERR(sai->clk_x8k) != -EPROBE_DEFER) + dev_err(dev, "missing x8k parent clock: %ld\n", + PTR_ERR(sai->clk_x8k)); + return PTR_ERR(sai->clk_x8k); + } + + sai->clk_x11k = devm_clk_get(dev, "x11k"); + if (IS_ERR(sai->clk_x11k)) { + if (PTR_ERR(sai->clk_x11k) != -EPROBE_DEFER) + dev_err(dev, "missing x11k parent clock: %ld\n", + PTR_ERR(sai->clk_x11k)); + return PTR_ERR(sai->clk_x11k); + } + + return 0; +} + static int stm32_sai_probe(struct platform_device *pdev) { struct stm32_sai_data *sai; @@ -160,6 +199,8 @@ static int stm32_sai_probe(struct platform_device *pdev) if (!sai) return -ENOMEM; + sai->pdev = pdev; + sai->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(sai->base)) return PTR_ERR(sai->base); @@ -178,15 +219,11 @@ static int stm32_sai_probe(struct platform_device *pdev) "missing bus clock pclk\n"); } - sai->clk_x8k = devm_clk_get(&pdev->dev, "x8k"); - if (IS_ERR(sai->clk_x8k)) - return dev_err_probe(&pdev->dev, PTR_ERR(sai->clk_x8k), - "missing x8k parent clock\n"); - - sai->clk_x11k = devm_clk_get(&pdev->dev, "x11k"); - if (IS_ERR(sai->clk_x11k)) - return dev_err_probe(&pdev->dev, PTR_ERR(sai->clk_x11k), - "missing x11k parent clock\n"); + if (sai->conf.get_sai_ck_parent) { + ret = sai->conf.get_sai_ck_parent(sai); + if (ret) + return ret; + } /* init irqs */ sai->irq = platform_get_irq(pdev, 0); @@ -227,7 +264,6 @@ static int stm32_sai_probe(struct platform_device *pdev) } clk_disable_unprepare(sai->pclk); - sai->pdev = pdev; sai->set_sync = &stm32_sai_set_sync; platform_set_drvdata(pdev, sai); |