FILE
audio-graph-card2-custom-sample.c
File preview with syntax highlighting.
linux-6.19.14/sound/soc/generic/audio-graph-card2-custom-sample.c
1// SPDX-License-Identifier: GPL-2.0 2// 3// audio-graph-card2-custom-sample.c 4// 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 priv 16 * 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 parsing 75 * 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 parsing 90 * 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 parsing 105 * 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>");
~/
Read-only file preview.