summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.cirrus.com>2025-02-17 14:01:58 +0000
committerMark Brown <broonie@kernel.org>2025-02-27 13:09:13 +0000
commit28c12866c22c2826ccbd8c82dc353f02ab2deea5 (patch)
treebe1ca1ba039964137e82bc52eb4dc154bd9894dc
parente3f7caf74b795621252e3c25b4a9fb6888336ef1 (diff)
ASoC: SDCA: Add regmap helpers for parsing for DisCo Constant values
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> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> Link: https://patch.msgid.link/20250217140159.2288784-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/sdca_regmap.h6
-rw-r--r--sound/soc/sdca/sdca_regmap.c80
2 files changed, 86 insertions, 0 deletions
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");