summaryrefslogtreecommitdiff
path: root/sound/soc/stm/stm32_sai.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/stm/stm32_sai.c')
-rw-r--r--sound/soc/stm/stm32_sai.c58
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);