Skip to content

Commit bce93a1

Browse files
AngeloGioacchino Del Regnobroonie
authored andcommitted
ASoC: mediatek: Add common machine soundcard driver probe mechanism
Add a common machine soundcard driver probe function that supports both DSP and AFE-direct usecases and also provides a hook for legacy machine soundcard driver probe mechanisms. Note that the hook is there because, even for legacy probe, a lot of the actual code can still be commonized, hence still reducing duplication for the legacy devicetree retrocompatibility cases. This common probe function deprecates all of the inconsistent previous probe mechanisms and aims to settle all of the MediaTek card drivers on consistent and common devicetree properties describing wanted DAIs, device specific DAI configuration and DAI links to codecs found on each device/board. Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://lore.kernel.org/r/20240416071410.75620-2-angelogioacchino.delregno@collabora.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 62c48dd commit bce93a1

3 files changed

Lines changed: 172 additions & 1 deletion

File tree

sound/soc/mediatek/common/mtk-soc-card.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@
99
#ifndef _MTK_SOC_CARD_H_
1010
#define _MTK_SOC_CARD_H_
1111

12+
struct mtk_platform_card_data;
13+
struct mtk_sof_priv;
14+
1215
struct mtk_soc_card_data {
16+
struct mtk_sof_priv *sof_priv;
17+
struct list_head sof_dai_link_list;
18+
struct mtk_platform_card_data *card_data;
1319
void *mach_priv;
14-
void *sof_priv;
1520
};
1621

1722
#endif

sound/soc/mediatek/common/mtk-soundcard-driver.c

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <linux/of.h>
1111
#include <sound/soc.h>
1212

13+
#include "mtk-dsp-sof-common.h"
14+
#include "mtk-soc-card.h"
1315
#include "mtk-soundcard-driver.h"
1416

