[PATCH] ASoC: stm32: spdifrx: manage identification registers

From: Olivier Moysan
Date: Mon May 06 2019 - 08:44:06 EST


Add support of identification registers in STM32 SPDIFRX.

Signed-off-by: Olivier Moysan <olivier.moysan@xxxxxx>
Signed-off-by: Mark Brown <broonie@xxxxxxxxxx>
---
sound/soc/stm/stm32_spdifrx.c | 37 +++++++++++++++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
index b4c3d983e195..62a887ee4a03 100644
--- a/sound/soc/stm/stm32_spdifrx.c
+++ b/sound/soc/stm/stm32_spdifrx.c
@@ -16,6 +16,7 @@
* details.
*/

+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
@@ -36,6 +37,9 @@
#define STM32_SPDIFRX_DR 0x10
#define STM32_SPDIFRX_CSR 0x14
#define STM32_SPDIFRX_DIR 0x18
+#define STM32_SPDIFRX_VERR 0x3F4
+#define STM32_SPDIFRX_IDR 0x3F8
+#define STM32_SPDIFRX_SIDR 0x3FC

/* Bit definition for SPDIF_CR register */
#define SPDIFRX_CR_SPDIFEN_SHIFT 0
@@ -169,6 +173,18 @@
#define SPDIFRX_SPDIFEN_SYNC 0x1
#define SPDIFRX_SPDIFEN_ENABLE 0x3

+/* Bit definition for SPDIFRX_VERR register */
+#define SPDIFRX_VERR_MIN_MASK GENMASK(3, 0)
+#define SPDIFRX_VERR_MAJ_MASK GENMASK(7, 4)
+
+/* Bit definition for SPDIFRX_IDR register */
+#define SPDIFRX_IDR_ID_MASK GENMASK(31, 0)
+
+/* Bit definition for SPDIFRX_SIDR register */
+#define SPDIFRX_SIDR_SID_MASK GENMASK(31, 0)
+
+#define SPDIFRX_IPIDR_NUMBER 0x00130041
+
#define SPDIFRX_IN1 0x1
#define SPDIFRX_IN2 0x2
#define SPDIFRX_IN3 0x3
@@ -607,6 +623,9 @@ static bool stm32_spdifrx_readable_reg(struct device *dev, unsigned int reg)
case STM32_SPDIFRX_DR:
case STM32_SPDIFRX_CSR:
case STM32_SPDIFRX_DIR:
+ case STM32_SPDIFRX_VERR:
+ case STM32_SPDIFRX_IDR:
+ case STM32_SPDIFRX_SIDR:
return true;
default:
return false;
@@ -642,10 +661,11 @@ static const struct regmap_config stm32_h7_spdifrx_regmap_conf = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
- .max_register = STM32_SPDIFRX_DIR,
+ .max_register = STM32_SPDIFRX_SIDR,
.readable_reg = stm32_spdifrx_readable_reg,
.volatile_reg = stm32_spdifrx_volatile_reg,
.writeable_reg = stm32_spdifrx_writeable_reg,
+ .num_reg_defaults_raw = STM32_SPDIFRX_SIDR / sizeof(u32) + 1,
.fast_io = true,
.cache_type = REGCACHE_FLAT,
};
@@ -911,6 +931,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
struct stm32_spdifrx_data *spdifrx;
struct reset_control *rst;
const struct snd_dmaengine_pcm_config *pcm_config = NULL;
+ u32 ver, idr;
int ret;

spdifrx = devm_kzalloc(&pdev->dev, sizeof(*spdifrx), GFP_KERNEL);
@@ -967,7 +988,19 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
goto error;
}

- return 0;
+ ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_IDR, &idr);
+ if (ret)
+ goto error;
+
+ if (idr == SPDIFRX_IPIDR_NUMBER) {
+ ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_VERR, &ver);
+
+ dev_dbg(&pdev->dev, "SPDIFRX version: %lu.%lu registered\n",
+ FIELD_GET(SPDIFRX_VERR_MAJ_MASK, ver),
+ FIELD_GET(SPDIFRX_VERR_MIN_MASK, ver));
+ }
+
+ return ret;

error:
if (!IS_ERR(spdifrx->ctrl_chan))
--
2.20.1