xref: /aosp_15_r20/external/tinyalsa_new/include/tinyalsa/plugin.h (revision 02e95f1a335b55495d41ca67eaf42361f13704fa)
1*02e95f1aSMarcin Radomski /* plugin.h
2*02e95f1aSMarcin Radomski ** Copyright (c) 2019-2020, The Linux Foundation.
3*02e95f1aSMarcin Radomski **
4*02e95f1aSMarcin Radomski ** Redistribution and use in source and binary forms, with or without
5*02e95f1aSMarcin Radomski ** modification, are permitted provided that the following conditions are
6*02e95f1aSMarcin Radomski ** met:
7*02e95f1aSMarcin Radomski **   * Redistributions of source code must retain the above copyright
8*02e95f1aSMarcin Radomski **     notice, this list of conditions and the following disclaimer.
9*02e95f1aSMarcin Radomski **   * Redistributions in binary form must reproduce the above
10*02e95f1aSMarcin Radomski **     copyright notice, this list of conditions and the following
11*02e95f1aSMarcin Radomski **     disclaimer in the documentation and/or other materials provided
12*02e95f1aSMarcin Radomski **     with the distribution.
13*02e95f1aSMarcin Radomski **   * Neither the name of The Linux Foundation nor the names of its
14*02e95f1aSMarcin Radomski **     contributors may be used to endorse or promote products derived
15*02e95f1aSMarcin Radomski **     from this software without specific prior written permission.
16*02e95f1aSMarcin Radomski **
17*02e95f1aSMarcin Radomski ** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18*02e95f1aSMarcin Radomski ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19*02e95f1aSMarcin Radomski ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20*02e95f1aSMarcin Radomski ** ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21*02e95f1aSMarcin Radomski ** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*02e95f1aSMarcin Radomski ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*02e95f1aSMarcin Radomski ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24*02e95f1aSMarcin Radomski ** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25*02e95f1aSMarcin Radomski ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26*02e95f1aSMarcin Radomski ** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27*02e95f1aSMarcin Radomski ** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*02e95f1aSMarcin Radomski **/
29*02e95f1aSMarcin Radomski 
30*02e95f1aSMarcin Radomski #ifndef TINYALSA_PLUGIN_H
31*02e95f1aSMarcin Radomski #define TINYALSA_PLUGIN_H
32*02e95f1aSMarcin Radomski 
33*02e95f1aSMarcin Radomski #include <poll.h>
34*02e95f1aSMarcin Radomski #include <stdint.h>
35*02e95f1aSMarcin Radomski #include <stdlib.h>
36*02e95f1aSMarcin Radomski #include <sys/types.h>
37*02e95f1aSMarcin Radomski #include <time.h>
38*02e95f1aSMarcin Radomski 
39*02e95f1aSMarcin Radomski #include <sound/asound.h>
40*02e95f1aSMarcin Radomski 
41*02e95f1aSMarcin Radomski /* static initializers */
42*02e95f1aSMarcin Radomski 
43*02e95f1aSMarcin Radomski #define SND_VALUE_ENUM(etexts, eitems)    \
44*02e95f1aSMarcin Radomski     {.texts = etexts, .items = eitems}
45*02e95f1aSMarcin Radomski 
46*02e95f1aSMarcin Radomski #define SND_VALUE_BYTES(csize)    \
47*02e95f1aSMarcin Radomski     {.size = csize }
48*02e95f1aSMarcin Radomski 
49*02e95f1aSMarcin Radomski #define SND_VALUE_INTEGER(icount, imin, imax, istep) \
50*02e95f1aSMarcin Radomski     {.count = icount, .min = imin, .max = imax, .step = istep }
51*02e95f1aSMarcin Radomski 
52*02e95f1aSMarcin Radomski #define SND_VALUE_TLV_BYTES(csize, cget, cput)       \
53*02e95f1aSMarcin Radomski     {.size = csize, .get = cget, .put = cput }
54*02e95f1aSMarcin Radomski 
55*02e95f1aSMarcin Radomski /* pointer based initializers */
56*02e95f1aSMarcin Radomski #define INIT_SND_CONTROL_INTEGER(c, cname, cget, cput, cint, pval, pdata)   \
57*02e95f1aSMarcin Radomski     {                                                                       \
58*02e95f1aSMarcin Radomski         c->iface = SNDRV_CTL_ELEM_IFACE_MIXER;                              \
59*02e95f1aSMarcin Radomski         c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;                        \
60*02e95f1aSMarcin Radomski         c->type = SNDRV_CTL_ELEM_TYPE_INTEGER;                              \
61*02e95f1aSMarcin Radomski         c->name = cname; c->value = &cint; c->get = cget; c->put = cput;    \
62*02e95f1aSMarcin Radomski         c->private_value = pval; c->private_data = pdata;                   \
63*02e95f1aSMarcin Radomski     }
64*02e95f1aSMarcin Radomski 
65*02e95f1aSMarcin Radomski #define INIT_SND_CONTROL_BYTES(c, cname, cget, cput, cint, pval, pdata)     \
66*02e95f1aSMarcin Radomski     {                                                                       \
67*02e95f1aSMarcin Radomski         c->iface = SNDRV_CTL_ELEM_IFACE_MIXER;                              \
68*02e95f1aSMarcin Radomski         c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;                        \
69*02e95f1aSMarcin Radomski         c->type = SNDRV_CTL_ELEM_TYPE_BYTES;                                \
70*02e95f1aSMarcin Radomski         c->name = cname; c->value = &cint; c->get = cget; c->put = cput;    \
71*02e95f1aSMarcin Radomski         c->private_value = pval; c->private_data = pdata;                   \
72*02e95f1aSMarcin Radomski     }
73*02e95f1aSMarcin Radomski 
74*02e95f1aSMarcin Radomski #define INIT_SND_CONTROL_ENUM(c, cname, cget, cput, cenum, pval, pdata)     \
75*02e95f1aSMarcin Radomski     {                                                                       \
76*02e95f1aSMarcin Radomski         c->iface = SNDRV_CTL_ELEM_IFACE_MIXER;                              \
77*02e95f1aSMarcin Radomski         c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;                        \
78*02e95f1aSMarcin Radomski         c->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;                           \
79*02e95f1aSMarcin Radomski         c->name = cname; c->value = cenum; c->get = cget; c->put = cput;    \
80*02e95f1aSMarcin Radomski         c->private_value = pval; c->private_data = pdata;                   \
81*02e95f1aSMarcin Radomski     }
82*02e95f1aSMarcin Radomski 
83*02e95f1aSMarcin Radomski #define INIT_SND_CONTROL_TLV_BYTES(c, cname, cbytes, priv_val, priv_data)  \
84*02e95f1aSMarcin Radomski     {                                                                      \
85*02e95f1aSMarcin Radomski         c->iface = SNDRV_CTL_ELEM_IFACE_MIXER;                             \
86*02e95f1aSMarcin Radomski         c->access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE;                   \
87*02e95f1aSMarcin Radomski         c->type = SNDRV_CTL_ELEM_TYPE_BYTES;                               \
88*02e95f1aSMarcin Radomski         c->name = cname; c->value = &cbytes;                               \
89*02e95f1aSMarcin Radomski         c->private_value = priv_val; c->private_data = priv_data;          \
90*02e95f1aSMarcin Radomski     }
91*02e95f1aSMarcin Radomski 
92*02e95f1aSMarcin Radomski struct mixer_plugin;
93*02e95f1aSMarcin Radomski struct pcm_plugin;
94*02e95f1aSMarcin Radomski struct snd_node;
95*02e95f1aSMarcin Radomski 
96*02e95f1aSMarcin Radomski /** Operations that are required to be registered by the plugin.
97*02e95f1aSMarcin Radomski  * @ingroup libtinyalsa-pcm
98*02e95f1aSMarcin Radomski  */
99*02e95f1aSMarcin Radomski struct pcm_plugin_ops {
100*02e95f1aSMarcin Radomski     /** open the pcm plugin */
101*02e95f1aSMarcin Radomski     int (*open) (struct pcm_plugin **plugin, unsigned int card,
102*02e95f1aSMarcin Radomski                  unsigned int device, unsigned int flags);
103*02e95f1aSMarcin Radomski     /** close the pcm plugin */
104*02e95f1aSMarcin Radomski     int (*close) (struct pcm_plugin *plugin);
105*02e95f1aSMarcin Radomski     /** Set the PCM hardware parameters to the plugin */
106*02e95f1aSMarcin Radomski     int (*hw_params) (struct pcm_plugin *plugin,
107*02e95f1aSMarcin Radomski                       struct snd_pcm_hw_params *params);
108*02e95f1aSMarcin Radomski     /** Set the PCM software parameters to the plugin */
109*02e95f1aSMarcin Radomski     int (*sw_params) (struct pcm_plugin *plugin,
110*02e95f1aSMarcin Radomski                       struct snd_pcm_sw_params *params);
111*02e95f1aSMarcin Radomski     /** Synchronize the pointer */
112*02e95f1aSMarcin Radomski     int (*sync_ptr) (struct pcm_plugin *plugin,
113*02e95f1aSMarcin Radomski                      struct snd_pcm_sync_ptr *sync_ptr);
114*02e95f1aSMarcin Radomski     /** Write frames to plugin to be rendered to output */
115*02e95f1aSMarcin Radomski     int (*writei_frames) (struct pcm_plugin *plugin,
116*02e95f1aSMarcin Radomski                           struct snd_xferi *x);
117*02e95f1aSMarcin Radomski     /** Read frames from plugin captured from input */
118*02e95f1aSMarcin Radomski     int (*readi_frames) (struct pcm_plugin *plugin,
119*02e95f1aSMarcin Radomski                          struct snd_xferi *x);
120*02e95f1aSMarcin Radomski     /** Obtain the timestamp for the PCM */
121*02e95f1aSMarcin Radomski     int (*ttstamp) (struct pcm_plugin *plugin,
122*02e95f1aSMarcin Radomski                     int *tstamp);
123*02e95f1aSMarcin Radomski     /** Prepare the plugin for data transfer */
124*02e95f1aSMarcin Radomski     int (*prepare) (struct pcm_plugin *plugin);
125*02e95f1aSMarcin Radomski     /** Start data transfer from/to the plugin */
126*02e95f1aSMarcin Radomski     int (*start) (struct pcm_plugin *plugin);
127*02e95f1aSMarcin Radomski     /** Signal the plugin to drain PCM */
128*02e95f1aSMarcin Radomski     int (*drain) (struct pcm_plugin *plugin);
129*02e95f1aSMarcin Radomski     /** Stop a PCM dropping pending frames if drain() is NOT called.
130*02e95f1aSMarcin Radomski      *  Stop a PCM preserving pending frames if drain() is called. */
131*02e95f1aSMarcin Radomski     int (*drop) (struct pcm_plugin *plugin);
132*02e95f1aSMarcin Radomski     /** Any custom or alsa specific ioctl implementation */
133*02e95f1aSMarcin Radomski     int (*ioctl) (struct pcm_plugin *plugin,
134*02e95f1aSMarcin Radomski                   int cmd, void *arg);
135*02e95f1aSMarcin Radomski     void *(*mmap) (struct pcm_plugin *plugin, void *addr, size_t length,
136*02e95f1aSMarcin Radomski                    int prot, int flags, off_t offset);
137*02e95f1aSMarcin Radomski     int (*munmap) (struct pcm_plugin *plugin, void *addr, size_t length);
138*02e95f1aSMarcin Radomski     int (*poll) (struct pcm_plugin *plugin, struct pollfd *pfd, nfds_t nfds,
139*02e95f1aSMarcin Radomski                  int timeout);
140*02e95f1aSMarcin Radomski };
141*02e95f1aSMarcin Radomski 
142*02e95f1aSMarcin Radomski /** Minimum and maximum values for hardware parameter constraints.
143*02e95f1aSMarcin Radomski  * @ingroup libtinyalsa-pcm
144*02e95f1aSMarcin Radomski  */
145*02e95f1aSMarcin Radomski struct pcm_plugin_min_max {
146*02e95f1aSMarcin Radomski     /** Minimum value for the hardware parameter */
147*02e95f1aSMarcin Radomski     unsigned int min;
148*02e95f1aSMarcin Radomski     /** Maximum value for the hardware parameter */
149*02e95f1aSMarcin Radomski     unsigned int max;
150*02e95f1aSMarcin Radomski };
151*02e95f1aSMarcin Radomski 
152*02e95f1aSMarcin Radomski /** Encapsulate the hardware parameter constraints
153*02e95f1aSMarcin Radomski  * @ingroup libtinyalsa-pcm
154*02e95f1aSMarcin Radomski  */
155*02e95f1aSMarcin Radomski struct pcm_plugin_hw_constraints {
156*02e95f1aSMarcin Radomski     /** Value for SNDRV_PCM_HW_PARAM_ACCESS param */
157*02e95f1aSMarcin Radomski     uint64_t access;
158*02e95f1aSMarcin Radomski     /** Value for SNDRV_PCM_HW_PARAM_FORMAT param.
159*02e95f1aSMarcin Radomski      * As of this implementation ALSA supports 52 formats */
160*02e95f1aSMarcin Radomski     uint64_t format;
161*02e95f1aSMarcin Radomski     /** Value for SNDRV_PCM_HW_PARAM_SAMPLE_BITS param */
162*02e95f1aSMarcin Radomski     struct pcm_plugin_min_max bit_width;
163*02e95f1aSMarcin Radomski     /** Value for SNDRV_PCM_HW_PARAM_CHANNELS param */
164*02e95f1aSMarcin Radomski     struct pcm_plugin_min_max channels;
165*02e95f1aSMarcin Radomski     /** Value for SNDRV_PCM_HW_PARAM_RATE param */
166*02e95f1aSMarcin Radomski     struct pcm_plugin_min_max rate;
167*02e95f1aSMarcin Radomski     /** Value for SNDRV_PCM_HW_PARAM_PERIODS param */
168*02e95f1aSMarcin Radomski     struct pcm_plugin_min_max periods;
169*02e95f1aSMarcin Radomski     /** Value for SNDRV_PCM_HW_PARAM_PERIOD_BYTES param */
170*02e95f1aSMarcin Radomski     struct pcm_plugin_min_max period_bytes;
171*02e95f1aSMarcin Radomski };
172*02e95f1aSMarcin Radomski 
173*02e95f1aSMarcin Radomski struct pcm_plugin {
174*02e95f1aSMarcin Radomski     /** Card number for the pcm device */
175*02e95f1aSMarcin Radomski     unsigned int card;
176*02e95f1aSMarcin Radomski     /** device number for the pcm device */
177*02e95f1aSMarcin Radomski     unsigned int device;
178*02e95f1aSMarcin Radomski     /** pointer to the contraints registered by the plugin */
179*02e95f1aSMarcin Radomski     struct pcm_plugin_hw_constraints *constraints;
180*02e95f1aSMarcin Radomski     /** Indicates read/write mode, etc.. */
181*02e95f1aSMarcin Radomski     int mode;
182*02e95f1aSMarcin Radomski     /* Pointer to hold the plugin's private data */
183*02e95f1aSMarcin Radomski     void *priv;
184*02e95f1aSMarcin Radomski     /* Tracks the plugin state */
185*02e95f1aSMarcin Radomski     unsigned int state;
186*02e95f1aSMarcin Radomski };
187*02e95f1aSMarcin Radomski 
188*02e95f1aSMarcin Radomski typedef void (*mixer_event_callback)(struct mixer_plugin *);
189*02e95f1aSMarcin Radomski 
190*02e95f1aSMarcin Radomski struct mixer_plugin_ops {
191*02e95f1aSMarcin Radomski     int (*open) (struct mixer_plugin **plugin, unsigned int card);
192*02e95f1aSMarcin Radomski     void (*close) (struct mixer_plugin **plugin);
193*02e95f1aSMarcin Radomski     int (*subscribe_events) (struct mixer_plugin *plugin,
194*02e95f1aSMarcin Radomski                              mixer_event_callback event_cb);
195*02e95f1aSMarcin Radomski     ssize_t (*read_event) (struct mixer_plugin *plugin,
196*02e95f1aSMarcin Radomski                            struct snd_ctl_event *ev, size_t size);
197*02e95f1aSMarcin Radomski };
198*02e95f1aSMarcin Radomski 
199*02e95f1aSMarcin Radomski struct snd_control {
200*02e95f1aSMarcin Radomski     snd_ctl_elem_iface_t iface;
201*02e95f1aSMarcin Radomski     unsigned int access;
202*02e95f1aSMarcin Radomski     const char *name;
203*02e95f1aSMarcin Radomski     snd_ctl_elem_type_t type;
204*02e95f1aSMarcin Radomski     void *value;
205*02e95f1aSMarcin Radomski     int (*get) (struct mixer_plugin *plugin,
206*02e95f1aSMarcin Radomski                 struct snd_control *control,
207*02e95f1aSMarcin Radomski                 struct snd_ctl_elem_value *ev);
208*02e95f1aSMarcin Radomski     int (*put) (struct mixer_plugin *plugin,
209*02e95f1aSMarcin Radomski                 struct snd_control *control,
210*02e95f1aSMarcin Radomski                 struct snd_ctl_elem_value *ev);
211*02e95f1aSMarcin Radomski     uint32_t private_value;
212*02e95f1aSMarcin Radomski     void *private_data;
213*02e95f1aSMarcin Radomski };
214*02e95f1aSMarcin Radomski 
215*02e95f1aSMarcin Radomski struct mixer_plugin {
216*02e95f1aSMarcin Radomski     unsigned int card;
217*02e95f1aSMarcin Radomski     void *priv;
218*02e95f1aSMarcin Radomski 
219*02e95f1aSMarcin Radomski     int eventfd;
220*02e95f1aSMarcin Radomski     int subscribed;
221*02e95f1aSMarcin Radomski     int event_cnt;
222*02e95f1aSMarcin Radomski 
223*02e95f1aSMarcin Radomski     struct snd_control *controls;
224*02e95f1aSMarcin Radomski     unsigned int num_controls;
225*02e95f1aSMarcin Radomski };
226*02e95f1aSMarcin Radomski 
227*02e95f1aSMarcin Radomski struct snd_value_enum {
228*02e95f1aSMarcin Radomski     unsigned int items;
229*02e95f1aSMarcin Radomski     char **texts;
230*02e95f1aSMarcin Radomski };
231*02e95f1aSMarcin Radomski 
232*02e95f1aSMarcin Radomski struct snd_value_bytes {
233*02e95f1aSMarcin Radomski     unsigned int size;
234*02e95f1aSMarcin Radomski };
235*02e95f1aSMarcin Radomski 
236*02e95f1aSMarcin Radomski struct snd_value_tlv_bytes {
237*02e95f1aSMarcin Radomski     unsigned int size;
238*02e95f1aSMarcin Radomski     int (*get) (struct mixer_plugin *plugin,
239*02e95f1aSMarcin Radomski                 struct snd_control *control,
240*02e95f1aSMarcin Radomski                 struct snd_ctl_tlv *tlv);
241*02e95f1aSMarcin Radomski     int (*put) (struct mixer_plugin *plugin,
242*02e95f1aSMarcin Radomski                 struct snd_control *control,
243*02e95f1aSMarcin Radomski                 struct snd_ctl_tlv *tlv);
244*02e95f1aSMarcin Radomski };
245*02e95f1aSMarcin Radomski 
246*02e95f1aSMarcin Radomski struct snd_value_int {
247*02e95f1aSMarcin Radomski     unsigned int count;
248*02e95f1aSMarcin Radomski     int min;
249*02e95f1aSMarcin Radomski     int max;
250*02e95f1aSMarcin Radomski     int step;
251*02e95f1aSMarcin Radomski };
252*02e95f1aSMarcin Radomski 
253*02e95f1aSMarcin Radomski /** Operations defined by the plugin.
254*02e95f1aSMarcin Radomski  * */
255*02e95f1aSMarcin Radomski struct snd_node_ops {
256*02e95f1aSMarcin Radomski     /** Function pointer to get card definition */
257*02e95f1aSMarcin Radomski     void* (*open_card)(unsigned int card);
258*02e95f1aSMarcin Radomski     /** Function pointer to release card definition */
259*02e95f1aSMarcin Radomski     void (*close_card)(void *card);
260*02e95f1aSMarcin Radomski     /** Get interger type properties from device definition */
261*02e95f1aSMarcin Radomski     int (*get_int)(void *node, const char *prop, int *val);
262*02e95f1aSMarcin Radomski     /** Get string type properties from device definition */
263*02e95f1aSMarcin Radomski     int (*get_str)(void *node, const char *prop, char **val);
264*02e95f1aSMarcin Radomski     /** Function pointer to get mixer definition */
265*02e95f1aSMarcin Radomski     void* (*get_mixer)(void *card);
266*02e95f1aSMarcin Radomski     /** Function pointer to get PCM definition */
267*02e95f1aSMarcin Radomski     void* (*get_pcm)(void *card, unsigned int id);
268*02e95f1aSMarcin Radomski     /** Reserved for other nodes such as compress */
269*02e95f1aSMarcin Radomski     void* reserved[4];
270*02e95f1aSMarcin Radomski };
271*02e95f1aSMarcin Radomski 
272*02e95f1aSMarcin Radomski #endif /* end of TINYALSA_PLUGIN_H */
273