summaryrefslogtreecommitdiff
path: root/sound/soc/stm/stm32_sai.c
diff options
context:
space:
mode:
authorOlivier Moysan <olivier.moysan@st.com>2019-06-03 10:16:34 +0200
committerMark Brown <broonie@kernel.org>2019-06-03 17:46:11 +0100
commit1d9c95c1896256a64e3a8d825f9e78cc79d29ebb (patch)
treeb706bbbd1e9f0090e5eb4fd75679878eace5edfc /sound/soc/stm/stm32_sai.c
parent970c43d1783539b75a5e234ff5e51fc5c888112f (diff)
ASoC: stm32: sai: manage identification registers
Add support of identification registers in STM32 SAI. Signed-off-by: Olivier Moysan <olivier.moysan@st.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/stm/stm32_sai.c')
-rw-r--r--sound/soc/stm/stm32_sai.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c
index 7550d5f08be3..98b29f712831 100644
--- a/sound/soc/stm/stm32_sai.c
+++ b/sound/soc/stm/stm32_sai.c
@@ -30,13 +30,20 @@
#include "stm32_sai.h"
static const struct stm32_sai_conf stm32_sai_conf_f4 = {
- .version = SAI_STM32F4,
- .has_spdif = false,
+ .version = STM_SAI_STM32F4,
+ .fifo_size = 8,
+ .has_spdif_pdm = false,
};
+/*
+ * Default settings for stm32 H7 socs and next.
+ * These default settings will be overridden if the soc provides
+ * support of hardware configuration registers.
+ */
static const struct stm32_sai_conf stm32_sai_conf_h7 = {
- .version = SAI_STM32H7,
- .has_spdif = true,
+ .version = STM_SAI_STM32H7,
+ .fifo_size = 8,
+ .has_spdif_pdm = true,
};
static const struct of_device_id stm32_sai_ids[] = {
@@ -157,6 +164,8 @@ static int stm32_sai_probe(struct platform_device *pdev)
struct reset_control *rst;
struct resource *res;
const struct of_device_id *of_id;
+ u32 val;
+ int ret;
sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
if (!sai)
@@ -169,7 +178,8 @@ static int stm32_sai_probe(struct platform_device *pdev)
of_id = of_match_device(stm32_sai_ids, &pdev->dev);
if (of_id)
- sai->conf = (struct stm32_sai_conf *)of_id->data;
+ memcpy(&sai->conf, (const struct stm32_sai_conf *)of_id->data,
+ sizeof(struct stm32_sai_conf));
else
return -EINVAL;
@@ -208,6 +218,30 @@ static int stm32_sai_probe(struct platform_device *pdev)
reset_control_deassert(rst);
}
+ /* Enable peripheral clock to allow register access */
+ ret = clk_prepare_enable(sai->pclk);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
+ return ret;
+ }
+
+ val = FIELD_GET(SAI_IDR_ID_MASK,
+ readl_relaxed(sai->base + STM_SAI_IDR));
+ if (val == SAI_IPIDR_NUMBER) {
+ val = readl_relaxed(sai->base + STM_SAI_HWCFGR);
+ sai->conf.fifo_size = FIELD_GET(SAI_HWCFGR_FIFO_SIZE, val);
+ sai->conf.has_spdif_pdm = !!FIELD_GET(SAI_HWCFGR_SPDIF_PDM,
+ val);
+
+ val = readl_relaxed(sai->base + STM_SAI_VERR);
+ sai->conf.version = val;
+
+ dev_dbg(&pdev->dev, "SAI version: %lu.%lu registered\n",
+ FIELD_GET(SAI_VERR_MAJ_MASK, val),
+ FIELD_GET(SAI_VERR_MIN_MASK, val));
+ }
+ clk_disable_unprepare(sai->pclk);
+
sai->pdev = pdev;
sai->set_sync = &stm32_sai_set_sync;
platform_set_drvdata(pdev, sai);