ASoC: SDCA: Force some SDCA Controls to be volatile

Whilst SDCA does specify an Access Mode for each Control, there is not a
1-to-1 mapping between that and ASoC's internal representation. Some
registers require being treated as volatile from the hosts perspective
even in their Access Mode is Read-Write. Add an explicit list of SDCA
controls that should be forced volatile.

Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Link: https://patch.msgid.link/20251020155512.353774-10-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Charles Keepax
2025-10-20 16:55:02 +01:00
committed by Mark Brown
parent dfe7c3401e
commit c7b6c6b605
3 changed files with 60 additions and 8 deletions

View File

@@ -771,6 +771,7 @@ struct sdca_control {
u8 layers;
bool deferrable;
bool is_volatile;
bool has_default;
bool has_fixed;
};

View File

@@ -779,6 +779,62 @@ find_sdca_control_datatype(const struct sdca_entity *entity,
}
}
static bool find_sdca_control_volatile(const struct sdca_entity *entity,
const struct sdca_control *control)
{
switch (control->mode) {
case SDCA_ACCESS_MODE_DC:
return false;
case SDCA_ACCESS_MODE_RO:
case SDCA_ACCESS_MODE_RW1S:
case SDCA_ACCESS_MODE_RW1C:
return true;
default:
break;
}
switch (SDCA_CTL_TYPE(entity->type, control->sel)) {
case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER):
case SDCA_CTL_TYPE_S(XU, FDL_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(XU, FDL_MESSAGELENGTH):
case SDCA_CTL_TYPE_S(XU, FDL_STATUS):
case SDCA_CTL_TYPE_S(XU, FDL_HOST_REQUEST):
case SDCA_CTL_TYPE_S(SPE, AUTHTX_CURRENTOWNER):
case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGELENGTH):
case SDCA_CTL_TYPE_S(SPE, AUTHRX_CURRENTOWNER):
case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGELENGTH):
case SDCA_CTL_TYPE_S(MFPU, AE_CURRENTOWNER):
case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGELENGTH):
case SDCA_CTL_TYPE_S(SMPU, HIST_CURRENTOWNER):
case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGELENGTH):
case SDCA_CTL_TYPE_S(SMPU, DTODTX_CURRENTOWNER):
case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGELENGTH):
case SDCA_CTL_TYPE_S(SMPU, DTODRX_CURRENTOWNER):
case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGELENGTH):
case SDCA_CTL_TYPE_S(SAPU, DTODTX_CURRENTOWNER):
case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGELENGTH):
case SDCA_CTL_TYPE_S(SAPU, DTODRX_CURRENTOWNER):
case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGELENGTH):
case SDCA_CTL_TYPE_S(HIDE, HIDTX_CURRENTOWNER):
case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGELENGTH):
case SDCA_CTL_TYPE_S(HIDE, HIDRX_CURRENTOWNER):
case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGEOFFSET):
case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGELENGTH):
return true;
default:
return false;
}
}
static int find_sdca_control_range(struct device *dev,
struct fwnode_handle *control_node,
struct sdca_control_range *range)
@@ -930,6 +986,8 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
break;
}
control->is_volatile = find_sdca_control_volatile(entity, control);
ret = find_sdca_control_range(dev, control_node, &control->range);
if (ret) {
dev_err(dev, "%s: control %#x: range missing: %d\n",

View File

@@ -147,14 +147,7 @@ bool sdca_regmap_volatile(struct sdca_function_data *function, unsigned int reg)
if (!control)
return false;
switch (control->mode) {
case SDCA_ACCESS_MODE_RO:
case SDCA_ACCESS_MODE_RW1S:
case SDCA_ACCESS_MODE_RW1C:
return true;
default:
return false;
}
return control->is_volatile;
}
EXPORT_SYMBOL_NS(sdca_regmap_volatile, "SND_SOC_SDCA");