diff options
author | Olivier Moysan <olivier.moysan@st.com> | 2019-06-03 10:16:34 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-06-03 17:46:11 +0100 |
commit | 1d9c95c1896256a64e3a8d825f9e78cc79d29ebb (patch) | |
tree | b706bbbd1e9f0090e5eb4fd75679878eace5edfc /sound/soc/stm/stm32_sai.c | |
parent | 970c43d1783539b75a5e234ff5e51fc5c888112f (diff) | |
download | lwn-1d9c95c1896256a64e3a8d825f9e78cc79d29ebb.tar.gz lwn-1d9c95c1896256a64e3a8d825f9e78cc79d29ebb.zip |
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.c | 44 |
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); |