]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: rockchip: spdif: Fill IEC958 CS info per params
authorSugar Zhang <sugar.zhang@rock-chips.com>
Tue, 3 Feb 2026 16:46:31 +0000 (17:46 +0100)
committerMark Brown <broonie@kernel.org>
Thu, 5 Feb 2026 18:46:47 +0000 (18:46 +0000)
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>
sound/soc/rockchip/Kconfig
sound/soc/rockchip/rockchip_spdif.c
sound/soc/rockchip/rockchip_spdif.h

index bd210fafe9fea1b4ab7a7b813c63503e9a5dbbd1..391ce2225fde04f7f97cd4da33f19222d6245537 100644 (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
index d06573f228052ec6b7bfd1f43b3f8a6f9e2eec03..e64c24897f29a6e6f5a78049302c570707eb28b7 100644 (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,
index acf64986a2e09a6c37595e5c5fa4418f83e00b68..b837b1f8d57f3538d023a0ab747bcfcd8cb83f62 100644 (file)
 #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 */