ASoC: SDCA: Add terminal type into input/output widget name

There have been some complaints around the UCM files for SDCA
devices that the control system is quite hard to follow. This is
definitely true without the specification handy the naming can be
a little cryptic. However, as most of the information is parsed
from DisCo there are some limits to what the driver can safely do
to improve this.

However, one area that can be improved is the non-streaming
input/output terminals. These have a field (enum sdca_terminal_type)
that describes the usage of that terminal. These types can be
appended to the entity name to give the users a better clue as
to the purpose. For example "OT 43", would now become "OT 43
Headphone". This would follow through into the jack controls which
would change from "OT 43 Jack" to "OT 43 Headphone Jack", making the
purpose much more obvious to the user.

This provides slightly more readable controls without relying on
implicit knowledge that individual parts might not conform to.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20251127163426.2500633-3-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Charles Keepax 2025-11-27 16:34:21 +00:00 committed by Mark Brown
parent 5fee9edf79
commit 48fa77af2f
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
3 changed files with 59 additions and 47 deletions

View File

@ -1456,6 +1456,8 @@ int sdca_parse_function(struct device *dev, struct sdw_slave *sdw,
struct sdca_function_desc *desc, struct sdca_function_desc *desc,
struct sdca_function_data *function); struct sdca_function_data *function);
const char *sdca_find_terminal_name(enum sdca_terminal_type type);
struct sdca_control *sdca_selector_find_control(struct device *dev, struct sdca_control *sdca_selector_find_control(struct device *dev,
struct sdca_entity *entity, struct sdca_entity *entity,
const int sel); const int sel);

View File

@ -115,50 +115,6 @@ int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *fun
} }
EXPORT_SYMBOL_NS(sdca_asoc_count_component, "SND_SOC_SDCA"); EXPORT_SYMBOL_NS(sdca_asoc_count_component, "SND_SOC_SDCA");
static const char *get_terminal_name(enum sdca_terminal_type type)
{
switch (type) {
case SDCA_TERM_TYPE_LINEIN_STEREO:
return SDCA_TERM_TYPE_LINEIN_STEREO_NAME;
case SDCA_TERM_TYPE_LINEIN_FRONT_LR:
return SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME;
case SDCA_TERM_TYPE_LINEIN_CENTER_LFE:
return SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME;
case SDCA_TERM_TYPE_LINEIN_SURROUND_LR:
return SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME;
case SDCA_TERM_TYPE_LINEIN_REAR_LR:
return SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME;
case SDCA_TERM_TYPE_LINEOUT_STEREO:
return SDCA_TERM_TYPE_LINEOUT_STEREO_NAME;
case SDCA_TERM_TYPE_LINEOUT_FRONT_LR:
return SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME;
case SDCA_TERM_TYPE_LINEOUT_CENTER_LFE:
return SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME;
case SDCA_TERM_TYPE_LINEOUT_SURROUND_LR:
return SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME;
case SDCA_TERM_TYPE_LINEOUT_REAR_LR:
return SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME;
case SDCA_TERM_TYPE_MIC_JACK:
return SDCA_TERM_TYPE_MIC_JACK_NAME;
case SDCA_TERM_TYPE_STEREO_JACK:
return SDCA_TERM_TYPE_STEREO_JACK_NAME;
case SDCA_TERM_TYPE_FRONT_LR_JACK:
return SDCA_TERM_TYPE_FRONT_LR_JACK_NAME;
case SDCA_TERM_TYPE_CENTER_LFE_JACK:
return SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME;
case SDCA_TERM_TYPE_SURROUND_LR_JACK:
return SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME;
case SDCA_TERM_TYPE_REAR_LR_JACK:
return SDCA_TERM_TYPE_REAR_LR_JACK_NAME;
case SDCA_TERM_TYPE_HEADPHONE_JACK:
return SDCA_TERM_TYPE_HEADPHONE_JACK_NAME;
case SDCA_TERM_TYPE_HEADSET_JACK:
return SDCA_TERM_TYPE_HEADSET_JACK_NAME;
default:
return NULL;
}
}
static int entity_early_parse_ge(struct device *dev, static int entity_early_parse_ge(struct device *dev,
struct sdca_function_data *function, struct sdca_function_data *function,
struct sdca_entity *entity) struct sdca_entity *entity)
@ -217,7 +173,7 @@ static int entity_early_parse_ge(struct device *dev,
type = sdca_range(range, SDCA_SELECTED_MODE_TERM_TYPE, i); type = sdca_range(range, SDCA_SELECTED_MODE_TERM_TYPE, i);
values[i + 3] = sdca_range(range, SDCA_SELECTED_MODE_INDEX, i); values[i + 3] = sdca_range(range, SDCA_SELECTED_MODE_INDEX, i);
texts[i + 3] = get_terminal_name(type); texts[i + 3] = sdca_find_terminal_name(type);
if (!texts[i + 3]) { if (!texts[i + 3]) {
dev_err(dev, "%s: unrecognised terminal type: %#x\n", dev_err(dev, "%s: unrecognised terminal type: %#x\n",
entity->label, type); entity->label, type);
@ -499,7 +455,7 @@ static int entity_parse_su_device(struct device *dev,
return -EINVAL; return -EINVAL;
} }
add_route(route, entity->label, get_terminal_name(term), add_route(route, entity->label, sdca_find_terminal_name(term),
entity->sources[affected->val - 1]->label); entity->sources[affected->val - 1]->label);
} }
} }

