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 */
snd_soc_tplg_get_data(struct snd_soc_tplg_hdr * hdr)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  	const 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  
snd_soc_tplg_component_remove(struct snd_soc_component * comp)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