mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
ASoC: add Audio Graph Card2 Custom Sample
audio-graph-card2 has customizing support. This means user can re-use audio-graph-card2 DT parsing, and possible to expand to own special handling. This patch adds Audio Graph Card2 Customize Sample Driver. It can re-use audio-graph-card2 parsing by calling audio_graph2_parse_of(...), and user can expand each functions by using hooks. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://lore.kernel.org/r/87v922lu3c.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
466ac332bc
commit
95373f36b9
@ -26,6 +26,12 @@ config SND_AUDIO_GRAPH_CARD2
|
||||
This option enables generic simple sound card2 support
|
||||
with OF-graph DT bindings.
|
||||
|
||||
config SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE
|
||||
tristate "ASoC Audio Graph Card2 base custom sample support"
|
||||
depends on SND_AUDIO_GRAPH_CARD2
|
||||
help
|
||||
This option enables Audio Graph Card2 base custom sample
|
||||
|
||||
config SND_TEST_COMPONENT
|
||||
tristate "ASoC Test component sound support"
|
||||
depends on OF
|
||||
|
@ -3,10 +3,12 @@ snd-soc-simple-card-utils-objs := simple-card-utils.o
|
||||
snd-soc-simple-card-objs := simple-card.o
|
||||
snd-soc-audio-graph-card-objs := audio-graph-card.o
|
||||
snd-soc-audio-graph-card2-objs := audio-graph-card2.o
|
||||
snd-soc-audio-graph-card2-custom-sample-objs := audio-graph-card2-custom-sample.o
|
||||
snd-soc-test-component-objs := test-component.o
|
||||
|
||||
obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o
|
||||
obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o
|
||||
obj-$(CONFIG_SND_AUDIO_GRAPH_CARD) += snd-soc-audio-graph-card.o
|
||||
obj-$(CONFIG_SND_AUDIO_GRAPH_CARD2) += snd-soc-audio-graph-card2.o
|
||||
obj-$(CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE) += snd-soc-audio-graph-card2-custom-sample.o
|
||||
obj-$(CONFIG_SND_TEST_COMPONENT) += snd-soc-test-component.o
|
||||
|
183
sound/soc/generic/audio-graph-card2-custom-sample.c
Normal file
183
sound/soc/generic/audio-graph-card2-custom-sample.c
Normal file
@ -0,0 +1,183 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// audio-graph-card2-custom-sample.c
|
||||
//
|
||||
// Copyright (C) 2020 Renesas Electronics Corp.
|
||||
// Copyright (C) 2020 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
//
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <sound/graph_card.h>
|
||||
|
||||
/*
|
||||
* Custom driver can have own priv
|
||||
* which includes asoc_simple_priv.
|
||||
*/
|
||||
struct custom_priv {
|
||||
struct asoc_simple_priv simple_priv;
|
||||
|
||||
/* custom driver's own params */
|
||||
int custom_params;
|
||||
};
|
||||
|
||||
/* You can get custom_priv from simple_priv */
|
||||
#define simple_to_custom(simple) container_of((simple), struct custom_priv, simple_priv)
|
||||
|
||||
static int custom_card_probe(struct snd_soc_card *card)
|
||||
{
|
||||
struct asoc_simple_priv *simple_priv = snd_soc_card_get_drvdata(card);
|
||||
struct custom_priv *custom_priv = simple_to_custom(simple_priv);
|
||||
struct device *dev = simple_priv_to_dev(simple_priv);
|
||||
|
||||
dev_info(dev, "custom probe\n");
|
||||
|
||||
custom_priv->custom_params = 1;
|
||||
|
||||
/* you can use generic probe function */
|
||||
return asoc_graph_card_probe(card);
|
||||
}
|
||||
|
||||
static int custom_hook_pre(struct asoc_simple_priv *priv)
|
||||
{
|
||||
struct device *dev = simple_priv_to_dev(priv);
|
||||
|
||||
/* You can custom before parsing */
|
||||
dev_info(dev, "hook : %s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int custom_hook_post(struct asoc_simple_priv *priv)
|
||||
{
|
||||
struct device *dev = simple_priv_to_dev(priv);
|
||||
struct snd_soc_card *card;
|
||||
|
||||
/* You can custom after parsing */
|
||||
dev_info(dev, "hook : %s\n", __func__);
|
||||
|
||||
/* overwrite .probe sample */
|
||||
card = simple_priv_to_card(priv);
|
||||
card->probe = custom_card_probe;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int custom_normal(struct asoc_simple_priv *priv,
|
||||
struct device_node *lnk,
|
||||
struct link_info *li)
|
||||
{
|
||||
struct device *dev = simple_priv_to_dev(priv);
|
||||
|
||||
/*
|
||||
* You can custom Normal parsing
|
||||
* before/affter audio_graph2_link_normal()
|
||||
*/
|
||||
dev_info(dev, "hook : %s\n", __func__);
|
||||
|
||||
return audio_graph2_link_normal(priv, lnk, li);
|
||||
}
|
||||
|
||||
static int custom_dpcm(struct asoc_simple_priv *priv,
|
||||
struct device_node *lnk,
|
||||
struct link_info *li)
|
||||
{
|
||||
struct device *dev = simple_priv_to_dev(priv);
|
||||
|
||||
/*
|
||||
* You can custom DPCM parsing
|
||||
* before/affter audio_graph2_link_dpcm()
|
||||
*/
|
||||
dev_info(dev, "hook : %s\n", __func__);
|
||||
|
||||
return audio_graph2_link_dpcm(priv, lnk, li);
|
||||
}
|
||||
|
||||
static int custom_c2c(struct asoc_simple_priv *priv,
|
||||
struct device_node *lnk,
|
||||
struct link_info *li)
|
||||
{
|
||||
struct device *dev = simple_priv_to_dev(priv);
|
||||
|
||||
/*
|
||||
* You can custom Codec2Codec parsing
|
||||
* before/affter audio_graph2_link_c2c()
|
||||
*/
|
||||
dev_info(dev, "hook : %s\n", __func__);
|
||||
|
||||
return audio_graph2_link_c2c(priv, lnk, li);
|
||||
}
|
||||
|
||||
/*
|
||||
* audio-graph-card2 has many hooks for your customizing.
|
||||
*/
|
||||
static struct graph2_custom_hooks custom_hooks = {
|
||||
.hook_pre = custom_hook_pre,
|
||||
.hook_post = custom_hook_post,
|
||||
.custom_normal = custom_normal,
|
||||
.custom_dpcm = custom_dpcm,
|
||||
.custom_c2c = custom_c2c,
|
||||
};
|
||||
|
||||
static int custom_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct device *dev = simple_priv_to_dev(priv);
|
||||
|
||||
dev_info(dev, "custom startup\n");
|
||||
|
||||
return asoc_simple_startup(substream);
|
||||
}
|
||||
|
||||
/* You can use custom ops */
|
||||
static const struct snd_soc_ops custom_ops = {
|
||||
.startup = custom_startup,
|
||||
.shutdown = asoc_simple_shutdown,
|
||||
.hw_params = asoc_simple_hw_params,
|
||||
};
|
||||
|
||||
static int custom_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct custom_priv *custom_priv;
|
||||
struct asoc_simple_priv *simple_priv;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
|
||||
custom_priv = devm_kzalloc(dev, sizeof(*custom_priv), GFP_KERNEL);
|
||||
if (!custom_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
simple_priv = &custom_priv->simple_priv;
|
||||
simple_priv->ops = &custom_ops; /* customize dai_link ops */
|
||||
|
||||
/* use audio-graph-card2 parsing with own custom hooks */
|
||||
ret = audio_graph2_parse_of(simple_priv, dev, &custom_hooks);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* customize more if needed */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id custom_of_match[] = {
|
||||
{ .compatible = "audio-graph-card2-custom-sample", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, custom_of_match);
|
||||
|
||||
static struct platform_driver custom_card = {
|
||||
.driver = {
|
||||
.name = "audio-graph-card2-custom-sample",
|
||||
.of_match_table = custom_of_match,
|
||||
},
|
||||
.probe = custom_probe,
|
||||
.remove = asoc_simple_remove,
|
||||
};
|
||||
module_platform_driver(custom_card);
|
||||
|
||||
MODULE_ALIAS("platform:asoc-audio-graph-card2-custom-sample");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("ASoC Audio Graph Card2 Custom Sample");
|
||||
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
|
Loading…
Reference in New Issue
Block a user