View File

@ -14,6 +14,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/soundwire/sdw.h> #include <linux/soundwire/sdw.h>
#include <linux/string.h>
#include <linux/types.h> #include <linux/types.h>
#include <sound/sdca.h> #include <sound/sdca.h>
#include <sound/sdca_function.h> #include <sound/sdca_function.h>
@ -1120,6 +1121,14 @@ static int find_sdca_entity_iot(struct device *dev,
terminal->type = tmp; terminal->type = tmp;
terminal->is_dataport = find_sdca_iot_dataport(terminal); terminal->is_dataport = find_sdca_iot_dataport(terminal);
if (!terminal->is_dataport) {
const char *type_name = sdca_find_terminal_name(terminal->type);
if (type_name)
entity->label = devm_kasprintf(dev, GFP_KERNEL, "%s %s",
entity->label, type_name);
}
ret = fwnode_property_read_u32(entity_node, ret = fwnode_property_read_u32(entity_node,
"mipi-sdca-terminal-reference-number", &tmp); "mipi-sdca-terminal-reference-number", &tmp);
if (!ret) if (!ret)
@ -1565,7 +1574,7 @@ static struct sdca_entity *find_sdca_entity_by_label(struct sdca_function_data *
for (i = 0; i < function->num_entities; i++) { for (i = 0; i < function->num_entities; i++) {
struct sdca_entity *entity = &function->entities[i]; struct sdca_entity *entity = &function->entities[i];
if (!strcmp(entity->label, entity_label)) if (!strncmp(entity->label, entity_label, strlen(entity_label)))
return entity; return entity;
} }
@ -2156,6 +2165,51 @@ int sdca_parse_function(struct device *dev, struct sdw_slave *sdw,
} }
EXPORT_SYMBOL_NS(sdca_parse_function, "SND_SOC_SDCA"); EXPORT_SYMBOL_NS(sdca_parse_function, "SND_SOC_SDCA");
const char *sdca_find_terminal_name(enum sdca_terminal_type type)
{
switch (type) {
case SDCA_TERM_TYPE_LINEIN_STEREO:
return SDCA_TERM_TYPE_LINEIN_STEREO_NAME;
case SDCA_TERM_TYPE_LINEIN_FRONT_LR:
return SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME;
case SDCA_TERM_TYPE_LINEIN_CENTER_LFE:
return SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME;
case SDCA_TERM_TYPE_LINEIN_SURROUND_LR:
return SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME;
case SDCA_TERM_TYPE_LINEIN_REAR_LR:
return SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME;
case SDCA_TERM_TYPE_LINEOUT_STEREO:
return SDCA_TERM_TYPE_LINEOUT_STEREO_NAME;
case SDCA_TERM_TYPE_LINEOUT_FRONT_LR:
return SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME;
case SDCA_TERM_TYPE_LINEOUT_CENTER_LFE:
return SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME;
case SDCA_TERM_TYPE_LINEOUT_SURROUND_LR:
return SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME;
case SDCA_TERM_TYPE_LINEOUT_REAR_LR:
return SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME;
case SDCA_TERM_TYPE_MIC_JACK:
return SDCA_TERM_TYPE_MIC_JACK_NAME;
case SDCA_TERM_TYPE_STEREO_JACK:
return SDCA_TERM_TYPE_STEREO_JACK_NAME;
case SDCA_TERM_TYPE_FRONT_LR_JACK:
return SDCA_TERM_TYPE_FRONT_LR_JACK_NAME;
case SDCA_TERM_TYPE_CENTER_LFE_JACK:
return SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME;
case SDCA_TERM_TYPE_SURROUND_LR_JACK:
return SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME;
case SDCA_TERM_TYPE_REAR_LR_JACK:
return SDCA_TERM_TYPE_REAR_LR_JACK_NAME;
case SDCA_TERM_TYPE_HEADPHONE_JACK:
return SDCA_TERM_TYPE_HEADPHONE_JACK_NAME;
case SDCA_TERM_TYPE_HEADSET_JACK:
return SDCA_TERM_TYPE_HEADSET_JACK_NAME;
default:
return NULL;
}
}
EXPORT_SYMBOL_NS(sdca_find_terminal_name, "SND_SOC_SDCA");
struct sdca_control *sdca_selector_find_control(struct device *dev, struct sdca_control *sdca_selector_find_control(struct device *dev,
struct sdca_entity *entity, struct sdca_entity *entity,
const int sel) const int sel)