[PATCH v2 08/17] ASoC: simple-amplifier: Remove DAPM widgets and routes from the ASoC component driver

Herve Codina
2026-04-29T07:44:32Z

The simple-amplifier set the DAPM wigets and routes table in the ASoC
component driver. This is perfectly fine when the component has well
known DAPM tables.

The simple-amplifier is going to handle several kind of components based
on the driver compatible string. The DAPM table will not be the same for
all components supported by the driver.

In order to have different DAPM table based on matching compatible
strings, move those tables from the ASoC component driver to the device
compatible string matching data.

Add those DAPM widgets and routes dynamically during the ASoC component
probe operation.

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
sound/soc/codecs/simple-amplifier.c | 59 ++++++++++++++++++++++++++---
1 file changed, 53 insertions(+), 6 deletions(-)

diff --git a/sound/soc/codecs/simple-amplifier.c b/sound/soc/codecs/simple-amplifier.c
index 231e84ab4c0e..a70f70566340 100644
--- a/sound/soc/codecs/simple-amplifier.c
+++ b/sound/soc/codecs/simple-amplifier.c
@@ -11,7 +11,15 @@
#include <linux/regulator/consumer.h>
#include <sound/soc.h>

+struct simple_amp_data {
+ const struct snd_soc_dapm_widget *dapm_widgets;
+ unsigned int num_dapm_widgets;
+ const struct snd_soc_dapm_route *dapm_routes;
+ unsigned int num_dapm_routes;
+};
+
struct simple_amp {
+ const struct simple_amp_data *data;
struct gpio_desc *gpiod_enable;
};

@@ -58,11 +66,39 @@ static const struct snd_soc_dapm_route simple_amp_dapm_routes[] = {
{ "OUTR", NULL, "DRV" },
};

+static int simple_amp_add_basic_dapm(struct snd_soc_component *component)
+{
+ struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
+ struct simple_amp *simple_amp = snd_soc_component_get_drvdata(component);
+ struct device *dev = component->dev;
+ int ret;
+
+ /* Add basic dapm widgets and routes */
+ ret = snd_soc_dapm_new_controls(dapm, simple_amp->data->dapm_widgets,
+ simple_amp->data->num_dapm_widgets);
+ if (ret) {
+ dev_err(dev, "Failed to add basic dapm widgets (%d)\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(dapm, simple_amp->data->dapm_routes,
+ simple_amp->data->num_dapm_routes);
+ if (ret) {
+ dev_err(dev, "Failed to basic dapm routes (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int simple_amp_component_probe(struct snd_soc_component *component)
+{
+ /* Add basic dapm widgets and routes */
+ return simple_amp_add_basic_dapm(component);
+}
+
static const struct snd_soc_component_driver simple_amp_component_driver = {
- .dapm_widgets = simple_amp_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(simple_amp_dapm_widgets),
- .dapm_routes = simple_amp_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(simple_amp_dapm_routes),
+ .probe = simple_amp_component_probe,
};

static int simple_amp_probe(struct platform_device *pdev)
@@ -75,6 +111,10 @@ static int simple_amp_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, simple_amp);

+ simple_amp->data = of_device_get_match_data(dev);
+ if (!simple_amp->data)
+ return -EINVAL;
+
simple_amp->gpiod_enable = devm_gpiod_get_optional(dev, "enable",
GPIOD_OUT_LOW);
if (IS_ERR(simple_amp->gpiod_enable))
@@ -86,9 +126,16 @@ static int simple_amp_probe(struct platform_device *pdev)
NULL, 0);
}

+static const struct simple_amp_data simple_audio_amplifier_data = {
+ .dapm_widgets = simple_amp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(simple_amp_dapm_widgets),
+ .dapm_routes = simple_amp_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(simple_amp_dapm_routes),
+};
+
static const struct of_device_id simple_amp_ids[] = {
- { .compatible = "dioo,dio2125", },
- { .compatible = "simple-audio-amplifier", },
+ { .compatible = "dioo,dio2125", .data = &simple_audio_amplifier_data},
+ { .compatible = "simple-audio-amplifier", .data = &simple_audio_amplifier_data},
{ }
};
MODULE_DEVICE_TABLE(of, simple_amp_ids);
--
2.53.0