* [PATCH 0/6] Some minor SDCA preparation
@ 2025-03-12 17:21 Charles Keepax
2025-03-12 17:22 ` [PATCH 1/6] ASoC: SDCA: Tidy up initialization write parsing Charles Keepax
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Charles Keepax @ 2025-03-12 17:21 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, pierre-louis.bossart, yung-chuan.liao, peter.ujfalusi,
linux-sound, linux-kernel, patches
Make some small fixups and add some minor missing features that will be
needed for the next major part of the SDCA work. This series doesn't do
a lot on its own, but as the next series will add all the ALSA control
and DAPM graph creation it's probably best to get these minor things out
of the way to simplify review on the bigger stuff.
Thanks,
Charles
Charles Keepax (6):
ASoC: SDCA: Tidy up initialization write parsing
ASoC: SDCA: Use __free() to manage local buffers
ASoC: SDCA: Allow naming of imp def controls
ASoC: SDCA: Add type flag for Controls
ASoC: SDCA: Add SDCA Control Range data access helper
ASoC: SDCA: Add support for GE Entity properties
include/sound/sdca_function.h | 90 ++++++++
sound/soc/sdca/sdca_functions.c | 374 ++++++++++++++++++++++++++++----
2 files changed, 422 insertions(+), 42 deletions(-)
--
2.39.5
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/6] ASoC: SDCA: Tidy up initialization write parsing
2025-03-12 17:21 [PATCH 0/6] Some minor SDCA preparation Charles Keepax
@ 2025-03-12 17:22 ` Charles Keepax
2025-03-12 17:22 ` [PATCH 2/6] ASoC: SDCA: Use __free() to manage local buffers Charles Keepax
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Charles Keepax @ 2025-03-12 17:22 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, pierre-louis.bossart, yung-chuan.liao, peter.ujfalusi,
linux-sound, linux-kernel, patches
Slightly neaten up the initialization write code to overlay a struct
rather than shifting the pointer along manually. This also removes the
Sparse warning:
sound/soc/sdca/sdca_functions.c:233:36: warning: cast to restricted __le32
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
sound/soc/sdca/sdca_functions.c | 43 ++++++++++++++++-----------------
1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
index 091d55abe1091..133cbde17ef48 100644
--- a/sound/soc/sdca/sdca_functions.c
+++ b/sound/soc/sdca/sdca_functions.c
@@ -10,6 +10,7 @@
#include <linux/acpi.h>
#include <linux/byteorder/generic.h>
+#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/dev_printk.h>
#include <linux/module.h>
@@ -186,14 +187,18 @@ void sdca_lookup_functions(struct sdw_slave *slave)
}
EXPORT_SYMBOL_NS(sdca_lookup_functions, "SND_SOC_SDCA");
+struct raw_init_write {
+ __le32 addr;
+ u8 val;
+} __packed;
+
static int find_sdca_init_table(struct device *dev,
struct fwnode_handle *function_node,
struct sdca_function_data *function)
{
+ struct raw_init_write *raw __free(kfree) = NULL;
struct sdca_init_write *init_write;
- int write_size = sizeof(init_write->addr) + sizeof(init_write->val);
- u8 *init_list, *init_iter;
- int num_init_writes;
+ int i, num_init_writes;
num_init_writes = fwnode_property_count_u8(function_node,
"mipi-sdca-function-initialization-table");
@@ -203,7 +208,7 @@ static int find_sdca_init_table(struct device *dev,
dev_err(dev, "%pfwP: failed to read initialization table: %d\n",
function_node, num_init_writes);
return num_init_writes;
- } else if (num_init_writes % write_size != 0) {
+ } else if (num_init_writes % sizeof(*raw) != 0) {
dev_err(dev, "%pfwP: init table size invalid\n", function_node);
return -EINVAL;
} else if (num_init_writes > SDCA_MAX_INIT_COUNT) {
@@ -211,33 +216,27 @@ static int find_sdca_init_table(struct device *dev,
return -EINVAL;
}
- init_write = devm_kcalloc(dev, num_init_writes / write_size,
- sizeof(*init_write), GFP_KERNEL);
- if (!init_write)
- return -ENOMEM;
-
- init_list = kcalloc(num_init_writes, sizeof(*init_list), GFP_KERNEL);
- if (!init_list)
+ raw = kzalloc(num_init_writes, GFP_KERNEL);
+ if (!raw)
return -ENOMEM;
fwnode_property_read_u8_array(function_node,
"mipi-sdca-function-initialization-table",
- init_list, num_init_writes);
+ (u8 *)raw, num_init_writes);
- function->num_init_table = num_init_writes;
- function->init_table = init_write;
+ num_init_writes /= sizeof(*raw);
- for (init_iter = init_list; init_iter < init_list + num_init_writes;) {
- u32 *addr = (u32 *)init_iter;
-
- init_write->addr = le32_to_cpu(*addr);
- init_iter += sizeof(init_write->addr);
+ init_write = devm_kcalloc(dev, num_init_writes, sizeof(*init_write), GFP_KERNEL);
+ if (!init_write)
+ return -ENOMEM;
- init_write->val = *init_iter;
- init_iter += sizeof(init_write->val);
+ for (i = 0; i < num_init_writes; i++) {
+ init_write[i].addr = le32_to_cpu(raw[i].addr);
+ init_write[i].val = raw[i].val;
}
- kfree(init_list);
+ function->num_init_table = num_init_writes;
+ function->init_table = init_write;
return 0;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/6] ASoC: SDCA: Use __free() to manage local buffers
2025-03-12 17:21 [PATCH 0/6] Some minor SDCA preparation Charles Keepax
2025-03-12 17:22 ` [PATCH 1/6] ASoC: SDCA: Tidy up initialization write parsing Charles Keepax
@ 2025-03-12 17:22 ` Charles Keepax
2025-03-12 17:22 ` [PATCH 3/6] ASoC: SDCA: Allow naming of imp def controls Charles Keepax
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Charles Keepax @ 2025-03-12 17:22 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, pierre-louis.bossart, yung-chuan.liao, peter.ujfalusi,
linux-sound, linux-kernel, patches
Use the cleanup.h helpers to manage some local buffers, this cleans up
the error paths a little.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
sound/soc/sdca/sdca_functions.c | 17 ++++-------------
1 file changed, 4 insertions(+), 13 deletions(-)
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
index 133cbde17ef48..4ee98d8fe89ed 100644
--- a/sound/soc/sdca/sdca_functions.c
+++ b/sound/soc/sdca/sdca_functions.c
@@ -913,9 +913,9 @@ static int find_sdca_entity_pde(struct device *dev,
{
static const int mult_delay = 3;
struct sdca_entity_pde *power = &entity->pde;
+ u32 *delay_list __free(kfree) = NULL;
struct sdca_pde_delay *delays;
int num_delays;
- u32 *delay_list;
int i, j;
num_delays = fwnode_property_count_u32(entity_node,
@@ -962,8 +962,6 @@ static int find_sdca_entity_pde(struct device *dev,
power->num_max_delay = num_delays;
power->max_delay = delays;
- kfree(delay_list);
-
return 0;
}
@@ -1022,8 +1020,8 @@ static int find_sdca_entities(struct device *dev,
struct fwnode_handle *function_node,
struct sdca_function_data *function)
{
+ u32 *entity_list __free(kfree) = NULL;
struct sdca_entity *entities;
- u32 *entity_list;
int num_entities;
int i, ret;
@@ -1054,8 +1052,6 @@ static int find_sdca_entities(struct device *dev,
for (i = 0; i < num_entities; i++)
entities[i].id = entity_list[i];
- kfree(entity_list);
-
/* now read subproperties */
for (i = 0; i < num_entities; i++) {
char entity_property[SDCA_PROPERTY_LENGTH];
@@ -1170,8 +1166,8 @@ static int find_sdca_entity_connection_pde(struct device *dev,
struct sdca_entity *entity)
{
struct sdca_entity_pde *power = &entity->pde;
+ u32 *managed_list __free(kfree) = NULL;
struct sdca_entity **managed;
- u32 *managed_list;
int num_managed;
int i;
@@ -1205,15 +1201,12 @@ static int find_sdca_entity_connection_pde(struct device *dev,
if (!managed[i]) {
dev_err(dev, "%s: failed to find entity with id %#x\n",
entity->label, managed_list[i]);
- kfree(managed_list);
return -EINVAL;
}
dev_info(dev, "%s -> %s\n", managed[i]->label, entity->label);
}
- kfree(managed_list);
-
power->num_managed = num_managed;
power->managed = managed;
@@ -1453,9 +1446,9 @@ static int find_sdca_clusters(struct device *dev,
struct fwnode_handle *function_node,
struct sdca_function_data *function)
{
+ u32 *cluster_list __free(kfree) = NULL;
struct sdca_cluster *clusters;
int num_clusters;
- u32 *cluster_list;
int i, ret;
num_clusters = fwnode_property_count_u32(function_node, "mipi-sdca-cluster-id-list");
@@ -1484,8 +1477,6 @@ static int find_sdca_clusters(struct device *dev,
for (i = 0; i < num_clusters; i++)
clusters[i].id = cluster_list[i];
- kfree(cluster_list);
-
/* now read subproperties */
for (i = 0; i < num_clusters; i++) {
char cluster_property[SDCA_PROPERTY_LENGTH];
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/6] ASoC: SDCA: Allow naming of imp def controls
2025-03-12 17:21 [PATCH 0/6] Some minor SDCA preparation Charles Keepax
2025-03-12 17:22 ` [PATCH 1/6] ASoC: SDCA: Tidy up initialization write parsing Charles Keepax
2025-03-12 17:22 ` [PATCH 2/6] ASoC: SDCA: Use __free() to manage local buffers Charles Keepax
@ 2025-03-12 17:22 ` Charles Keepax
2025-03-12 17:22 ` [PATCH 4/6] ASoC: SDCA: Add type flag for Controls Charles Keepax
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Charles Keepax @ 2025-03-12 17:22 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, pierre-louis.bossart, yung-chuan.liao, peter.ujfalusi,
linux-sound, linux-kernel, patches
Implementation defined controls will not be present in the large list of
known controls for SDCA. The driver should not return an error for these,
because it is perfectly legal to have implementation defined controls.
Update the handling to instead generate a generic name.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
sound/soc/sdca/sdca_functions.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
index 4ee98d8fe89ed..1e36dd20d7abf 100644
--- a/sound/soc/sdca/sdca_functions.c
+++ b/sound/soc/sdca/sdca_functions.c
@@ -241,7 +241,8 @@ static int find_sdca_init_table(struct device *dev,
return 0;
}
-static const char *find_sdca_control_label(const struct sdca_entity *entity,
+static const char *find_sdca_control_label(struct device *dev,
+ const struct sdca_entity *entity,
const struct sdca_control *control)
{
switch (SDCA_CTL_TYPE(entity->type, control->sel)) {
@@ -530,7 +531,7 @@ static const char *find_sdca_control_label(const struct sdca_entity *entity,
case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_SDCA_VERSION):
return SDCA_CTL_DEVICE_SDCA_VERSION_NAME;
default:
- return NULL;
+ return devm_kasprintf(dev, GFP_KERNEL, "Imp-Def %#x", control->sel);
}
}
@@ -739,12 +740,9 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
if (!ret)
control->interrupt_position = tmp;
- control->label = find_sdca_control_label(entity, control);
- if (!control->label) {
- dev_err(dev, "%s: control %#x: name not found\n",
- entity->label, control->sel);
- return -EINVAL;
- }
+ control->label = find_sdca_control_label(dev, entity, control);
+ if (!control->label)
+ return -ENOMEM;
control->nbits = find_sdca_control_bits(entity, control);
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/6] ASoC: SDCA: Add type flag for Controls
2025-03-12 17:21 [PATCH 0/6] Some minor SDCA preparation Charles Keepax
` (2 preceding siblings ...)
2025-03-12 17:22 ` [PATCH 3/6] ASoC: SDCA: Allow naming of imp def controls Charles Keepax
@ 2025-03-12 17:22 ` Charles Keepax
2025-03-12 17:22 ` [PATCH 5/6] ASoC: SDCA: Add SDCA Control Range data access helper Charles Keepax
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Charles Keepax @ 2025-03-12 17:22 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, pierre-louis.bossart, yung-chuan.liao, peter.ujfalusi,
linux-sound, linux-kernel, patches
SDCA Controls come in a variety of data formats, to simplify later
parsing work out this data type as the control is parsed and stash it
for later use.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
include/sound/sdca_function.h | 23 +++++
sound/soc/sdca/sdca_functions.c | 173 ++++++++++++++++++++++++++++++++
2 files changed, 196 insertions(+)
diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h
index f001ab643fed4..ca0376903e87c 100644
--- a/include/sound/sdca_function.h
+++ b/include/sound/sdca_function.h
@@ -600,6 +600,27 @@ enum sdca_entity0_controls {
#define SDCA_CTL_DEVICE_VERSION_NAME "Device Version"
#define SDCA_CTL_DEVICE_SDCA_VERSION_NAME "Device SDCA Version"
+/**
+ * enum sdca_control_datatype - SDCA Control Data Types
+ *
+ * Data Types as described in the SDCA specification v1.0 section
+ * 7.3.
+ */
+enum sdca_control_datatype {
+ SDCA_CTL_DATATYPE_ONEBIT,
+ SDCA_CTL_DATATYPE_INTEGER,
+ SDCA_CTL_DATATYPE_SPEC_ENCODED_VALUE,
+ SDCA_CTL_DATATYPE_BCD,
+ SDCA_CTL_DATATYPE_Q7P8DB,
+ SDCA_CTL_DATATYPE_BYTEINDEX,
+ SDCA_CTL_DATATYPE_POSTURENUMBER,
+ SDCA_CTL_DATATYPE_DP_INDEX,
+ SDCA_CTL_DATATYPE_BITINDEX,
+ SDCA_CTL_DATATYPE_BITMAP,
+ SDCA_CTL_DATATYPE_GUID,
+ SDCA_CTL_DATATYPE_IMPDEF,
+};
+
/**
* enum sdca_access_mode - SDCA Control access mode
*
@@ -653,6 +674,7 @@ struct sdca_control_range {
* @cn_list: A bitmask showing the valid Control Numbers within this Control,
* Control Numbers typically represent channels.
* @range: Buffer describing valid range of values for the Control.
+ * @type: Format of the data in the Control.
* @mode: Access mode of the Control.
* @layers: Bitmask of access layers of the Control.
* @deferrable: Indicates if the access to the Control can be deferred.
@@ -669,6 +691,7 @@ struct sdca_control {
u64 cn_list;
struct sdca_control_range range;
+ enum sdca_control_datatype type;
enum sdca_access_mode mode;
u8 layers;
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
index 1e36dd20d7abf..0cc25fb9679b4 100644
--- a/sound/soc/sdca/sdca_functions.c
+++ b/sound/soc/sdca/sdca_functions.c
@@ -603,6 +603,178 @@ static unsigned int find_sdca_control_bits(const struct sdca_entity *entity,
}
}
+static enum sdca_control_datatype
+find_sdca_control_datatype(const struct sdca_entity *entity,
+ const struct sdca_control *control)
+{
+ switch (SDCA_CTL_TYPE(entity->type, control->sel)) {
+ 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(FU, AGC):
+ case SDCA_CTL_TYPE_S(FU, BASS_BOOST):
+ case SDCA_CTL_TYPE_S(FU, LOUDNESS):
+ return SDCA_CTL_DATATYPE_ONEBIT;
+ case SDCA_CTL_TYPE_S(IT, LATENCY):
+ case SDCA_CTL_TYPE_S(OT, LATENCY):
+ case SDCA_CTL_TYPE_S(MU, LATENCY):
+ case SDCA_CTL_TYPE_S(SU, LATENCY):
+ case SDCA_CTL_TYPE_S(FU, LATENCY):
+ case SDCA_CTL_TYPE_S(XU, LATENCY):
+ case SDCA_CTL_TYPE_S(CRU, LATENCY):
+ case SDCA_CTL_TYPE_S(UDMPU, LATENCY):
+ case SDCA_CTL_TYPE_S(MFPU, LATENCY):
+ case SDCA_CTL_TYPE_S(SMPU, LATENCY):
+ case SDCA_CTL_TYPE_S(SAPU, LATENCY):
+ case SDCA_CTL_TYPE_S(PPU, LATENCY):
+ case SDCA_CTL_TYPE_S(SU, SELECTOR):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_0):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_1):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_2):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_3):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_4):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_5):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_6):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_7):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_8):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_9):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_10):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_11):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_12):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_13):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_14):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_15):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_16):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_17):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_18):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_19):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_20):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_21):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_22):
+ case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_23):
+ case SDCA_CTL_TYPE_S(SAPU, PROTECTION_MODE):
+ case SDCA_CTL_TYPE_S(SMPU, HIST_BUFFER_PREAMBLE):
+ case SDCA_CTL_TYPE_S(XU, FDL_HOST_REQUEST):
+ case SDCA_CTL_TYPE_S(XU, XU_ID):
+ case SDCA_CTL_TYPE_S(CX, CLOCK_SELECT):
+ case SDCA_CTL_TYPE_S(TG, TONE_DIVIDER):
+ case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_MANUFACTURER_ID):
+ case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_ID):
+ case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_EXTENSION_ID):
+ case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_MANUFACTURER_ID):
+ case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_PART_ID):
+ case SDCA_CTL_TYPE_S(XU, FDL_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(XU, FDL_MESSAGELENGTH):
+ case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGELENGTH):
+ case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGELENGTH):
+ case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGELENGTH):
+ case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGELENGTH):
+ case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGELENGTH):
+ case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGELENGTH):
+ case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGELENGTH):
+ case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGELENGTH):
+ case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGELENGTH):
+ case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGEOFFSET):
+ case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGELENGTH):
+ return SDCA_CTL_DATATYPE_INTEGER;
+ case SDCA_CTL_TYPE_S(IT, MIC_BIAS):
+ case SDCA_CTL_TYPE_S(SMPU, HIST_BUFFER_MODE):
+ case SDCA_CTL_TYPE_S(PDE, REQUESTED_PS):
+ case SDCA_CTL_TYPE_S(PDE, ACTUAL_PS):
+ case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_TYPE):
+ return SDCA_CTL_DATATYPE_SPEC_ENCODED_VALUE;
+ case SDCA_CTL_TYPE_S(XU, XU_VERSION):
+ case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_SDCA_VERSION):
+ case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_VERSION):
+ case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_EXTENSION_VERSION):
+ case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_VERSION):
+ case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_SDCA_VERSION):
+ return SDCA_CTL_DATATYPE_BCD;
+ case SDCA_CTL_TYPE_S(FU, CHANNEL_VOLUME):
+ case SDCA_CTL_TYPE_S(FU, GAIN):
+ case SDCA_CTL_TYPE_S(MU, MIXER):
+ case SDCA_CTL_TYPE_S(PPU, HORIZONTALBALANCE):
+ case SDCA_CTL_TYPE_S(PPU, VERTICALBALANCE):
+ case SDCA_CTL_TYPE_S(MFPU, ULTRASOUND_LEVEL):
+ case SDCA_CTL_TYPE_S(UDMPU, ACOUSTIC_ENERGY_LEVEL_MONITOR):
+ case SDCA_CTL_TYPE_S(UDMPU, ULTRASOUND_LOOP_GAIN):
+ return SDCA_CTL_DATATYPE_Q7P8DB;
+ case SDCA_CTL_TYPE_S(IT, USAGE):
+ case SDCA_CTL_TYPE_S(OT, USAGE):
+ case SDCA_CTL_TYPE_S(IT, CLUSTERINDEX):
+ case SDCA_CTL_TYPE_S(CRU, CLUSTERINDEX):
+ case SDCA_CTL_TYPE_S(UDMPU, CLUSTERINDEX):
+ case SDCA_CTL_TYPE_S(MFPU, CLUSTERINDEX):
+ case SDCA_CTL_TYPE_S(MFPU, CENTER_FREQUENCY_INDEX):
+ case SDCA_CTL_TYPE_S(MFPU, AE_NUMBER):
+ case SDCA_CTL_TYPE_S(SAPU, OPAQUESETREQ_INDEX):
+ case SDCA_CTL_TYPE_S(XU, FDL_SET_INDEX):
+ case SDCA_CTL_TYPE_S(CS, SAMPLERATEINDEX):
+ case SDCA_CTL_TYPE_S(GE, SELECTED_MODE):
+ case SDCA_CTL_TYPE_S(GE, DETECTED_MODE):
+ return SDCA_CTL_DATATYPE_BYTEINDEX;
+ case SDCA_CTL_TYPE_S(PPU, POSTURENUMBER):
+ return SDCA_CTL_DATATYPE_POSTURENUMBER;
+ case SDCA_CTL_TYPE_S(IT, DATAPORT_SELECTOR):
+ case SDCA_CTL_TYPE_S(OT, DATAPORT_SELECTOR):
+ return SDCA_CTL_DATATYPE_DP_INDEX;
+ case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_READY):
+ case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_ENABLE):
+ case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_PREPARE):
+ case SDCA_CTL_TYPE_S(SAPU, PROTECTION_STATUS):
+ case SDCA_CTL_TYPE_S(SMPU, TRIGGER_ENABLE):
+ case SDCA_CTL_TYPE_S(SMPU, TRIGGER_STATUS):
+ case SDCA_CTL_TYPE_S(SMPU, TRIGGER_READY):
+ case SDCA_CTL_TYPE_S(SPE, PRIVACY_POLICY):
+ case SDCA_CTL_TYPE_S(SPE, PRIVACY_OWNER):
+ return SDCA_CTL_DATATYPE_BITINDEX;
+ case SDCA_CTL_TYPE_S(IT, KEEP_ALIVE):
+ case SDCA_CTL_TYPE_S(OT, KEEP_ALIVE):
+ case SDCA_CTL_TYPE_S(IT, NDAI_STREAM):
+ case SDCA_CTL_TYPE_S(OT, NDAI_STREAM):
+ case SDCA_CTL_TYPE_S(IT, NDAI_CATEGORY):
+ case SDCA_CTL_TYPE_S(OT, NDAI_CATEGORY):
+ case SDCA_CTL_TYPE_S(IT, NDAI_CODINGTYPE):
+ case SDCA_CTL_TYPE_S(OT, NDAI_CODINGTYPE):
+ case SDCA_CTL_TYPE_S(IT, NDAI_PACKETTYPE):
+ case SDCA_CTL_TYPE_S(OT, NDAI_PACKETTYPE):
+ case SDCA_CTL_TYPE_S(SMPU, HIST_ERROR):
+ case SDCA_CTL_TYPE_S(XU, FDL_STATUS):
+ case SDCA_CTL_TYPE_S(CS, CLOCK_VALID):
+ case SDCA_CTL_TYPE_S(SPE, PRIVACY_LOCKSTATE):
+ case SDCA_CTL_TYPE_S(ENTITY_0, COMMIT_GROUP_MASK):
+ case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_STATUS):
+ case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_ACTION):
+ case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER):
+ case SDCA_CTL_TYPE_S(SPE, AUTHTX_CURRENTOWNER):
+ case SDCA_CTL_TYPE_S(SPE, AUTHRX_CURRENTOWNER):
+ case SDCA_CTL_TYPE_S(MFPU, AE_CURRENTOWNER):
+ case SDCA_CTL_TYPE_S(SMPU, HIST_CURRENTOWNER):
+ case SDCA_CTL_TYPE_S(SMPU, DTODTX_CURRENTOWNER):
+ case SDCA_CTL_TYPE_S(SMPU, DTODRX_CURRENTOWNER):
+ case SDCA_CTL_TYPE_S(SAPU, DTODTX_CURRENTOWNER):
+ case SDCA_CTL_TYPE_S(SAPU, DTODRX_CURRENTOWNER):
+ case SDCA_CTL_TYPE_S(HIDE, HIDTX_CURRENTOWNER):
+ case SDCA_CTL_TYPE_S(HIDE, HIDRX_CURRENTOWNER):
+ return SDCA_CTL_DATATYPE_BITMAP;
+ case SDCA_CTL_TYPE_S(IT, MATCHING_GUID):
+ case SDCA_CTL_TYPE_S(OT, MATCHING_GUID):
+ case SDCA_CTL_TYPE_S(ENTITY_0, MATCHING_GUID):
+ return SDCA_CTL_DATATYPE_GUID;
+ default:
+ return SDCA_CTL_DATATYPE_IMPDEF;
+ }
+}
+
static int find_sdca_control_range(struct device *dev,
struct fwnode_handle *control_node,
struct sdca_control_range *range)
@@ -744,6 +916,7 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
if (!control->label)
return -ENOMEM;
+ control->type = find_sdca_control_datatype(entity, control);
control->nbits = find_sdca_control_bits(entity, control);
dev_info(dev, "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d value %#x %s\n",
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/6] ASoC: SDCA: Add SDCA Control Range data access helper
2025-03-12 17:21 [PATCH 0/6] Some minor SDCA preparation Charles Keepax
` (3 preceding siblings ...)
2025-03-12 17:22 ` [PATCH 4/6] ASoC: SDCA: Add type flag for Controls Charles Keepax
@ 2025-03-12 17:22 ` Charles Keepax
2025-03-12 17:22 ` [PATCH 6/6] ASoC: SDCA: Add support for GE Entity properties Charles Keepax
2025-03-17 21:54 ` [PATCH 0/6] Some minor SDCA preparation Mark Brown
6 siblings, 0 replies; 8+ messages in thread
From: Charles Keepax @ 2025-03-12 17:22 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, pierre-louis.bossart, yung-chuan.liao, peter.ujfalusi,
linux-sound, linux-kernel, patches
SDCA Ranges are two dimensional arrays of data associated with controls,
add a helper to provide an x,y access mechanism to the data and a helper
to locate a specific value inside a range.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
include/sound/sdca_function.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h
index ca0376903e87c..d7489e3c7e471 100644
--- a/include/sound/sdca_function.h
+++ b/include/sound/sdca_function.h
@@ -1136,6 +1136,25 @@ struct sdca_function_data {
unsigned int busy_max_delay;
};
+static inline u32 sdca_range(struct sdca_control_range *range,
+ unsigned int col, unsigned int row)
+{
+ return range->data[(row * range->cols) + col];
+}
+
+static inline u32 sdca_range_search(struct sdca_control_range *range,
+ int search_col, int value, int result_col)
+{
+ int i;
+
+ for (i = 0; i < range->rows; i++) {
+ if (sdca_range(range, search_col, i) == value)
+ return sdca_range(range, result_col, i);
+ }
+
+ return 0;
+}
+
int sdca_parse_function(struct device *dev,
struct sdca_function_desc *desc,
struct sdca_function_data *function);
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/6] ASoC: SDCA: Add support for GE Entity properties
2025-03-12 17:21 [PATCH 0/6] Some minor SDCA preparation Charles Keepax
` (4 preceding siblings ...)
2025-03-12 17:22 ` [PATCH 5/6] ASoC: SDCA: Add SDCA Control Range data access helper Charles Keepax
@ 2025-03-12 17:22 ` Charles Keepax
2025-03-17 21:54 ` [PATCH 0/6] Some minor SDCA preparation Mark Brown
6 siblings, 0 replies; 8+ messages in thread
From: Charles Keepax @ 2025-03-12 17:22 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, pierre-louis.bossart, yung-chuan.liao, peter.ujfalusi,
linux-sound, linux-kernel, patches
Add support for parsing the Group Entity properties from DisCo/ACPI.
Group Entities allow control of several other Entities, typically
Selector Units, from a single control.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
include/sound/sdca_function.h | 48 ++++++++++++
sound/soc/sdca/sdca_functions.c | 129 ++++++++++++++++++++++++++++++++
2 files changed, 177 insertions(+)
diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h
index d7489e3c7e471..253654568a41e 100644
--- a/include/sound/sdca_function.h
+++ b/include/sound/sdca_function.h
@@ -44,6 +44,11 @@ struct sdca_function_desc;
*/
#define SDCA_MAX_DELAY_COUNT 256
+/*
+ * Sanity check on size of affected controls data, can be expanded if needed.
+ */
+#define SDCA_MAX_AFFECTED_COUNT 2048
+
/**
* enum sdca_function_type - SDCA Function Type codes
* @SDCA_FUNCTION_TYPE_SMART_AMP: Amplifier with protection features.
@@ -927,11 +932,51 @@ enum sdca_entity_type {
SDCA_ENTITY_TYPE_HIDE = 0x31,
};
+/**
+ * struct sdca_ge_control - control entry in the affected controls list
+ * @id: Entity ID of the Control affected.
+ * @sel: Control Selector of the Control affected.
+ * @cn: Control Number of the Control affected.
+ * @val: Value written to Control for this Mode.
+ */
+struct sdca_ge_control {
+ int id;
+ int sel;
+ int cn;
+ int val;
+};
+
+/**
+ * struct sdca_ge_mode - mode entry in the affected controls list
+ * @controls: Dynamically allocated array of controls written for this Mode.
+ * @num_controls: Number of controls written in this Mode.
+ * @val: GE Selector Mode value.
+ */
+struct sdca_ge_mode {
+ struct sdca_ge_control *controls;
+ int num_controls;
+ int val;
+};
+
+/**
+ * struct sdca_entity_ge - information specific to Group Entities
+ * @kctl: ALSA control pointer that can be used by linked Entities.
+ * @modes: Dynamically allocated array of Modes and the Controls written
+ * in each mode.
+ * @num_modes: Number of Modes.
+ */
+struct sdca_entity_ge {
+ struct snd_kcontrol_new *kctl;
+ struct sdca_ge_mode *modes;
+ int num_modes;
+};
+
/**
* struct sdca_entity - information for one SDCA Entity
* @label: String such as "OT 12".
* @id: Identifier used for addressing.
* @type: Type code for the Entity.
+ * @group: Pointer to Group Entity controlling this one, NULL if N/A.
* @sources: Dynamically allocated array pointing to each input Entity
* connected to this Entity.
* @controls: Dynamically allocated array of Controls.
@@ -940,12 +985,14 @@ enum sdca_entity_type {
* @iot: Input/Output Terminal specific Entity properties.
* @cs: Clock Source specific Entity properties.
* @pde: Power Domain Entity specific Entity properties.
+ * @ge: Group Entity specific Entity properties.
*/
struct sdca_entity {
const char *label;
int id;
enum sdca_entity_type type;
+ struct sdca_entity *group;
struct sdca_entity **sources;
struct sdca_control *controls;
int num_sources;
@@ -954,6 +1001,7 @@ struct sdca_entity {
struct sdca_entity_iot iot;
struct sdca_entity_cs cs;
struct sdca_entity_pde pde;
+ struct sdca_entity_ge ge;
};
};
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
index 0cc25fb9679b4..c8efdc5301b53 100644
--- a/sound/soc/sdca/sdca_functions.c
+++ b/sound/soc/sdca/sdca_functions.c
@@ -1136,6 +1136,92 @@ static int find_sdca_entity_pde(struct device *dev,
return 0;
}
+struct raw_ge_mode {
+ u8 val;
+ u8 num_controls;
+ struct {
+ u8 id;
+ u8 sel;
+ u8 cn;
+ __le32 val;
+ } __packed controls[] __counted_by(num_controls);
+} __packed;
+
+static int find_sdca_entity_ge(struct device *dev,
+ struct fwnode_handle *entity_node,
+ struct sdca_entity *entity)
+{
+ struct sdca_entity_ge *group = &entity->ge;
+ u8 *affected_list __free(kfree) = NULL;
+ u8 *affected_iter;
+ int num_affected;
+ int i, j;
+
+ num_affected = fwnode_property_count_u8(entity_node,
+ "mipi-sdca-ge-selectedmode-controls-affected");
+ if (!num_affected || num_affected == -EINVAL) {
+ return 0;
+ } else if (num_affected < 0) {
+ dev_err(dev, "%s: failed to read affected controls: %d\n",
+ entity->label, num_affected);
+ return num_affected;
+ } else if (num_affected > SDCA_MAX_AFFECTED_COUNT) {
+ dev_err(dev, "%s: maximum affected controls size exceeded\n",
+ entity->label);
+ return -EINVAL;
+ }
+
+ affected_list = kcalloc(num_affected, sizeof(*affected_list), GFP_KERNEL);
+ if (!affected_list)
+ return -ENOMEM;
+
+ fwnode_property_read_u8_array(entity_node,
+ "mipi-sdca-ge-selectedmode-controls-affected",
+ affected_list, num_affected);
+
+ group->num_modes = *affected_list;
+ affected_iter = affected_list + 1;
+
+ group->modes = devm_kcalloc(dev, group->num_modes, sizeof(*group->modes),
+ GFP_KERNEL);
+ if (!group->modes)
+ return -ENOMEM;
+
+ for (i = 0; i < group->num_modes; i++) {
+ struct raw_ge_mode *raw = (struct raw_ge_mode *)affected_iter;
+ struct sdca_ge_mode *mode = &group->modes[i];
+
+ affected_iter += sizeof(*raw);
+ if (affected_iter > affected_list + num_affected)
+ goto bad_list;
+
+ mode->val = raw->val;
+ mode->num_controls = raw->num_controls;
+
+ affected_iter += mode->num_controls * sizeof(raw->controls[0]);
+ if (affected_iter > affected_list + num_affected)
+ goto bad_list;
+
+ mode->controls = devm_kcalloc(dev, mode->num_controls,
+ sizeof(*mode->controls), GFP_KERNEL);
+ if (!mode->controls)
+ return -ENOMEM;
+
+ for (j = 0; j < mode->num_controls; j++) {
+ mode->controls[j].id = raw->controls[j].id;
+ mode->controls[j].sel = raw->controls[j].sel;
+ mode->controls[j].cn = raw->controls[j].cn;
+ mode->controls[j].val = le32_to_cpu(raw->controls[j].val);
+ }
+ }
+
+ return 0;
+
+bad_list:
+ dev_err(dev, "%s: malformed affected controls list\n", entity->label);
+ return -EINVAL;
+}
+
static int find_sdca_entity(struct device *dev,
struct fwnode_handle *function_node,
struct fwnode_handle *entity_node,
@@ -1174,6 +1260,9 @@ static int find_sdca_entity(struct device *dev,
case SDCA_ENTITY_TYPE_PDE:
ret = find_sdca_entity_pde(dev, entity_node, entity);
break;
+ case SDCA_ENTITY_TYPE_GE:
+ ret = find_sdca_entity_ge(dev, entity_node, entity);
+ break;
default:
break;
}
@@ -1384,6 +1473,42 @@ static int find_sdca_entity_connection_pde(struct device *dev,
return 0;
}
+static int find_sdca_entity_connection_ge(struct device *dev,
+ struct sdca_function_data *function,
+ struct fwnode_handle *entity_node,
+ struct sdca_entity *entity)
+{
+ int i, j;
+
+ for (i = 0; i < entity->ge.num_modes; i++) {
+ struct sdca_ge_mode *mode = &entity->ge.modes[i];
+
+ for (j = 0; j < mode->num_controls; j++) {
+ struct sdca_ge_control *affected = &mode->controls[j];
+ struct sdca_entity *managed;
+
+ managed = find_sdca_entity_by_id(function, affected->id);
+ if (!managed) {
+ dev_err(dev, "%s: failed to find entity with id %#x\n",
+ entity->label, affected->id);
+ return -EINVAL;
+ }
+
+ if (managed->group && managed->group != entity) {
+ dev_err(dev,
+ "%s: entity controlled by two groups %s, %s\n",
+ managed->label, managed->group->label,
+ entity->label);
+ return -EINVAL;
+ }
+
+ managed->group = entity;
+ }
+ }
+
+ return 0;
+}
+
static int find_sdca_entity_connection(struct device *dev,
struct sdca_function_data *function,
struct fwnode_handle *entity_node,
@@ -1404,6 +1529,10 @@ static int find_sdca_entity_connection(struct device *dev,
ret = find_sdca_entity_connection_pde(dev, function,
entity_node, entity);
break;
+ case SDCA_ENTITY_TYPE_GE:
+ ret = find_sdca_entity_connection_ge(dev, function,
+ entity_node, entity);
+ break;
default:
ret = 0;
break;
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 0/6] Some minor SDCA preparation
2025-03-12 17:21 [PATCH 0/6] Some minor SDCA preparation Charles Keepax
` (5 preceding siblings ...)
2025-03-12 17:22 ` [PATCH 6/6] ASoC: SDCA: Add support for GE Entity properties Charles Keepax
@ 2025-03-17 21:54 ` Mark Brown
6 siblings, 0 replies; 8+ messages in thread
From: Mark Brown @ 2025-03-17 21:54 UTC (permalink / raw)
To: Charles Keepax
Cc: lgirdwood, pierre-louis.bossart, yung-chuan.liao, peter.ujfalusi,
linux-sound, linux-kernel, patches
On Wed, 12 Mar 2025 17:21:59 +0000, Charles Keepax wrote:
> Make some small fixups and add some minor missing features that will be
> needed for the next major part of the SDCA work. This series doesn't do
> a lot on its own, but as the next series will add all the ALSA control
> and DAPM graph creation it's probably best to get these minor things out
> of the way to simplify review on the bigger stuff.
>
> Thanks,
> Charles
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/6] ASoC: SDCA: Tidy up initialization write parsing
commit: 988adcb73669a4015974da9057d43226ddc1aa9d
[2/6] ASoC: SDCA: Use __free() to manage local buffers
commit: 0d16daa9405ef7de5c278183d4079013f39a51ac
[3/6] ASoC: SDCA: Allow naming of imp def controls
commit: 49680c9f13b64c13e79e1312c7616d0ab9775e4a
[4/6] ASoC: SDCA: Add type flag for Controls
commit: 2a4667f3d589524bd2fbfe4f7dc0e2f12b832e10
[5/6] ASoC: SDCA: Add SDCA Control Range data access helper
commit: 1bcbb88bedb17804491e692a3f1a38223e09152c
[6/6] ASoC: SDCA: Add support for GE Entity properties
commit: d1cd13f80dc6c8525c539a28d4eb1df913d542de
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-03-17 21:54 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-12 17:21 [PATCH 0/6] Some minor SDCA preparation Charles Keepax
2025-03-12 17:22 ` [PATCH 1/6] ASoC: SDCA: Tidy up initialization write parsing Charles Keepax
2025-03-12 17:22 ` [PATCH 2/6] ASoC: SDCA: Use __free() to manage local buffers Charles Keepax
2025-03-12 17:22 ` [PATCH 3/6] ASoC: SDCA: Allow naming of imp def controls Charles Keepax
2025-03-12 17:22 ` [PATCH 4/6] ASoC: SDCA: Add type flag for Controls Charles Keepax
2025-03-12 17:22 ` [PATCH 5/6] ASoC: SDCA: Add SDCA Control Range data access helper Charles Keepax
2025-03-12 17:22 ` [PATCH 6/6] ASoC: SDCA: Add support for GE Entity properties Charles Keepax
2025-03-17 21:54 ` [PATCH 0/6] Some minor SDCA preparation Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox