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