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