]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: SDCA: Fix some holes in the regmap readable/writeable helpers
authorCharles Keepax <ckeepax@opensource.cirrus.com>
Fri, 18 Jul 2025 13:54:31 +0000 (14:54 +0100)
committerMark Brown <broonie@kernel.org>
Thu, 24 Jul 2025 12:28:08 +0000 (13:28 +0100)
The current regmap readable/writeable helper functions always
allow the Next flag and allows any Control Number. Mask the Next
flag based on SDCA_ACCESS_MODE_DUAL which is the only Mode that
supports it. Also check that the Control Number is valid for
the given control.

Fixes: e3f7caf74b79 ("ASoC: SDCA: Add generic regmap SDCA helpers")
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20250718135432.1048566-2-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sdca/sdca_regmap.c

index 66e7eee7d7f498abd3f795ba92365252f48f1b74..c41c67c2204a41966c74687a14c3cb8516a95101 100644 (file)
@@ -72,12 +72,18 @@ bool sdca_regmap_readable(struct sdca_function_data *function, unsigned int reg)
        if (!control)
                return false;
 
+       if (!(BIT(SDW_SDCA_CTL_CNUM(reg)) & control->cn_list))
+               return false;
+
        switch (control->mode) {
        case SDCA_ACCESS_MODE_RW:
        case SDCA_ACCESS_MODE_RO:
-       case SDCA_ACCESS_MODE_DUAL:
        case SDCA_ACCESS_MODE_RW1S:
        case SDCA_ACCESS_MODE_RW1C:
+               if (SDW_SDCA_NEXT_CTL(0) & reg)
+                       return false;
+               fallthrough;
+       case SDCA_ACCESS_MODE_DUAL:
                /* No access to registers marked solely for device use */
                return control->layers & ~SDCA_ACCESS_LAYER_DEVICE;
        default:
@@ -104,11 +110,17 @@ bool sdca_regmap_writeable(struct sdca_function_data *function, unsigned int reg
        if (!control)
                return false;
 
+       if (!(BIT(SDW_SDCA_CTL_CNUM(reg)) & control->cn_list))
+               return false;
+
        switch (control->mode) {
        case SDCA_ACCESS_MODE_RW:
-       case SDCA_ACCESS_MODE_DUAL:
        case SDCA_ACCESS_MODE_RW1S:
        case SDCA_ACCESS_MODE_RW1C:
+               if (SDW_SDCA_NEXT_CTL(0) & reg)
+                       return false;
+               fallthrough;
+       case SDCA_ACCESS_MODE_DUAL:
                /* No access to registers marked solely for device use */
                return control->layers & ~SDCA_ACCESS_LAYER_DEVICE;
        default: