From 52b97d43b7c52da481758931a111a091da5e4802 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 16 May 2025 14:10:05 +0100 Subject: ASoC: SDCA: Fix minor typo Fix minor typo SDAC -> SDCA. Fixes: 42b144cb6a2d ("ASoC: SDCA: Add SDCA Control parsing") Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250516131011.221310-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 253654568a41..e7165e4f15c4 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -125,7 +125,7 @@ struct sdca_init_write { * macros. * * Short hand to specific a Control type statically for example: - * SDAC_CTL_TYPE_S(IT, MIC_BIAS). + * SDCA_CTL_TYPE_S(IT, MIC_BIAS). */ #define SDCA_CTL_TYPE_S(ent, sel) SDCA_CTL_TYPE(SDCA_ENTITY_TYPE_##ent, \ SDCA_CTL_##ent##_##sel) -- cgit v1.2.3 From 737379e5062e26c59fe069a8bdad2ee363d52686 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 16 May 2025 14:10:08 +0100 Subject: ASoC: dapm: Add component level pin switches The core currently supports pin switches for source/sink widgets, but only at the card level. SDCA components specify the fabric at the level of the individual components, to support this add helpers to allow component level pin switches. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250516131011.221310-5-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index af802ef536e7..400584474bc8 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -445,6 +445,10 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *uncontrol); int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *uncontrol); +int snd_soc_dapm_get_component_pin_switch(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uncontrol); +int snd_soc_dapm_put_component_pin_switch(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uncontrol); int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget, unsigned int num); struct snd_soc_dapm_widget *snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, -- cgit v1.2.3 From 2c8b3a8e6aa877583e5dc2f669a8adc896a771d4 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 16 May 2025 14:10:09 +0100 Subject: ASoC: SDCA: Create DAPM widgets and routes from DisCo Use the previously parsed DisCo information from ACPI to create DAPM widgets and routes representing a SDCA Function. For the most part SDCA maps well to the DAPM abstractions. The primary point of interest is the SDCA Power Domain Entities (PDEs), which actually control the power status of the device. Whilst these PDEs are the primary widgets the other parts of the SDCA graph are added to maintain a consistency with the hardware abstract, and allow routing to take effect. As for the PDEs themselves the code currently only handle PS0 and PS3 (basically on and off), the two intermediate power states are not commonly used and don't map well to ASoC/DAPM. Other minor points of slightly complexity include, the Group Entities (GEs) these set the value of several other controls, typically Selector Units (SUs) for enabling a cetain jack configuration. Multiple SUs being controlled by a GE are easily modelled creating a single control and sharing it among the controlled muxes. SDCA also has a slight habit of having fully connected paths, relying more on activating the PDEs to enable functionality. This doesn't map quite so perfectly to DAPM which considers the path a reason to power the PDE. Whilst in the current specification Mixer Units are defined as fixed-function, in DAPM we create a virtual control for each input (which defaults to connected). This allows paths to be connected/disconnected, providing a more ASoC style approach to managing the power. PIN_SWITCHs will also be added for non-dataport terminal entities in a later patch along with the other ALSA controls, providing greater flexibility in power management. A top level helper sdca_asoc_populate_component() is exported that counts and allocates everything, however, the intermediate counting and population functions are also exported. This will allow end drivers to do allocation and add custom handling, which is probably fairly likely for the early SDCA devices. Clock muxes are currently not fully supported, so some future work will also be required there. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250516131011.221310-6-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_asoc.h | 30 ++++++++++++++++++++++++++++++ include/sound/sdca_function.h | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 include/sound/sdca_asoc.h (limited to 'include') diff --git a/include/sound/sdca_asoc.h b/include/sound/sdca_asoc.h new file mode 100644 index 000000000000..414d461b6fc4 --- /dev/null +++ b/include/sound/sdca_asoc.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * The MIPI SDCA specification is available for public downloads at + * https://www.mipi.org/mipi-sdca-v1-0-download + * + * Copyright (C) 2025 Cirrus Logic, Inc. and + * Cirrus Logic International Semiconductor Ltd. + */ + +#ifndef __SDCA_ASOC_H__ +#define __SDCA_ASOC_H__ + +struct device; +struct sdca_function_data; +struct snd_soc_component_driver; +struct snd_soc_dapm_route; +struct snd_soc_dapm_widget; + +int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function, + int *num_widgets, int *num_routes); + +int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *function, + struct snd_soc_dapm_widget *widgets, + struct snd_soc_dapm_route *routes); + +int sdca_asoc_populate_component(struct device *dev, + struct sdca_function_data *function, + struct snd_soc_component_driver *component_drv); + +#endif // __SDCA_ASOC_H__ diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index e7165e4f15c4..008e23882de8 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -257,6 +257,14 @@ enum sdca_pde_controls { SDCA_CTL_PDE_ACTUAL_PS = 0x10, }; +/** + * enum sdca_requested_ps_range - Column definitions for Requested PS + */ +enum sdca_requested_ps_range { + SDCA_REQUESTED_PS_STATE = 0, + SDCA_REQUESTED_PS_NCOLS = 1, +}; + /** * enum sdca_ge_controls - SDCA Controls for Group Unit * @@ -268,6 +276,15 @@ enum sdca_ge_controls { SDCA_CTL_GE_DETECTED_MODE = 0x02, }; +/** + * enum sdca_selected_mode_range - Column definitions for Selected Mode + */ +enum sdca_selected_mode_range { + SDCA_SELECTED_MODE_INDEX = 0, + SDCA_SELECTED_MODE_TERM_TYPE = 1, + SDCA_SELECTED_MODE_NCOLS = 2, +}; + /** * enum sdca_spe_controls - SDCA Controls for Security & Privacy Unit * @@ -773,6 +790,25 @@ enum sdca_terminal_type { SDCA_TERM_TYPE_PRIVACY_INDICATORS = 0x747, }; +#define SDCA_TERM_TYPE_LINEIN_STEREO_NAME "LineIn Stereo" +#define SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME "LineIn Front-LR" +#define SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME "LineIn Center-LFE" +#define SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME "LineIn Surround-LR" +#define SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME "LineIn Rear-LR" +#define SDCA_TERM_TYPE_LINEOUT_STEREO_NAME "LineOut Stereo" +#define SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME "LineOut Front-LR" +#define SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME "LineOut Center-LFE" +#define SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME "LineOut Surround-LR" +#define SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME "LineOut Rear-LR" +#define SDCA_TERM_TYPE_MIC_JACK_NAME "Microphone" +#define SDCA_TERM_TYPE_STEREO_JACK_NAME "Speaker Stereo" +#define SDCA_TERM_TYPE_FRONT_LR_JACK_NAME "Speaker Front-LR" +#define SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME "Speaker Center-LFE" +#define SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME "Speaker Surround-LR" +#define SDCA_TERM_TYPE_REAR_LR_JACK_NAME "Speaker Rear-LR" +#define SDCA_TERM_TYPE_HEADPHONE_JACK_NAME "Headphone" +#define SDCA_TERM_TYPE_HEADSET_JACK_NAME "Headset" + /** * enum sdca_connector_type - SDCA Connector Types * -- cgit v1.2.3 From c3ca24e3fcb656c6afe702b69e6e9efcc3ff1128 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 16 May 2025 14:10:10 +0100 Subject: ASoC: SDCA: Create ALSA controls from DisCo Use the previously parsed DisCo information from ACPI to create the ALSA controls required by an SDCA Function. This maps all User and Application level SDCA Controls to ALSA controls. Typically controls marked with those access levels are just volumes and mutes. SDCA defines volume controls as an integer in 1/256ths of a dB and then provides a mechanism to specify what values are valid (range templates). Currently only a simple case of a single linear volume range with a power of 2 step size is supported. This allows the code to expose the volume control using a simple shift. This will need expanded in the future, to support more complex ranges and probably also some additional control types but this should be sufficient to for a first pass. For non-dataport terminal widgets also add a pin switch to allow that endpoint to be turned on/off. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250516131011.221310-7-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_asoc.h | 6 +++++- include/sound/sdca_function.h | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/sound/sdca_asoc.h b/include/sound/sdca_asoc.h index 414d461b6fc4..d19e7e969283 100644 --- a/include/sound/sdca_asoc.h +++ b/include/sound/sdca_asoc.h @@ -12,16 +12,20 @@ struct device; struct sdca_function_data; +struct snd_kcontrol_new; struct snd_soc_component_driver; struct snd_soc_dapm_route; struct snd_soc_dapm_widget; int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function, - int *num_widgets, int *num_routes); + int *num_widgets, int *num_routes, int *num_controls); int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *function, struct snd_soc_dapm_widget *widgets, struct snd_soc_dapm_route *routes); +int sdca_asoc_populate_controls(struct device *dev, + struct sdca_function_data *function, + struct snd_kcontrol_new *kctl); int sdca_asoc_populate_component(struct device *dev, struct sdca_function_data *function, diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 008e23882de8..2ecf0c3a5e03 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -206,6 +206,16 @@ enum sdca_fu_controls { SDCA_CTL_FU_LATENCY = 0x10, }; +/** + * enum sdca_volume_range - Column definitions for Q7.8dB volumes/gains + */ +enum sdca_volume_range { + SDCA_VOLUME_LINEAR_MIN = 0, + SDCA_VOLUME_LINEAR_MAX = 1, + SDCA_VOLUME_LINEAR_STEP = 2, + SDCA_VOLUME_LINEAR_NCOLS = 3, +}; + /** * enum sdca_xu_controls - SDCA Controls for Extension Unit * -- cgit v1.2.3 From 108f878d435437f649da32dea9f0d4f684eba3ba Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 16 May 2025 14:10:11 +0100 Subject: ASoC: SDCA: Create DAI drivers from DisCo Use the previously parsed DisCo information from ACPI to create the DAI drivers required to connect an SDCA Function into an ASoC soundcard. Create DAI driver structures and populate the supported sample rates and sample widths into them based on the Input/Output Terminal and any attach Clock Source entities. More complex relationships with channels etc. will be added later as constraints as part of the DAI startup. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250516131011.221310-8-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_asoc.h | 12 ++++++++++-- include/sound/sdca_function.h | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/sound/sdca_asoc.h b/include/sound/sdca_asoc.h index d19e7e969283..9121531f0826 100644 --- a/include/sound/sdca_asoc.h +++ b/include/sound/sdca_asoc.h @@ -14,11 +14,14 @@ struct device; struct sdca_function_data; struct snd_kcontrol_new; struct snd_soc_component_driver; +struct snd_soc_dai_driver; +struct snd_soc_dai_ops; struct snd_soc_dapm_route; struct snd_soc_dapm_widget; int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function, - int *num_widgets, int *num_routes, int *num_controls); + int *num_widgets, int *num_routes, int *num_controls, + int *num_dais); int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *function, struct snd_soc_dapm_widget *widgets, @@ -26,9 +29,14 @@ int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *funct int sdca_asoc_populate_controls(struct device *dev, struct sdca_function_data *function, struct snd_kcontrol_new *kctl); +int sdca_asoc_populate_dais(struct device *dev, struct sdca_function_data *function, + struct snd_soc_dai_driver *dais, + const struct snd_soc_dai_ops *ops); int sdca_asoc_populate_component(struct device *dev, struct sdca_function_data *function, - struct snd_soc_component_driver *component_drv); + struct snd_soc_component_driver *component_drv, + struct snd_soc_dai_driver **dai_drv, int *num_dai_drv, + const struct snd_soc_dai_ops *ops); #endif // __SDCA_ASOC_H__ diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 2ecf0c3a5e03..eaedb54a8322 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -168,6 +168,20 @@ enum sdca_ot_controls { SDCA_CTL_OT_NDAI_PACKETTYPE = 0x17, }; +/** + * enum sdca_usage_range - Column definitions for Usage + */ +enum sdca_usage_range { + SDCA_USAGE_NUMBER = 0, + SDCA_USAGE_CBN = 1, + SDCA_USAGE_SAMPLE_RATE = 2, + SDCA_USAGE_SAMPLE_WIDTH = 3, + SDCA_USAGE_FULL_SCALE = 4, + SDCA_USAGE_NOISE_FLOOR = 5, + SDCA_USAGE_TAG = 6, + SDCA_USAGE_NCOLS = 7, +}; + /** * enum sdca_mu_controls - SDCA Controls for Mixer Unit * @@ -246,6 +260,15 @@ enum sdca_cs_controls { SDCA_CTL_CS_SAMPLERATEINDEX = 0x10, }; +/** + * enum sdca_samplerateindex_range - Column definitions for SampleRateIndex + */ +enum sdca_samplerateindex_range { + SDCA_SAMPLERATEINDEX_INDEX = 0, + SDCA_SAMPLERATEINDEX_RATE = 1, + SDCA_SAMPLERATEINDEX_NCOLS = 2, +}; + /** * enum sdca_cx_controls - SDCA Controls for Clock Selector * -- cgit v1.2.3