1*d0c94b83SXin Li /* 2*d0c94b83SXin Li ** Copyright (c) 2019, The Linux Foundation. All rights reserved. 3*d0c94b83SXin Li ** 4*d0c94b83SXin Li ** Redistribution and use in source and binary forms, with or without 5*d0c94b83SXin Li ** modification, are permitted provided that the following conditions are 6*d0c94b83SXin Li ** met: 7*d0c94b83SXin Li ** * Redistributions of source code must retain the above copyright 8*d0c94b83SXin Li ** notice, this list of conditions and the following disclaimer. 9*d0c94b83SXin Li ** * Redistributions in binary form must reproduce the above 10*d0c94b83SXin Li ** copyright notice, this list of conditions and the following 11*d0c94b83SXin Li ** disclaimer in the documentation and/or other materials provided 12*d0c94b83SXin Li ** with the distribution. 13*d0c94b83SXin Li ** * Neither the name of The Linux Foundation nor the names of its 14*d0c94b83SXin Li ** contributors may be used to endorse or promote products derived 15*d0c94b83SXin Li ** from this software without specific prior written permission. 16*d0c94b83SXin Li ** 17*d0c94b83SXin Li ** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18*d0c94b83SXin Li ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19*d0c94b83SXin Li ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20*d0c94b83SXin Li ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21*d0c94b83SXin Li ** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22*d0c94b83SXin Li ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23*d0c94b83SXin Li ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24*d0c94b83SXin Li ** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25*d0c94b83SXin Li ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26*d0c94b83SXin Li ** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27*d0c94b83SXin Li ** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*d0c94b83SXin Li **/ 29*d0c94b83SXin Li 30*d0c94b83SXin Li 31*d0c94b83SXin Li #ifndef __MIXER_PLUGIN_H__ 32*d0c94b83SXin Li #define __MIXER_PLUGIN_H__ 33*d0c94b83SXin Li 34*d0c94b83SXin Li #include <pthread.h> 35*d0c94b83SXin Li 36*d0c94b83SXin Li #define MIXER_PLUGIN_OPEN_FN(name) \ 37*d0c94b83SXin Li int name##_open(struct mixer_plugin **plugin, \ 38*d0c94b83SXin Li unsigned int card) 39*d0c94b83SXin Li 40*d0c94b83SXin Li #define MIXER_PLUGIN_OPEN_FN_PTR() \ 41*d0c94b83SXin Li int (*mixer_plugin_open_fn) (struct mixer_plugin **plugin, \ 42*d0c94b83SXin Li unsigned int card) \ 43*d0c94b83SXin Li 44*d0c94b83SXin Li struct mixer_plugin; 45*d0c94b83SXin Li 46*d0c94b83SXin Li typedef void (*event_callback)(struct mixer_plugin *); 47*d0c94b83SXin Li 48*d0c94b83SXin Li struct mixer_plugin_ops { 49*d0c94b83SXin Li void (*close) (struct mixer_plugin **plugin); 50*d0c94b83SXin Li int (*subscribe_events) (struct mixer_plugin *plugin, 51*d0c94b83SXin Li event_callback event_cb); 52*d0c94b83SXin Li ssize_t (*read_event) (struct mixer_plugin *plugin, 53*d0c94b83SXin Li struct ctl_event *ev, size_t size); 54*d0c94b83SXin Li }; 55*d0c94b83SXin Li 56*d0c94b83SXin Li struct snd_control { 57*d0c94b83SXin Li ctl_elem_iface_t iface; 58*d0c94b83SXin Li unsigned int access; 59*d0c94b83SXin Li const char *name; 60*d0c94b83SXin Li snd_ctl_elem_type_t type; 61*d0c94b83SXin Li void *value; 62*d0c94b83SXin Li int (*get) (struct mixer_plugin *plugin, 63*d0c94b83SXin Li struct snd_control *control, 64*d0c94b83SXin Li struct snd_ctl_elem_value *ev); 65*d0c94b83SXin Li int (*put) (struct mixer_plugin *plugin, 66*d0c94b83SXin Li struct snd_control *control, 67*d0c94b83SXin Li struct snd_ctl_elem_value *ev); 68*d0c94b83SXin Li uint32_t private_value; 69*d0c94b83SXin Li void *private_data; 70*d0c94b83SXin Li }; 71*d0c94b83SXin Li 72*d0c94b83SXin Li struct mixer_plugin { 73*d0c94b83SXin Li unsigned int card; 74*d0c94b83SXin Li struct mixer_plugin_ops *ops; 75*d0c94b83SXin Li void *priv; 76*d0c94b83SXin Li 77*d0c94b83SXin Li int eventfd; 78*d0c94b83SXin Li int subscribed; 79*d0c94b83SXin Li int event_cnt; 80*d0c94b83SXin Li 81*d0c94b83SXin Li struct snd_control *controls; 82*d0c94b83SXin Li unsigned int num_controls; 83*d0c94b83SXin Li pthread_mutex_t mutex; 84*d0c94b83SXin Li }; 85*d0c94b83SXin Li 86*d0c94b83SXin Li struct snd_value_enum { 87*d0c94b83SXin Li unsigned int items; 88*d0c94b83SXin Li char **texts; 89*d0c94b83SXin Li }; 90*d0c94b83SXin Li 91*d0c94b83SXin Li struct snd_value_bytes { 92*d0c94b83SXin Li unsigned int size; 93*d0c94b83SXin Li }; 94*d0c94b83SXin Li 95*d0c94b83SXin Li struct snd_value_tlv_bytes { 96*d0c94b83SXin Li unsigned int size; 97*d0c94b83SXin Li int (*get) (struct mixer_plugin *plugin, 98*d0c94b83SXin Li struct snd_control *control, 99*d0c94b83SXin Li struct snd_ctl_tlv *tlv); 100*d0c94b83SXin Li int (*put) (struct mixer_plugin *plugin, 101*d0c94b83SXin Li struct snd_control *control, 102*d0c94b83SXin Li struct snd_ctl_tlv *tlv); 103*d0c94b83SXin Li }; 104*d0c94b83SXin Li 105*d0c94b83SXin Li struct snd_value_int { 106*d0c94b83SXin Li unsigned int count; 107*d0c94b83SXin Li int min; 108*d0c94b83SXin Li int max; 109*d0c94b83SXin Li int step; 110*d0c94b83SXin Li }; 111*d0c94b83SXin Li 112*d0c94b83SXin Li /* static initializers */ 113*d0c94b83SXin Li 114*d0c94b83SXin Li #define SND_VALUE_ENUM(etexts, eitems) \ 115*d0c94b83SXin Li {.texts = etexts, .items = eitems} 116*d0c94b83SXin Li 117*d0c94b83SXin Li #define SND_VALUE_BYTES(csize) \ 118*d0c94b83SXin Li {.size = csize } 119*d0c94b83SXin Li 120*d0c94b83SXin Li #define SND_VALUE_INTEGER(icount, imin, imax, istep) \ 121*d0c94b83SXin Li {.count = icount, .min = imin, .max = imax, .step = istep } 122*d0c94b83SXin Li 123*d0c94b83SXin Li #define SND_VALUE_TLV_BYTES(csize, cget, cput) \ 124*d0c94b83SXin Li {.size = csize, .get = cget, .put = cput } 125*d0c94b83SXin Li 126*d0c94b83SXin Li #define SND_CONTROL_ENUM(cname, cget, cput, cenum, priv_val, priv_data) \ 127*d0c94b83SXin Li { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 128*d0c94b83SXin Li .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 129*d0c94b83SXin Li .type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, \ 130*d0c94b83SXin Li .name = cname, .value = &cenum, .get = cget, .put = cput, \ 131*d0c94b83SXin Li .private_value = priv_val, .private_data = priv_data, \ 132*d0c94b83SXin Li } 133*d0c94b83SXin Li 134*d0c94b83SXin Li #define SND_CONTROL_BYTES(cname, cget, cput, cbytes, priv_val, priv_data) \ 135*d0c94b83SXin Li { \ 136*d0c94b83SXin Li .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 137*d0c94b83SXin Li .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 138*d0c94b83SXin Li .type = SNDRV_CTL_ELEM_TYPE_BYTES, \ 139*d0c94b83SXin Li .name = cname, .value = &cbytes, .get = cget, .put = cput, \ 140*d0c94b83SXin Li .private_value = priv_val, .private_data = priv_data, \ 141*d0c94b83SXin Li } 142*d0c94b83SXin Li 143*d0c94b83SXin Li #define SND_CONTROL_INTEGER(cname, cget, cput, cint, priv_val, priv_data) \ 144*d0c94b83SXin Li { \ 145*d0c94b83SXin Li .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 146*d0c94b83SXin Li .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 147*d0c94b83SXin Li .type = SNDRV_CTL_ELEM_TYPE_INTEGER, \ 148*d0c94b83SXin Li .name = cname, .value = &cint, .get = cget, .put = cput, \ 149*d0c94b83SXin Li .private_value = priv_val, .private_data = priv_data, \ 150*d0c94b83SXin Li } 151*d0c94b83SXin Li 152*d0c94b83SXin Li #define SND_CONTROL_TLV_BYTES(cname, cbytes, priv_val, priv_data) \ 153*d0c94b83SXin Li { \ 154*d0c94b83SXin Li .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 155*d0c94b83SXin Li .access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE, \ 156*d0c94b83SXin Li .type = SNDRV_CTL_ELEM_TYPE_BYTES, \ 157*d0c94b83SXin Li .name = cname, .value = &cbytes, \ 158*d0c94b83SXin Li .private_value = priv_val, .private_data = priv_data, \ 159*d0c94b83SXin Li } 160*d0c94b83SXin Li 161*d0c94b83SXin Li /* pointer based initializers */ 162*d0c94b83SXin Li #define INIT_SND_CONTROL_INTEGER(c, cname, cget, cput, cint, pval, pdata) \ 163*d0c94b83SXin Li { \ 164*d0c94b83SXin Li c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \ 165*d0c94b83SXin Li c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; \ 166*d0c94b83SXin Li c->type = SNDRV_CTL_ELEM_TYPE_INTEGER; \ 167*d0c94b83SXin Li c->name = cname; c->value = &cint; c->get = cget; c->put = cput; \ 168*d0c94b83SXin Li c->private_value = pval; c->private_data = pdata; \ 169*d0c94b83SXin Li } 170*d0c94b83SXin Li 171*d0c94b83SXin Li #define INIT_SND_CONTROL_BYTES(c, cname, cget, cput, cint, pval, pdata) \ 172*d0c94b83SXin Li { \ 173*d0c94b83SXin Li c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \ 174*d0c94b83SXin Li c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; \ 175*d0c94b83SXin Li c->type = SNDRV_CTL_ELEM_TYPE_BYTES; \ 176*d0c94b83SXin Li c->name = cname; c->value = &cint; c->get = cget; c->put = cput; \ 177*d0c94b83SXin Li c->private_value = pval; c->private_data = pdata; \ 178*d0c94b83SXin Li } 179*d0c94b83SXin Li 180*d0c94b83SXin Li #define INIT_SND_CONTROL_ENUM(c, cname, cget, cput, cenum, pval, pdata) \ 181*d0c94b83SXin Li { \ 182*d0c94b83SXin Li c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \ 183*d0c94b83SXin Li c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; \ 184*d0c94b83SXin Li c->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; \ 185*d0c94b83SXin Li c->name = cname; c->value = cenum; c->get = cget; c->put = cput; \ 186*d0c94b83SXin Li c->private_value = pval; c->private_data = pdata; \ 187*d0c94b83SXin Li } 188*d0c94b83SXin Li #define INIT_SND_CONTROL_TLV_BYTES(c, cname, cbytes, priv_val, priv_data) \ 189*d0c94b83SXin Li { \ 190*d0c94b83SXin Li c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \ 191*d0c94b83SXin Li c->access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE; \ 192*d0c94b83SXin Li c->type = SNDRV_CTL_ELEM_TYPE_BYTES; \ 193*d0c94b83SXin Li c->name = cname; c->value = &cbytes; \ 194*d0c94b83SXin Li c->private_value = priv_val; c->private_data = priv_data; \ 195*d0c94b83SXin Li } 196*d0c94b83SXin Li #endif /* end of __MIXER_PLUGIN_H__ */ 197