Hi Carl
Yes, so asoc-audio-graph-card currently only supports headphone jack plug detection on devices that provide a simple gpio to sense plug state. The intent of this patch is to allow the componant driver to implement jack detection in cases where something else has to be done to sense state, sutch as comunicating with device firmware or using a shared irq. See the other patches in this series for an example. This is performed by sharing the jack with the component via set_jack().
OK, I see. It seems other drivers are using dai_link->init for detecting and set_jack().
I guess we can call set_jack() at asoc_simple_init_jack() and call asoc_simple_init_hp() at dai_link->init ?
It is not tested, but I added sample code below. I hope my understanding was correct and it solves your issue.
sutch as comunicating with device firmware or using a shared irq. See the other patches in this series for an example. This is performed by
I now noticed that I had mailing list issue...
Thank you for your help !!
----------- From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Subject: [PATCH] ASoC: simple_card_utils: call snd_soc_component_set_jack() at asoc_simple_init_jack()
Current simple-card / audio-graph-card are detecting HP/MIC at card->probe timing (= A), and not calling snd_soc_component_set_jack() for it. Other sound card drivers are using dai_link->init timing (= B) for both detecting and set_jack().
static int snd_soc_bind_card(...) { .... (A) ret = snd_soc_card_probe(card); ... for_each_card_rtds(card, rtd) { (B) ret = soc_init_pcm_runtime(card, rtd); ... } ... }
This patch do (a) call set_jack() (= Y) at asoc_simple_init_jack() (= X) which is used to detect HP/MIC. (b) call it from dai_link->init timing (= B) instead of card->probe timing (= A). (c) remove card->init (= A) timing function from simple-card / audio-graph-card.
(X) int asoc_simple_init_jack(...) { ... if (gpio_is_valid(det)) { ...
snd_soc_card_jack_new(...); snd_soc_jack_add_gpios(...); for_each_card_components(card, component) (Y) snd_soc_component_set_jack(component, ...); } ... }
One note here is that simple-card needs PREFIX to detecting HP/MIC, but it is not needed on audio-graph-card. Thus simple-card uses local function for it, and audio-graph-card is using global function and sharing the code with audio-graph-card / audio-graph-card2 / audio-graph-card2-custom-sample / tegra_audio_graph_card.
Reported-by: Carl Philipp Klemm philipp@uvos.xyz Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/simple_card_utils.h | 2 +- sound/soc/generic/audio-graph-card.c | 3 +- .../generic/audio-graph-card2-custom-sample.c | 3 +- sound/soc/generic/audio-graph-card2.c | 3 +- sound/soc/generic/simple-card-utils.c | 14 ++++++- sound/soc/generic/simple-card.c | 40 ++++++++++--------- sound/soc/tegra/tegra_audio_graph_card.c | 2 +- 7 files changed, 39 insertions(+), 28 deletions(-)
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index df430f1c2a10..34891da5a0fa 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -182,7 +182,7 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, struct link_info *li); int asoc_simple_remove(struct platform_device *pdev);
-int asoc_graph_card_probe(struct snd_soc_card *card); +int asoc_graph_dai_init(struct snd_soc_pcm_runtime *rtd); int asoc_graph_is_ports0(struct device_node *port);
#ifdef DEBUG diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 2b598af8feef..456db1f894af 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -259,7 +259,7 @@ static int graph_link_init(struct asoc_simple_priv *priv, if (ret < 0) return ret;
- dai_link->init = asoc_simple_dai_init; + dai_link->init = asoc_graph_dai_init; dai_link->ops = &graph_ops; if (priv->ops) dai_link->ops = priv->ops; @@ -716,7 +716,6 @@ static int graph_probe(struct platform_device *pdev) card = simple_priv_to_card(priv); card->dapm_widgets = graph_dapm_widgets; card->num_dapm_widgets = ARRAY_SIZE(graph_dapm_widgets); - card->probe = asoc_graph_card_probe;
if (of_device_get_match_data(dev)) priv->dpcm_selectable = 1; diff --git a/sound/soc/generic/audio-graph-card2-custom-sample.c b/sound/soc/generic/audio-graph-card2-custom-sample.c index 4a2c743e286c..da6cb69faa8d 100644 --- a/sound/soc/generic/audio-graph-card2-custom-sample.c +++ b/sound/soc/generic/audio-graph-card2-custom-sample.c @@ -34,8 +34,7 @@ static int custom_card_probe(struct snd_soc_card *card)
custom_priv->custom_params = 1;
- /* you can use generic probe function */ - return asoc_graph_card_probe(card); + return 0; }
static int custom_hook_pre(struct asoc_simple_priv *priv) diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index c3947347dda3..75a1aeb75d2c 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -710,7 +710,7 @@ static void graph_link_init(struct asoc_simple_priv *priv, daiclk = snd_soc_daifmt_clock_provider_fliped(daiclk);
dai_link->dai_fmt = daifmt | daiclk; - dai_link->init = asoc_simple_dai_init; + dai_link->init = asoc_graph_dai_init; dai_link->ops = &graph_ops; if (priv->ops) dai_link->ops = priv->ops; @@ -1180,7 +1180,6 @@ int audio_graph2_parse_of(struct asoc_simple_priv *priv, struct device *dev, if (!li) return -ENOMEM;
- card->probe = asoc_graph_card_probe; card->owner = THIS_MODULE; card->dev = dev;
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 850e968677f1..398fc4cb1d07 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -588,6 +588,8 @@ int asoc_simple_init_jack(struct snd_soc_card *card, return -EPROBE_DEFER;
if (gpio_is_valid(det)) { + struct snd_soc_component *component; + sjack->pin.pin = pin_name; sjack->pin.mask = mask;
@@ -603,6 +605,9 @@ int asoc_simple_init_jack(struct snd_soc_card *card,
snd_soc_jack_add_gpios(&sjack->jack, 1, &sjack->gpio); + + for_each_card_components(card, component) + snd_soc_component_set_jack(component, &sjack->jack, NULL); }
return 0; @@ -758,11 +763,16 @@ int asoc_simple_remove(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(asoc_simple_remove);
-int asoc_graph_card_probe(struct snd_soc_card *card) +int asoc_graph_dai_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_card *card = rtd->card; struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(card); int ret;
+ ret = asoc_simple_dai_init(rtd); + if (ret < 0) + return ret; + ret = asoc_simple_init_hp(card, &priv->hp_jack, NULL); if (ret < 0) return ret; @@ -773,7 +783,7 @@ int asoc_graph_card_probe(struct snd_soc_card *card)
return 0; } -EXPORT_SYMBOL_GPL(asoc_graph_card_probe); +EXPORT_SYMBOL_GPL(asoc_graph_dai_init);
int asoc_graph_is_ports0(struct device_node *np) { diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index a89d1cfdda32..e76bfae6ced4 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -149,6 +149,27 @@ static int simple_parse_node(struct asoc_simple_priv *priv, return 0; }
+static int simple_dai_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(card); + int ret; + + ret = asoc_simple_dai_init(rtd); + if (ret < 0) + return ret; + + ret = asoc_simple_init_hp(card, &priv->hp_jack, PREFIX); + if (ret < 0) + return ret; + + ret = asoc_simple_init_mic(card, &priv->mic_jack, PREFIX); + if (ret < 0) + return ret; + + return 0; +} + static int simple_link_init(struct asoc_simple_priv *priv, struct device_node *node, struct device_node *codec, @@ -164,7 +185,7 @@ static int simple_link_init(struct asoc_simple_priv *priv, if (ret < 0) return 0;
- dai_link->init = asoc_simple_dai_init; + dai_link->init = simple_dai_init; dai_link->ops = &simple_ops;
return asoc_simple_set_dailink_name(dev, dai_link, name); @@ -587,22 +608,6 @@ static int simple_get_dais_count(struct asoc_simple_priv *priv, simple_count_dpcm); }
-static int simple_soc_probe(struct snd_soc_card *card) -{ - struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(card); - int ret; - - ret = asoc_simple_init_hp(card, &priv->hp_jack, PREFIX); - if (ret < 0) - return ret; - - ret = asoc_simple_init_mic(card, &priv->mic_jack, PREFIX); - if (ret < 0) - return ret; - - return 0; -} - static int asoc_simple_probe(struct platform_device *pdev) { struct asoc_simple_priv *priv; @@ -620,7 +625,6 @@ static int asoc_simple_probe(struct platform_device *pdev) card = simple_priv_to_card(priv); card->owner = THIS_MODULE; card->dev = dev; - card->probe = simple_soc_probe; card->driver_name = "simple-card";
li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL); diff --git a/sound/soc/tegra/tegra_audio_graph_card.c b/sound/soc/tegra/tegra_audio_graph_card.c index 1f2c5018bf5a..404762d40389 100644 --- a/sound/soc/tegra/tegra_audio_graph_card.c +++ b/sound/soc/tegra/tegra_audio_graph_card.c @@ -184,7 +184,7 @@ static int tegra_audio_graph_card_probe(struct snd_soc_card *card) return PTR_ERR(priv->clk_plla_out0); }
- return asoc_graph_card_probe(card); + return 0; }
static int tegra_audio_graph_probe(struct platform_device *pdev)