Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Charles Keepax and committed by
Mark Brown
193c65ec 222cbe17

+22 -10
+22 -10
sound/soc/sdca/sdca_regmap.c
··· 286 286 if (control->mode == SDCA_ACCESS_MODE_DC) 287 287 return 0; 288 288 289 - if (!control->has_default && !control->has_fixed) 289 + if (control->layers & SDCA_ACCESS_LAYER_DEVICE) 290 290 return 0; 291 291 292 292 i = 0; 293 293 for_each_set_bit(cn, (unsigned long *)&control->cn_list, 294 294 BITS_PER_TYPE(control->cn_list)) { 295 - unsigned int reg; 295 + unsigned int reg, val; 296 296 297 297 reg = SDW_SDCA_CTL(function->desc->adr, entity->id, control->sel, cn); 298 298 299 - ret = regmap_write(regmap, reg, control->values[i]); 300 - if (ret) { 301 - dev_err(dev, "Failed to write default %#x: %d\n", 302 - reg, ret); 303 - return ret; 304 - } 299 + if (control->has_default || control->has_fixed) { 300 + ret = regmap_write(regmap, reg, control->values[i]); 301 + if (ret) { 302 + dev_err(dev, "Failed to write default %#x: %d\n", 303 + reg, ret); 304 + return ret; 305 + } 305 306 306 - i++; 307 + i++; 308 + } else if (!control->is_volatile) { 309 + ret = regmap_read(regmap, reg, &val); 310 + if (ret) { 311 + dev_err(dev, "Failed to read initial %#x: %d\n", 312 + reg, ret); 313 + return ret; 314 + } 315 + } 307 316 } 308 317 309 318 return 0; ··· 326 317 * 327 318 * This function will write out to the hardware all the DisCo default and 328 319 * fixed value controls. This will cause them to be populated into the cache, 329 - * and subsequent handling can be done through a cache sync. 320 + * and subsequent handling can be done through a cache sync. It will also 321 + * read any non-volatile registers that don't have defaults/fixed values to 322 + * populate those into the cache, this ensures they are available for reads 323 + * even when the device is runtime suspended. 330 324 * 331 325 * Return: Returns zero on success, and a negative error code on failure. 332 326 */