1 | /* SPDX-License-Identifier: GPL-2.0 |
2 | * |
3 | * linux/sound/soc-topology.h -- ALSA SoC Firmware Controls and DAPM |
4 | * |
5 | * Copyright (C) 2012 Texas Instruments Inc. |
6 | * Copyright (C) 2015 Intel Corporation. |
7 | * |
8 | * Simple file API to load FW that includes mixers, coefficients, DAPM graphs, |
9 | * algorithms, equalisers, DAIs, widgets, FE caps, BE caps, codec link caps etc. |
10 | */ |
11 | |
12 | #ifndef __LINUX_SND_SOC_TPLG_H |
13 | #define __LINUX_SND_SOC_TPLG_H |
14 | |
15 | #include <sound/asoc.h> |
16 | #include <linux/list.h> |
17 | |
18 | struct firmware; |
19 | struct snd_kcontrol; |
20 | struct snd_soc_tplg_pcm_be; |
21 | struct snd_ctl_elem_value; |
22 | struct snd_ctl_elem_info; |
23 | struct snd_soc_dapm_widget; |
24 | struct snd_soc_component; |
25 | struct snd_soc_tplg_pcm_fe; |
26 | struct snd_soc_dapm_context; |
27 | struct snd_soc_card; |
28 | struct snd_kcontrol_new; |
29 | struct snd_soc_dai_link; |
30 | struct snd_soc_dai_driver; |
31 | struct snd_soc_dai; |
32 | struct snd_soc_dapm_route; |
33 | |
34 | /* dynamic object type */ |
35 | enum snd_soc_dobj_type { |
36 | SND_SOC_DOBJ_NONE = 0, /* object is not dynamic */ |
37 | SND_SOC_DOBJ_MIXER, |
38 | SND_SOC_DOBJ_BYTES, |
39 | SND_SOC_DOBJ_ENUM, |
40 | SND_SOC_DOBJ_GRAPH, |
41 | SND_SOC_DOBJ_WIDGET, |
42 | SND_SOC_DOBJ_DAI_LINK, |
43 | SND_SOC_DOBJ_PCM, |
44 | SND_SOC_DOBJ_CODEC_LINK, |
45 | SND_SOC_DOBJ_BACKEND_LINK, |
46 | }; |
47 | |
48 | /* dynamic control object */ |
49 | struct snd_soc_dobj_control { |
50 | struct snd_kcontrol *kcontrol; |
51 | char **dtexts; |
52 | unsigned long *dvalues; |
53 | }; |
54 | |
55 | /* dynamic widget object */ |
56 | struct snd_soc_dobj_widget { |
57 | unsigned int *kcontrol_type; /* kcontrol type: mixer, enum, bytes */ |
58 | }; |
59 | |
60 | /* generic dynamic object - all dynamic objects belong to this struct */ |
61 | struct snd_soc_dobj { |
62 | enum snd_soc_dobj_type type; |
63 | unsigned int index; /* objects can belong in different groups */ |
64 | struct list_head list; |
65 | int (*unload)(struct snd_soc_component *comp, struct snd_soc_dobj *dobj); |
66 | union { |
67 | struct snd_soc_dobj_control control; |
68 | struct snd_soc_dobj_widget widget; |
69 | }; |
70 | void *private; /* core does not touch this */ |
71 | }; |
72 | |
73 | /* |
74 | * Kcontrol operations - used to map handlers onto firmware based controls. |
75 | */ |
76 | struct snd_soc_tplg_kcontrol_ops { |
77 | u32 id; |
78 | int (*get)(struct snd_kcontrol *kcontrol, |
79 | struct snd_ctl_elem_value *ucontrol); |
80 | int (*put)(struct snd_kcontrol *kcontrol, |
81 | struct snd_ctl_elem_value *ucontrol); |
82 | int (*info)(struct snd_kcontrol *kcontrol, |
83 | struct snd_ctl_elem_info *uinfo); |
84 | }; |
85 | |
86 | /* Bytes ext operations, for TLV byte controls */ |
87 | struct snd_soc_tplg_bytes_ext_ops { |
88 | u32 id; |
89 | int (*get)(struct snd_kcontrol *kcontrol, unsigned int __user *bytes, |
90 | unsigned int size); |
91 | int (*put)(struct snd_kcontrol *kcontrol, |
92 | const unsigned int __user *bytes, unsigned int size); |
93 | }; |
94 | |
95 | /* |
96 | * DAPM widget event handlers - used to map handlers onto widgets. |
97 | */ |
98 | struct snd_soc_tplg_widget_events { |
99 | u16 type; |
100 | int (*event_handler)(struct snd_soc_dapm_widget *w, |
101 | struct snd_kcontrol *k, int event); |
102 | }; |
103 | |
104 | /* |
105 | * Public API - Used by component drivers to load and unload dynamic objects |
106 | * and their resources. |
107 | */ |
108 | struct snd_soc_tplg_ops { |
109 | |
110 | /* external kcontrol init - used for any driver specific init */ |
111 | int (*control_load)(struct snd_soc_component *, int index, |
112 | struct snd_kcontrol_new *, struct snd_soc_tplg_ctl_hdr *); |
113 | int (*control_unload)(struct snd_soc_component *, |
114 | struct snd_soc_dobj *); |
115 | |
116 | /* DAPM graph route element loading and unloading */ |
117 | int (*dapm_route_load)(struct snd_soc_component *, int index, |
118 | struct snd_soc_dapm_route *route); |
119 | int (*dapm_route_unload)(struct snd_soc_component *, |
120 | struct snd_soc_dobj *); |
121 | |
122 | /* external widget init - used for any driver specific init */ |
123 | int (*widget_load)(struct snd_soc_component *, int index, |
124 | struct snd_soc_dapm_widget *, |
125 | struct snd_soc_tplg_dapm_widget *); |
126 | int (*widget_ready)(struct snd_soc_component *, int index, |
127 | struct snd_soc_dapm_widget *, |
128 | struct snd_soc_tplg_dapm_widget *); |
129 | int (*widget_unload)(struct snd_soc_component *, |
130 | struct snd_soc_dobj *); |
131 | |
132 | /* FE DAI - used for any driver specific init */ |
133 | int (*dai_load)(struct snd_soc_component *, int index, |
134 | struct snd_soc_dai_driver *dai_drv, |
135 | struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai); |
136 | |
137 | int (*dai_unload)(struct snd_soc_component *, |
138 | struct snd_soc_dobj *); |
139 | |
140 | /* DAI link - used for any driver specific init */ |
141 | int (*link_load)(struct snd_soc_component *, int index, |
142 | struct snd_soc_dai_link *link, |
143 | struct snd_soc_tplg_link_config *cfg); |
144 | int (*link_unload)(struct snd_soc_component *, |
145 | struct snd_soc_dobj *); |
146 | |
147 | /* callback to handle vendor bespoke data */ |
148 | int (*vendor_load)(struct snd_soc_component *, int index, |
149 | struct snd_soc_tplg_hdr *); |
150 | int (*vendor_unload)(struct snd_soc_component *, |
151 | struct snd_soc_tplg_hdr *); |
152 | |
153 | /* completion - called at completion of firmware loading */ |
154 | int (*complete)(struct snd_soc_component *comp); |
155 | |
156 | /* manifest - optional to inform component of manifest */ |
157 | int (*manifest)(struct snd_soc_component *, int index, |
158 | struct snd_soc_tplg_manifest *); |
159 | |
160 | /* vendor specific kcontrol handlers available for binding */ |
161 | const struct snd_soc_tplg_kcontrol_ops *io_ops; |
162 | int io_ops_count; |
163 | |
164 | /* vendor specific bytes ext handlers available for binding */ |
165 | const struct snd_soc_tplg_bytes_ext_ops *bytes_ext_ops; |
166 | int bytes_ext_ops_count; |
167 | }; |
168 | |
169 | #ifdef CONFIG_SND_SOC_TOPOLOGY |
170 | |
171 | /* gets a pointer to data from the firmware block header */ |
172 | static inline const void *snd_soc_tplg_get_data(struct snd_soc_tplg_hdr *hdr) |
173 | { |
174 | const void *ptr = hdr; |
175 | |
176 | return ptr + sizeof(*hdr); |
177 | } |
178 | |
179 | /* Dynamic Object loading and removal for component drivers */ |
180 | int snd_soc_tplg_component_load(struct snd_soc_component *comp, |
181 | struct snd_soc_tplg_ops *ops, const struct firmware *fw); |
182 | int snd_soc_tplg_component_remove(struct snd_soc_component *comp); |
183 | |
184 | /* Binds event handlers to dynamic widgets */ |
185 | int snd_soc_tplg_widget_bind_event(struct snd_soc_dapm_widget *w, |
186 | const struct snd_soc_tplg_widget_events *events, int num_events, |
187 | u16 event_type); |
188 | |
189 | #else |
190 | |
191 | static inline int snd_soc_tplg_component_remove(struct snd_soc_component *comp) |
192 | { |
193 | return 0; |
194 | } |
195 | |
196 | #endif |
197 | |
198 | #endif |
199 | |