1517
static int set_card_codec_info(struct snd_soc_card *card,
@@ -136,3 +138,149 @@ void clean_card_reference(struct snd_soc_card *card)
136138
snd_soc_of_put_dai_link_codecs(dai_link);
137139
}
138140
EXPORT_SYMBOL_GPL(clean_card_reference);
141+
142+
int mtk_soundcard_common_probe(struct platform_device *pdev)
143+
{
144+
struct device_node *platform_node, *adsp_node;
145+
const struct mtk_soundcard_pdata *pdata;
146+
struct mtk_soc_card_data *soc_card_data;
147+
struct snd_soc_dai_link *orig_dai_link, *dai_link;
148+
struct snd_soc_jack *jacks;
149+
struct snd_soc_card *card;
150+
int i, orig_num_links, ret;
151+
bool needs_legacy_probe;
152+
153+
pdata = device_get_match_data(&pdev->dev);
154+
if (!pdata)
155+
return -EINVAL;
156+
157+
card = pdata->card_data->card;
158+
card->dev = &pdev->dev;
159+
orig_dai_link = card->dai_link;
160+
orig_num_links = card->num_links;
161+
162+
ret = snd_soc_of_parse_card_name(card, "model");
163+
if (ret)
164+
return ret;
165+
166+
if (!card->name) {
167+
if (!pdata->card_name)
168+
return -EINVAL;
169+
170+
card->name = pdata->card_name;
171+
}
172+
173+
needs_legacy_probe = !of_property_read_bool(pdev->dev.of_node, "audio-routing");
174+
if (needs_legacy_probe) {
175+
/*
176+
* If we have no .soc_probe() callback there's no way of using
177+
* any legacy probe mechanism, as that cannot not be generic.
178+
*/
179+
if (!pdata->soc_probe)
180+
return -EINVAL;
181+
182+
dev_info_once(&pdev->dev, "audio-routing not found: using legacy probe\n");
183+
} else {
184+
ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
185+
if (ret)
186+
return ret;
187+
}
188+
189+
soc_card_data = devm_kzalloc(&pdev->dev, sizeof(*soc_card_data), GFP_KERNEL);
190+
if (!soc_card_data)
191+
return -ENOMEM;
192+
193+
soc_card_data->card_data = pdata->card_data;
194+
195+
jacks = devm_kcalloc(card->dev, soc_card_data->card_data->num_jacks,
196+
sizeof(*jacks), GFP_KERNEL);
197+
if (!jacks)
198+
return -ENOMEM;
199+
200+
soc_card_data->card_data->jacks = jacks;
201+
202+
platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0);
203+
if (!platform_node)
204+
return dev_err_probe(&pdev->dev, -EINVAL,
205+
"Property mediatek,platform missing or invalid\n");
206+
207+
/* Check if this SoC has an Audio DSP */
208+
if (pdata->sof_priv)
209+
adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0);
210+
else
211+
adsp_node = NULL;
212+
213+
if (adsp_node) {
214+
if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) {
215+
ret = mtk_sof_dailink_parse_of(card, pdev->dev.of_node,
216+
"mediatek,dai-link",
217+
card->dai_link, card->num_links);
218+
if (ret) {
219+
of_node_put(adsp_node);
220+
of_node_put(platform_node);
221+
return dev_err_probe(&pdev->dev, ret,
222+
"Cannot parse mediatek,dai-link\n");
223+
}
224+
}
225+
226+
soc_card_data->sof_priv = pdata->sof_priv;
227+
card->probe = mtk_sof_card_probe;
228+
card->late_probe = mtk_sof_card_late_probe;
229+
if (!card->topology_shortname_created) {
230+
snprintf(card->topology_shortname, 32, "sof-%s", card->name);
231+
card->topology_shortname_created = true;
232+
}
233+
card->name = card->topology_shortname;
234+
}
235+
236+
/*
237+
* Regardless of whether the ADSP is wanted and/or present in a machine
238+
* specific device tree or not and regardless of whether any AFE_SOF
239+
* link is present, we have to make sure that the platforms->of_node
240+
* is not NULL, and set to either ADSP (adsp_node) or AFE (platform_node).
241+
*/
242+
for_each_card_prelinks(card, i, dai_link) {
243+
if (adsp_node && !strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")))
244+
dai_link->platforms->of_node = adsp_node;
245+
else if (!dai_link->platforms->name && !dai_link->platforms->of_node)
246+
dai_link->platforms->of_node = platform_node;
247+
}
248+
249+
if (!needs_legacy_probe) {
250+
ret = parse_dai_link_info(card);
251+
if (ret)
252+
goto err_restore_dais;
253+
} else {
254+
if (adsp_node)
255+
of_node_put(adsp_node);
256+
of_node_put(platform_node);
257+
}
258+
259+
if (pdata->soc_probe) {
260+
ret = pdata->soc_probe(soc_card_data, needs_legacy_probe);
261+
if (ret) {
262+
if (!needs_legacy_probe)
263+
clean_card_reference(card);
264+
goto err_restore_dais;
265+
}
266+
}
267+
snd_soc_card_set_drvdata(card, soc_card_data);
268+
269+
ret = devm_snd_soc_register_card(&pdev->dev, card);
270+
271+
if (!needs_legacy_probe)
272+
clean_card_reference(card);
273+
274+
if (ret) {
275+
dev_err_probe(&pdev->dev, ret, "Cannot register card\n");
276+
goto err_restore_dais;
277+
}
278+
279+
return 0;
280+
281+
err_restore_dais:
282+
card->dai_link = orig_dai_link;
283+
card->num_links = orig_num_links;
284+
return ret;
285+
}
286+
EXPORT_SYMBOL_GPL(mtk_soundcard_common_probe);

sound/soc/mediatek/common/mtk-soundcard-driver.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@
99
#ifndef _MTK_SOUNDCARD_DRIVER_H_
1010
#define _MTK_SOUNDCARD_DRIVER_H_
1111

12+
struct mtk_sof_priv;
13+
struct mtk_soc_card_data;
14+
15+
struct mtk_platform_card_data {
16+
struct snd_soc_card *card;
17+
struct snd_soc_jack *jacks;
18+
u8 num_jacks;
19+
u8 flags;
20+
};
21+
22+
struct mtk_soundcard_pdata {
23+
const char *card_name;
24+
struct mtk_platform_card_data *card_data;
25+
struct mtk_sof_priv *sof_priv;
26+
int (*soc_probe)(struct mtk_soc_card_data *card_data, bool legacy);
27+
};
28+
1229
int parse_dai_link_info(struct snd_soc_card *card);
1330
void clean_card_reference(struct snd_soc_card *card);
31+
int mtk_soundcard_common_probe(struct platform_device *pdev);
1432
#endif

0 commit comments

Comments
 (0)