]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: rsnd: ssiu: Add RZ/G3E BUSIF support
authorJohn Madieu <john.madieu.xa@bp.renesas.com>
Mon, 25 May 2026 11:02:22 +0000 (11:02 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 1 Jun 2026 14:30:20 +0000 (15:30 +0100)
Add support for the SSIU found on the Renesas RZ/G3E SoC, which
provides a different BUSIF layout compared to earlier generations:

 - SSI0-SSI4: 4 BUSIF instances each (BUSIF0-3)
 - SSI5-SSI8: 1 BUSIF instance each (BUSIF0 only)
 - SSI9:      4 BUSIF instances (BUSIF0-3)
 - Total:     28 BUSIFs

The RZ/G3E also has only two pairs of BUSIF error-status registers
instead of four, and the SSI always operates in BUSIF mode: the
SSI_MODE0 BUSIF/PIO select bit is not implemented and must not be written.

While at it, add RSND_SSIU_BUSIF_STATUS_COUNT_2 as a capability flag in
the match data, consumed via struct rsnd_ssiu_ctrl, to parametrise the two
BUSIF error-status loops.

Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://patch.msgid.link/20260525110230.4014435-11-john.madieu.xa@bp.renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/renesas/rcar/core.c
sound/soc/renesas/rcar/rsnd.h
sound/soc/renesas/rcar/ssiu.c

index 7169d0ef8f9008e0f2861e2ddf422f3cca42b479..f5c8ba8c5d565117e8e55460a0467f58bf8eb028 100644 (file)
@@ -106,7 +106,8 @@ static const struct of_device_id rsnd_of_match[] = {
        { .compatible = "renesas,rcar_sound-gen4", .data = (void *)RSND_GEN4 },
        /* Special Handling */
        { .compatible = "renesas,rcar_sound-r8a77990", .data = (void *)(RSND_GEN3 | RSND_SOC_E) },
-       { .compatible = "renesas,r9a09g047-sound", .data = (void *)(RSND_RZ3 | RSND_RZG3E) },
+       { .compatible = "renesas,r9a09g047-sound",
+                       .data = (void *)(RSND_RZ3 | RSND_RZG3E | RSND_SSIU_BUSIF_STATUS_COUNT_2) },
        {},
 };
 MODULE_DEVICE_TABLE(of, rsnd_of_match);
index e917aa12fa80cb61822ae03027cdd9df90993d9e..95843a20c43cc916275ac615120b93368dd91d0c 100644 (file)
@@ -666,6 +666,7 @@ struct rsnd_priv {
 #define RSND_RZ3       (3 << 8)
 #define RSND_RZ_ID_MASK        (0xF << 12) /* nibble D */
 #define RSND_RZG3E     (1 << 12)
+#define RSND_SSIU_BUSIF_STATUS_COUNT_2 BIT(16) /* Only 2 BUSIF error-status register pairs */
        /*
         * below value will be filled on rsnd_gen_probe()
         */
@@ -690,6 +691,7 @@ struct rsnd_priv {
        /*
         * below value will be filled on rsnd_ssiu_probe()
         */
+       void *ssiu_ctrl;
        void *ssiu;
        int ssiu_nr;
 
index 2b922ead62d098f8fd35644ad5ad3e4045129bf4..8d4ce9d35e9e709311aa00ee90aae4d0fcc18595 100644 (file)
@@ -29,31 +29,39 @@ struct rsnd_ssiu {
             i++)
 
 /*
- *     SSI     Gen2            Gen3            Gen4
- *     0       BUSIF0-3        BUSIF0-7        BUSIF0-7
- *     1       BUSIF0-3        BUSIF0-7
- *     2       BUSIF0-3        BUSIF0-7
- *     3       BUSIF0          BUSIF0-7
- *     4       BUSIF0          BUSIF0-7
- *     5       BUSIF0          BUSIF0
- *     6       BUSIF0          BUSIF0
- *     7       BUSIF0          BUSIF0
- *     8       BUSIF0          BUSIF0
- *     9       BUSIF0-3        BUSIF0-7
- *     total   22              52              8
+ *     SSI     Gen2            Gen3            Gen4            RZ/G3E
+ *     0       BUSIF0-3        BUSIF0-7        BUSIF0-7        BUSIF0-3
+ *     1       BUSIF0-3        BUSIF0-7                        BUSIF0-3
+ *     2       BUSIF0-3        BUSIF0-7                        BUSIF0-3
+ *     3       BUSIF0          BUSIF0-7                        BUSIF0-3
+ *     4       BUSIF0          BUSIF0-7                        BUSIF0-3
+ *     5       BUSIF0          BUSIF0                          BUSIF0
+ *     6       BUSIF0          BUSIF0                          BUSIF0
+ *     7       BUSIF0          BUSIF0                          BUSIF0
+ *     8       BUSIF0          BUSIF0                          BUSIF0
+ *     9       BUSIF0-3        BUSIF0-7                        BUSIF0-3
+ *     total   22              52              8               28
  */
 static const int gen2_id[] = { 0, 4,  8, 12, 13, 14, 15, 16, 17, 18 };
 static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 };
 static const int gen4_id[] = { 0 };
+static const int rzg3e_id[] = { 0, 4, 8, 12, 16, 20, 21, 22, 23, 24 };
+
+struct rsnd_ssiu_ctrl {
+       unsigned int busif_status_count;
+};
+
+#define rsnd_priv_to_ssiu_ctrl(priv) \
+       ((struct rsnd_ssiu_ctrl *)(priv)->ssiu_ctrl)
 
 /* enable busif buffer over/under run interrupt. */
 #define rsnd_ssiu_busif_err_irq_enable(mod)  rsnd_ssiu_busif_err_irq_ctrl(mod, 1)
 #define rsnd_ssiu_busif_err_irq_disable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 0)
 static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
 {
+       struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
        int id = rsnd_mod_id(mod);
        int shift, offset;
-       int i;
 
        switch (id) {
        case 0:
@@ -72,7 +80,7 @@ static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
                return;
        }
 
-       for (i = 0; i < 4; i++) {
+       for (unsigned int i = 0; i < rsnd_priv_to_ssiu_ctrl(priv)->busif_status_count; i++) {
                enum rsnd_reg reg = SSI_SYS_INT_ENABLE((i * 2) + offset);
                u32 val = 0xf << (shift * 4);
                u32 sys_int_enable = rsnd_mod_read(mod, reg);
@@ -87,10 +95,10 @@ static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
 
 bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod)
 {
+       struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
        bool error = false;
        int id = rsnd_mod_id(mod);
        int shift, offset;
-       int i;
 
        switch (id) {
        case 0:
@@ -109,14 +117,13 @@ bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod)
                goto out;
        }
 
-       for (i = 0; i < 4; i++) {
+       for (unsigned int i = 0; i < rsnd_priv_to_ssiu_ctrl(priv)->busif_status_count; i++) {
                u32 reg = SSI_SYS_STATUS(i * 2) + offset;
                u32 status = rsnd_mod_read(mod, reg);
                u32 val = 0xf << (shift * 4);
 
                status &= val;
                if (status) {
-                       struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
                        struct device *dev = rsnd_priv_to_dev(priv);
 
                        rsnd_print_irq_status(dev, "%s err status : 0x%08x\n",
@@ -160,7 +167,8 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
        /*
         * SSI_MODE0
         */
-       rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
+       if (!rsnd_is_rzg3e(priv))
+               rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
 
        /*
         * SSI_MODE1 / SSI_MODE2
@@ -511,6 +519,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
        struct device *dev = rsnd_priv_to_dev(priv);
        struct device_node *node __free(device_node) = rsnd_ssiu_of_node(priv);
        struct reset_control *rstc;
+       struct rsnd_ssiu_ctrl *ctrl;
        struct rsnd_ssiu *ssiu;
        struct rsnd_mod_ops *ops;
        const int *list = NULL;
@@ -535,8 +544,15 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
        if (!ssiu)
                return -ENOMEM;
 
+       ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
+       if (!ctrl)
+               return -ENOMEM;
+
+       ctrl->busif_status_count = rsnd_flags_has(priv, RSND_SSIU_BUSIF_STATUS_COUNT_2) ? 2 : 4;
+
        priv->ssiu      = ssiu;
        priv->ssiu_nr   = nr;
+       priv->ssiu_ctrl = ctrl;
 
        if (rsnd_is_gen1(priv))
                ops = &rsnd_ssiu_ops_gen1;
@@ -559,6 +575,9 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
                } else if (rsnd_is_gen4(priv)) {
                        list    = gen4_id;
                        nr      = ARRAY_SIZE(gen4_id);
+               } else if (rsnd_is_rzg3e(priv)) {
+                       list    = rzg3e_id;
+                       nr      = ARRAY_SIZE(rzg3e_id);
                } else {
                        dev_err(dev, "unknown SSIU\n");
                        return -ENODEV;