summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.cirrus.com>2025-11-20 15:30:18 +0000
committerMark Brown <broonie@kernel.org>2025-11-20 17:22:57 +0000
commit193c65ec8ed4d946b3f80b7d08e4320ded7ac4fa (patch)
treecdb5186099987e80c98520f69c78a944eb5ed37b
parent222cbe172e5f7de130cc9c3c85f8f33d51c131bc (diff)
ASoC: SDCA: Populate regmap cache for readable Controls
It is not uncommon for an SDCA Control to have no specified default value in the DisCo. Non-volatile registers with no defaults will not be present in the cache until they are accessed. However, if the first operation user-space performs is a read whilst the device is runtime suspended this read will fail. To avoid such problems we should populate values from the hardware into the cache for all non-volatile readable registers with no defaults. Update the defaults handling to do this cache population since it is iterating over the Controls and happens at a time the hardware is always powered up. Tested-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Maciej Strozek <mstrozek@opensource.cirrus.com> Reviewed-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Tested-by: Richard Fitzgerald <rf@opensource.cirrus.com> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20251120153023.2105663-10-ckeepax@opensource.cirrus.com Reviewed-by: Vinod Koul <vkoul@kernel.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/sdca/sdca_regmap.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/sound/soc/sdca/sdca_regmap.c b/sound/soc/sdca/sdca_regmap.c
index 5104ae99df33..6fbb241d9d35 100644
--- a/sound/soc/sdca/sdca_regmap.c
+++ b/sound/soc/sdca/sdca_regmap.c
@@ -286,24 +286,33 @@ static int populate_control_defaults(struct device *dev, struct regmap *regmap,
if (control->mode == SDCA_ACCESS_MODE_DC)
return 0;
- if (!control->has_default && !control->has_fixed)
+ if (control->layers & SDCA_ACCESS_LAYER_DEVICE)
return 0;
i = 0;
for_each_set_bit(cn, (unsigned long *)&control->cn_list,
BITS_PER_TYPE(control->cn_list)) {
- unsigned int reg;
+ unsigned int reg, val;
reg = SDW_SDCA_CTL(function->desc->adr, entity->id, control->sel, cn);
- ret = regmap_write(regmap, reg, control->values[i]);
- if (ret) {
- dev_err(dev, "Failed to write default %#x: %d\n",
- reg, ret);
- return ret;
- }
+ if (control->has_default || control->has_fixed) {
+ ret = regmap_write(regmap, reg, control->values[i]);
+ if (ret) {
+ dev_err(dev, "Failed to write default %#x: %d\n",
+ reg, ret);
+ return ret;
+ }
- i++;
+ i++;
+ } else if (!control->is_volatile) {
+ ret = regmap_read(regmap, reg, &val);
+ if (ret) {
+ dev_err(dev, "Failed to read initial %#x: %d\n",
+ reg, ret);
+ return ret;
+ }
+ }
}
return 0;
@@ -317,7 +326,10 @@ static int populate_control_defaults(struct device *dev, struct regmap *regmap,
*
* This function will write out to the hardware all the DisCo default and
* fixed value controls. This will cause them to be populated into the cache,
- * and subsequent handling can be done through a cache sync.
+ * and subsequent handling can be done through a cache sync. It will also
+ * read any non-volatile registers that don't have defaults/fixed values to
+ * populate those into the cache, this ensures they are available for reads
+ * even when the device is runtime suspended.
*
* Return: Returns zero on success, and a negative error code on failure.
*/