Alternative kernel package based on Arch Linux 6.19.9 with 12 upstream SDCA backport patches that enable audio on Intel Panther Lake systems (Dell XPS 2026 and similar hardware with CS35L57 SoundWire amps). The stock 6.19.9 kernel lacks the SDCA class/function topology driver code needed for PTL audio. These patches backport the SDCA support from mainline v7.0 to the stable 6.19.x series. Tested on Dell XPS 16 (Panther Lake): all 4 CS35L57 amps probe with calibration, SDCA jack detection works, sof-soundwire sound card registers successfully. CONFIG_RUST is disabled to avoid build failures with newer Rust toolchain versions. Rust is not required for audio functionality.
161 lines
5.6 KiB
Diff
161 lines
5.6 KiB
Diff
From a80d5cd47c6d2eb3890235a527ad41a73b28009e Mon Sep 17 00:00:00 2001
|
|
From: Charles Keepax <ckeepax@opensource.cirrus.com>
|
|
Date: Wed, 4 Feb 2026 12:59:42 +0000
|
|
Subject: [PATCH 13/17] ASoC: SDCA: Add regmap defaults for specification
|
|
defined values
|
|
|
|
Some of the SDCA Controls have a defined reset value in the
|
|
specification. Update the parsing to add these specification defined
|
|
values into the regmap defaults array. This will reduce the number of
|
|
registers that are synchronised on a cache sync.
|
|
|
|
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
|
Link: https://patch.msgid.link/20260204125944.1134011-6-ckeepax@opensource.cirrus.com
|
|
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
---
|
|
include/sound/sdca_function.h | 4 ++++
|
|
sound/soc/sdca/sdca_functions.c | 36 +++++++++++++++++++++++++++++++++
|
|
sound/soc/sdca/sdca_regmap.c | 14 ++++++++++---
|
|
3 files changed, 51 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h
|
|
index 6e9391b3816c..79bd5a7a0f88 100644
|
|
--- a/include/sound/sdca_function.h
|
|
+++ b/include/sound/sdca_function.h
|
|
@@ -798,6 +798,7 @@ struct sdca_control_range {
|
|
* @sel: Identifier used for addressing.
|
|
* @nbits: Number of bits used in the Control.
|
|
* @values: Holds the Control value for constants and defaults.
|
|
+ * @reset: Defined reset value for the Control.
|
|
* @cn_list: A bitmask showing the valid Control Numbers within this Control,
|
|
* Control Numbers typically represent channels.
|
|
* @interrupt_position: SCDA interrupt line that will alert to changes on this
|
|
@@ -808,6 +809,7 @@ struct sdca_control_range {
|
|
* @layers: Bitmask of access layers of the Control.
|
|
* @deferrable: Indicates if the access to the Control can be deferred.
|
|
* @has_default: Indicates the Control has a default value to be written.
|
|
+ * @has_reset: Indicates the Control has a defined reset value.
|
|
* @has_fixed: Indicates the Control only supports a single value.
|
|
*/
|
|
struct sdca_control {
|
|
@@ -816,6 +818,7 @@ struct sdca_control {
|
|
|
|
int nbits;
|
|
int *values;
|
|
+ int reset;
|
|
u64 cn_list;
|
|
int interrupt_position;
|
|
|
|
@@ -827,6 +830,7 @@ struct sdca_control {
|
|
bool deferrable;
|
|
bool is_volatile;
|
|
bool has_default;
|
|
+ bool has_reset;
|
|
bool has_fixed;
|
|
};
|
|
|
|
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
|
|
index f38791eab4f1..95b67bb904c3 100644
|
|
--- a/sound/soc/sdca/sdca_functions.c
|
|
+++ b/sound/soc/sdca/sdca_functions.c
|
|
@@ -911,6 +911,38 @@ static int find_sdca_control_value(struct device *dev, struct sdca_entity *entit
|
|
return 0;
|
|
}
|
|
|
|
+static int find_sdca_control_reset(const struct sdca_entity *entity,
|
|
+ struct sdca_control *control)
|
|
+{
|
|
+ switch (SDCA_CTL_TYPE(entity->type, control->sel)) {
|
|
+ case SDCA_CTL_TYPE_S(FU, AGC):
|
|
+ case SDCA_CTL_TYPE_S(FU, BASS_BOOST):
|
|
+ case SDCA_CTL_TYPE_S(FU, LOUDNESS):
|
|
+ case SDCA_CTL_TYPE_S(SMPU, TRIGGER_ENABLE):
|
|
+ case SDCA_CTL_TYPE_S(GE, SELECTED_MODE):
|
|
+ case SDCA_CTL_TYPE_S(TG, TONE_DIVIDER):
|
|
+ case SDCA_CTL_TYPE_S(ENTITY_0, COMMIT_GROUP_MASK):
|
|
+ control->has_reset = true;
|
|
+ control->reset = 0;
|
|
+ break;
|
|
+ case SDCA_CTL_TYPE_S(XU, BYPASS):
|
|
+ case SDCA_CTL_TYPE_S(MFPU, BYPASS):
|
|
+ case SDCA_CTL_TYPE_S(FU, MUTE):
|
|
+ case SDCA_CTL_TYPE_S(CX, CLOCK_SELECT):
|
|
+ control->has_reset = true;
|
|
+ control->reset = 1;
|
|
+ break;
|
|
+ case SDCA_CTL_TYPE_S(PDE, REQUESTED_PS):
|
|
+ control->has_reset = true;
|
|
+ control->reset = 3;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int find_sdca_entity_control(struct device *dev, struct sdca_entity *entity,
|
|
struct fwnode_handle *control_node,
|
|
struct sdca_control *control)
|
|
@@ -986,6 +1018,10 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
|
|
|
|
control->is_volatile = find_sdca_control_volatile(entity, control);
|
|
|
|
+ ret = find_sdca_control_reset(entity, control);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
ret = find_sdca_control_range(dev, control_node, &control->range);
|
|
if (ret) {
|
|
dev_err(dev, "%s: control %#x: range missing: %d\n",
|
|
diff --git a/sound/soc/sdca/sdca_regmap.c b/sound/soc/sdca/sdca_regmap.c
|
|
index 2cca9a9c71ea..4f8a685dc43d 100644
|
|
--- a/sound/soc/sdca/sdca_regmap.c
|
|
+++ b/sound/soc/sdca/sdca_regmap.c
|
|
@@ -218,7 +218,8 @@ int sdca_regmap_count_constants(struct device *dev,
|
|
struct sdca_entity *entity = &function->entities[i];
|
|
|
|
for (j = 0; j < entity->num_controls; j++) {
|
|
- if (entity->controls[j].mode == SDCA_ACCESS_MODE_DC)
|
|
+ if (entity->controls[j].mode == SDCA_ACCESS_MODE_DC ||
|
|
+ entity->controls[j].has_reset)
|
|
nconsts += hweight64(entity->controls[j].cn_list);
|
|
}
|
|
}
|
|
@@ -255,7 +256,8 @@ int sdca_regmap_populate_constants(struct device *dev,
|
|
struct sdca_control *control = &entity->controls[j];
|
|
int cn;
|
|
|
|
- if (control->mode != SDCA_ACCESS_MODE_DC)
|
|
+ if (control->mode != SDCA_ACCESS_MODE_DC &&
|
|
+ !control->has_reset)
|
|
continue;
|
|
|
|
l = 0;
|
|
@@ -264,7 +266,10 @@ int sdca_regmap_populate_constants(struct device *dev,
|
|
consts[k].reg = SDW_SDCA_CTL(function->desc->adr,
|
|
entity->id,
|
|
control->sel, cn);
|
|
- consts[k].def = control->values[l];
|
|
+ if (control->mode == SDCA_ACCESS_MODE_DC)
|
|
+ consts[k].def = control->values[l];
|
|
+ else
|
|
+ consts[k].def = control->reset;
|
|
k++;
|
|
l++;
|
|
}
|
|
@@ -306,6 +311,9 @@ static int populate_control_defaults(struct device *dev, struct regmap *regmap,
|
|
|
|
i++;
|
|
} else if (!control->is_volatile) {
|
|
+ if (control->has_reset)
|
|
+ regcache_drop_region(regmap, reg, reg);
|
|
+
|
|
ret = regmap_read(regmap, reg, &val);
|
|
if (ret) {
|
|
dev_err(dev, "Failed to read initial %#x: %d\n",
|
|
--
|
|
2.43.0
|
|
|