From 6938d9c200a3c7cab04ab376c92bda1a8a11dfba Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Fri, 2 Sep 2022 11:43:27 +0800 Subject: [PATCH] ASoC: rockchip: spdif: Fill IEC958 CS info per params This patch fill IEC958 Channel Status info to fix mismatch SampleRate measured by Analyzer. | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | CS0: | Mode | d | c | b | a | CS1: | Category Code | CS2: | Channel Number | Source Number | CS3: | Clock Accuracy | Sample Freq | CS4: | Ori Sample Freq | Word Length | CS5: | | CGMS-A | CS6~CS23: Reserved a: use of channel status block b: linear PCM identification: 0 for lpcm, 1 for nlpcm c: copyright information d: additional format information Signed-off-by: Sugar Zhang Change-Id: I1e1e3ffb8f3706ae19117c4ae3fc38e20a71f78b --- sound/soc/rockchip/Kconfig | 1 + sound/soc/rockchip/rockchip_spdif.c | 44 ++++++++++++++++++++++++++--- sound/soc/rockchip/rockchip_spdif.h | 8 ++++++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index b4ce27050568..bd16de1b3fd7 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig @@ -52,6 +52,7 @@ config SND_SOC_ROCKCHIP_PDM config SND_SOC_ROCKCHIP_SPDIF tristate "Rockchip SPDIF Device Driver" depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP + select SND_PCM_IEC958 select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for SPDIF driver for diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c index a1f2b3d56cf8..83878933aee1 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "rockchip_spdif.h" @@ -28,7 +29,25 @@ enum rk_spdif_type { RK_SPDIF_RK3366, }; -#define RK3288_GRF_SOC_CON2 0x24c +/* + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * CS0: | Mode | d | c | b | a | + * CS1: | Category Code | + * CS2: | Channel Number | Source Number | + * CS3: | Clock Accuracy | Sample Freq | + * CS4: | Ori Sample Freq | Word Length | + * CS5: | | CGMS-A | + * CS6~CS23: Reserved + * + * a: use of channel status block + * b: linear PCM identification: 0 for lpcm, 1 for nlpcm + * c: copyright information + * d: additional format information + */ +#define CS_BYTE 6 +#define CS_FRAME(c) ((c) << 16 | (c)) + +#define RK3288_GRF_SOC_CON2 0x24c struct rk_spdif_dev { struct device *dev; @@ -113,8 +132,19 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream, struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai); unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE; unsigned int mclk_rate = clk_get_rate(spdif->mclk); - int bmc, div; - int ret; + int bmc, div, ret, i; + u8 cs[CS_BYTE]; + u16 *fc = (u16 *)cs; + + ret = snd_pcm_create_iec958_consumer_hw_params(params, cs, sizeof(cs)); + if (ret < 0) + return ret; + + for (i = 0; i < CS_BYTE / 2; i++) + regmap_write(spdif->regmap, SPDIF_CHNSRn(i), CS_FRAME(fc[i])); + + regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CSE_MASK, + SPDIF_CFGR_CSE_EN); /* bmc = 128fs */ bmc = 128 * params_rate(params); @@ -249,6 +279,9 @@ static bool rk_spdif_wr_reg(struct device *dev, unsigned int reg) case SPDIF_INTCR: case SPDIF_XFER: case SPDIF_SMPDR: + case SPDIF_VLDFRn(0) ... SPDIF_VLDFRn(11): + case SPDIF_USRDRn(0) ... SPDIF_USRDRn(11): + case SPDIF_CHNSRn(0) ... SPDIF_CHNSRn(11): return true; default: return false; @@ -264,6 +297,9 @@ static bool rk_spdif_rd_reg(struct device *dev, unsigned int reg) case SPDIF_INTSR: case SPDIF_XFER: case SPDIF_SMPDR: + case SPDIF_VLDFRn(0) ... SPDIF_VLDFRn(11): + case SPDIF_USRDRn(0) ... SPDIF_USRDRn(11): + case SPDIF_CHNSRn(0) ... SPDIF_CHNSRn(11): return true; default: return false; @@ -286,7 +322,7 @@ static const struct regmap_config rk_spdif_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = SPDIF_SMPDR, + .max_register = SPDIF_VERSION, .writeable_reg = rk_spdif_wr_reg, .readable_reg = rk_spdif_rd_reg, .volatile_reg = rk_spdif_volatile_reg, diff --git a/sound/soc/rockchip/rockchip_spdif.h b/sound/soc/rockchip/rockchip_spdif.h index 762d570b5326..1dbac8719cb2 100644 --- a/sound/soc/rockchip/rockchip_spdif.h +++ b/sound/soc/rockchip/rockchip_spdif.h @@ -17,6 +17,10 @@ #define SPDIF_CFGR_CLK_DIV_MASK (0xff << SPDIF_CFGR_CLK_DIV_SHIFT) #define SPDIF_CFGR_CLK_DIV(x) ((x - 1) << SPDIF_CFGR_CLK_DIV_SHIFT) +#define SPDIF_CFGR_CSE_MASK BIT(6) +#define SPDIF_CFGR_CSE_EN BIT(6) +#define SPDIF_CFGR_CSE_DIS 0 + #define SPDIF_CFGR_HALFWORD_SHIFT 2 #define SPDIF_CFGR_HALFWORD_DISABLE (0 << SPDIF_CFGR_HALFWORD_SHIFT) #define SPDIF_CFGR_HALFWORD_ENABLE (1 << SPDIF_CFGR_HALFWORD_SHIFT) @@ -56,5 +60,9 @@ #define SPDIF_INTSR (0x0010) #define SPDIF_XFER (0x0018) #define SPDIF_SMPDR (0x0020) +#define SPDIF_VLDFRn(x) (0x0060 + (x) * 4) +#define SPDIF_USRDRn(x) (0x0090 + (x) * 4) +#define SPDIF_CHNSRn(x) (0x00c0 + (x) * 4) +#define SPDIF_VERSION (0x01c0) #endif /* _ROCKCHIP_SPDIF_H */