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 <sugar.zhang@rock-chips.com>
Change-Id: I1e1e3ffb8f3706ae19117c4ae3fc38e20a71f78b
This commit is contained in:
Sugar Zhang
2022-09-02 11:43:27 +08:00
parent 4501f4263f
commit 6938d9c200
3 changed files with 49 additions and 4 deletions

View File

@@ -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

View File

@@ -17,6 +17,7 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <sound/pcm_params.h>
#include <sound/pcm_iec958.h>
#include <sound/dmaengine_pcm.h>
#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,

View File

@@ -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 */