brintos

brintos / linux-shallow public Read only

0
0
Text · 4.6 KiB · 7151d42 Raw
188 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// audio-graph-card2-custom-sample.c4//5// Copyright (C) 2020 Renesas Electronics Corp.6// Copyright (C) 2020 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>7//8#include <linux/device.h>9#include <linux/mod_devicetable.h>10#include <linux/module.h>11#include <linux/platform_device.h>12#include <sound/graph_card.h>13 14/*15 * Custom driver can have own priv16 * which includes simple_util_priv.17 */18struct custom_priv {19	struct simple_util_priv simple_priv;20 21	/* custom driver's own params */22	int custom_params;23};24 25/* You can get custom_priv from simple_priv */26#define simple_to_custom(simple) container_of((simple), struct custom_priv, simple_priv)27 28static int custom_card_probe(struct snd_soc_card *card)29{30	struct simple_util_priv *simple_priv = snd_soc_card_get_drvdata(card);31	struct custom_priv *custom_priv = simple_to_custom(simple_priv);32	struct device *dev = simple_priv_to_dev(simple_priv);33 34	dev_info(dev, "custom probe\n");35 36	custom_priv->custom_params = 1;37 38	/* you can use generic probe function */39	return graph_util_card_probe(card);40}41 42static int custom_hook_pre(struct simple_util_priv *priv)43{44	struct device *dev = simple_priv_to_dev(priv);45 46	/* You can custom before parsing */47	dev_info(dev, "hook : %s\n", __func__);48 49	return 0;50}51 52static int custom_hook_post(struct simple_util_priv *priv)53{54	struct device *dev = simple_priv_to_dev(priv);55	struct snd_soc_card *card;56 57	/* You can custom after parsing */58	dev_info(dev, "hook : %s\n", __func__);59 60	/* overwrite .probe sample */61	card = simple_priv_to_card(priv);62	card->probe = custom_card_probe;63 64	return 0;65}66 67static int custom_normal(struct simple_util_priv *priv,68			 struct device_node *lnk,69			 struct link_info *li)70{71	struct device *dev = simple_priv_to_dev(priv);72 73	/*74	 * You can custom Normal parsing75	 * before/affter audio_graph2_link_normal()76	 */77	dev_info(dev, "hook : %s\n", __func__);78 79	return audio_graph2_link_normal(priv, lnk, li);80}81 82static int custom_dpcm(struct simple_util_priv *priv,83		       struct device_node *lnk,84		       struct link_info *li)85{86	struct device *dev = simple_priv_to_dev(priv);87 88	/*89	 * You can custom DPCM parsing90	 * before/affter audio_graph2_link_dpcm()91	 */92	dev_info(dev, "hook : %s\n", __func__);93 94	return audio_graph2_link_dpcm(priv, lnk, li);95}96 97static int custom_c2c(struct simple_util_priv *priv,98		      struct device_node *lnk,99		      struct link_info *li)100{101	struct device *dev = simple_priv_to_dev(priv);102 103	/*104	 * You can custom Codec2Codec parsing105	 * before/affter audio_graph2_link_c2c()106	 */107	dev_info(dev, "hook : %s\n", __func__);108 109	return audio_graph2_link_c2c(priv, lnk, li);110}111 112/*113 * audio-graph-card2 has many hooks for your customizing.114 */115static struct graph2_custom_hooks custom_hooks = {116	.hook_pre	= custom_hook_pre,117	.hook_post	= custom_hook_post,118	.custom_normal	= custom_normal,119	.custom_dpcm	= custom_dpcm,120	.custom_c2c	= custom_c2c,121};122 123static int custom_startup(struct snd_pcm_substream *substream)124{125	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);126	struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card);127	struct device *dev = simple_priv_to_dev(priv);128 129	dev_info(dev, "custom startup\n");130 131	return simple_util_startup(substream);132}133 134/* You can use custom ops */135static const struct snd_soc_ops custom_ops = {136	.startup	= custom_startup,137	.shutdown	= simple_util_shutdown,138	.hw_params	= simple_util_hw_params,139};140 141static int custom_probe(struct platform_device *pdev)142{143	struct custom_priv *custom_priv;144	struct simple_util_priv *simple_priv;145	struct device *dev = &pdev->dev;146	int ret;147 148	custom_priv = devm_kzalloc(dev, sizeof(*custom_priv), GFP_KERNEL);149	if (!custom_priv)150		return -ENOMEM;151 152	simple_priv		= &custom_priv->simple_priv;153	simple_priv->ops	= &custom_ops; /* customize dai_link ops */154 155	/* "audio-graph-card2-custom-sample" is too long */156	simple_priv->snd_card.name = "card2-custom";157 158	/* use audio-graph-card2 parsing with own custom hooks */159	ret = audio_graph2_parse_of(simple_priv, dev, &custom_hooks);160	if (ret < 0)161		return ret;162 163	/* customize more if needed */164 165	return 0;166}167 168static const struct of_device_id custom_of_match[] = {169	{ .compatible = "audio-graph-card2-custom-sample", },170	{},171};172MODULE_DEVICE_TABLE(of, custom_of_match);173 174static struct platform_driver custom_card = {175	.driver = {176		.name = "audio-graph-card2-custom-sample",177		.of_match_table = custom_of_match,178	},179	.probe	= custom_probe,180	.remove = simple_util_remove,181};182module_platform_driver(custom_card);183 184MODULE_ALIAS("platform:asoc-audio-graph-card2-custom-sample");185MODULE_LICENSE("GPL v2");186MODULE_DESCRIPTION("ASoC Audio Graph Card2 Custom Sample");187MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");188