ASoC: rockchip: spdif: Fill IEC958 CS info per params

Add support to fill IEC958 channel status information.

Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patch.msgid.link/20260203-rockchip-spdif-cleanup-and-bsp-sync-v2-9-4412016cf577@collabora.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Sugar Zhang 2026-02-03 17:46:31 +01:00 committed by Mark Brown
parent c43ec50901
commit 07a791020b
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0
3 changed files with 50 additions and 4 deletions

View file

@ -41,6 +41,7 @@ config SND_SOC_ROCKCHIP_SAI
config SND_SOC_ROCKCHIP_SPDIF
tristate "Rockchip SPDIF Device Driver"
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

@ -16,6 +16,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"
@ -27,7 +28,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;
@ -88,8 +107,20 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
unsigned int mclk_rate = clk_get_rate(spdif->mclk);
unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE;
int bmc, div;
int ret;
int bmc, div, ret, i;
u16 *fc;
u8 cs[CS_BYTE];
ret = snd_pcm_create_iec958_consumer_hw_params(params, cs, sizeof(cs));
if (ret < 0)
return ret;
fc = (u16 *)cs;
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);
@ -239,6 +270,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;
@ -254,6 +288,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;
@ -276,7 +313,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

@ -21,6 +21,10 @@
#define SPDIF_CFGR_CLR_EN BIT(7)
#define SPDIF_CFGR_CLR_DIS 0
#define SPDIF_CFGR_CSE_MASK BIT(6)
#define SPDIF_CFGR_CSE_EN BIT(6)
#define SPDIF_CFGR_CSE_DIS 0
#define SPDIF_CFGR_ADJ_MASK BIT(3)
#define SPDIF_CFGR_ADJ_LEFT_J BIT(3)
#define SPDIF_CFGR_ADJ_RIGHT_J 0
@ -64,5 +68,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 */