diff mbox series

[3/4] ASoC: SDCA: Add regmap helpers for parsing for DisCo Constant values

Message ID 20250217140159.2288784-4-ckeepax@opensource.cirrus.com (mailing list archive)
State New
Headers show
Series Add SDCA register map support | expand

Commit Message

Charles Keepax Feb. 17, 2025, 2:01 p.m. UTC
Add helpers to parse the DisCo Constant values from ACPI and populate an
array of reg_defaults with these. This will allow drivers to access
these ACPI specified values through the same interface as other
registers that are physically present on the device, using the regmap
cache.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
 include/sound/sdca_regmap.h  |  6 +++
 sound/soc/sdca/sdca_regmap.c | 80 ++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+)
diff mbox series

Patch

diff --git a/include/sound/sdca_regmap.h b/include/sound/sdca_regmap.h
index 11826f4f0726..850533e83f3b 100644
--- a/include/sound/sdca_regmap.h
+++ b/include/sound/sdca_regmap.h
@@ -10,7 +10,9 @@ 
 #ifndef __SDCA_REGMAP_H__
 #define __SDCA_REGMAP_H__
 
+struct device;
 struct sdca_function_data;
+struct reg_default;
 
 bool sdca_regmap_readable(struct sdca_function_data *function, unsigned int reg);
 bool sdca_regmap_writeable(struct sdca_function_data *function, unsigned int reg);
@@ -18,4 +20,8 @@  bool sdca_regmap_volatile(struct sdca_function_data *function, unsigned int reg)
 bool sdca_regmap_deferrable(struct sdca_function_data *function, unsigned int reg);
 int sdca_regmap_mbq_size(struct sdca_function_data *function, unsigned int reg);
 
+int sdca_regmap_count_constants(struct device *dev, struct sdca_function_data *function);
+int sdca_regmap_populate_constants(struct device *dev, struct sdca_function_data *function,
+				   struct reg_default *consts);
+
 #endif // __SDCA_REGMAP_H__
diff --git a/sound/soc/sdca/sdca_regmap.c b/sound/soc/sdca/sdca_regmap.c
index ae6358f0fc26..dba4188620f9 100644
--- a/sound/soc/sdca/sdca_regmap.c
+++ b/sound/soc/sdca/sdca_regmap.c
@@ -10,8 +10,10 @@ 
 #include <linux/bitops.h>
 #include <linux/minmax.h>
 #include <linux/module.h>
+#include <linux/regmap.h>
 #include <linux/soundwire/sdw_registers.h>
 #include <linux/types.h>
+#include <sound/sdca.h>
 #include <sound/sdca_function.h>
 #include <sound/sdca_regmap.h>
 
@@ -188,5 +190,83 @@  int sdca_regmap_mbq_size(struct sdca_function_data *function, unsigned int reg)
 }
 EXPORT_SYMBOL_NS(sdca_regmap_mbq_size, "SND_SOC_SDCA");
 
+/**
+ * sdca_regmap_count_constants - count the number of DisCo constant Controls
+ * @dev: Pointer to the device.
+ * @function: Pointer to the Function information, to be parsed.
+ *
+ * This function returns the number of DisCo constant Controls present
+ * in a function. Typically this information will be used to populate
+ * the regmap defaults array, allowing drivers to access the values of
+ * DisCo constants as any other physical register.
+ *
+ * Return: Returns number of DisCo constant controls, or a negative error
+ * code on failure.
+ */
+int sdca_regmap_count_constants(struct device *dev,
+				struct sdca_function_data *function)
+{
+	int nconsts = 0;
+	int i, j;
+
+	for (i = 0; i < function->num_entities; i++) {
+		struct sdca_entity *entity = &function->entities[i];
+
+		for (j = 0; j < entity->num_controls; j++) {
+			if (entity->controls[j].mode == SDCA_ACCESS_MODE_DC)
+				nconsts += hweight64(entity->controls[j].cn_list);
+		}
+	}
+
+	return nconsts;
+}
+EXPORT_SYMBOL_NS(sdca_regmap_count_constants, "SND_SOC_SDCA");
+
+/**
+ * sdca_regmap_populate_constants - fill an array with DisCo constant values
+ * @dev: Pointer to the device.
+ * @function: Pointer to the Function information, to be parsed.
+ * @consts: Pointer to the array which should be filled with the DisCo
+ * constant values.
+ *
+ * This function will populate a regmap struct reg_default array with
+ * the values of the DisCo constants for a given Function. This
+ * allows to access the values of DisCo constants the same as any
+ * other physical register.
+ *
+ * Return: Returns the number of constants populated on success, a negative
+ * error code on failure.
+ */
+int sdca_regmap_populate_constants(struct device *dev,
+				   struct sdca_function_data *function,
+				   struct reg_default *consts)
+{
+	int i, j, k;
+
+	for (i = 0, k = 0; i < function->num_entities; i++) {
+		struct sdca_entity *entity = &function->entities[i];
+
+		for (j = 0; j < entity->num_controls; j++) {
+			struct sdca_control *control = &entity->controls[j];
+			int cn;
+
+			if (control->mode != SDCA_ACCESS_MODE_DC)
+				continue;
+
+			for_each_set_bit(cn, (unsigned long *)&control->cn_list,
+					 BITS_PER_TYPE(control->cn_list)) {
+				consts[k].reg = SDW_SDCA_CTL(function->desc->adr,
+							     entity->id,
+							     control->sel, cn);
+				consts[k].def = control->value;
+				k++;
+			}
+		}
+	}
+
+	return k;
+}
+EXPORT_SYMBOL_NS(sdca_regmap_populate_constants, "SND_SOC_SDCA");
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SDCA library");