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 #define MIXER_PLUGIN_OPEN_FN(name) \ 35 int name##_open(struct mixer_plugin **plugin, \ 36 unsigned int card) 37 38 #define MIXER_PLUGIN_OPEN_FN_PTR() \ 39 int (*mixer_plugin_open_fn) (struct mixer_plugin **plugin, \ 40 unsigned int card) \ 41 42 struct mixer_plugin; 43 44 typedef void (*event_callback)(struct mixer_plugin *); 45 46 struct mixer_plugin_ops { 47 void (*close) (struct mixer_plugin **plugin); 48 int (*subscribe_events) (struct mixer_plugin *plugin, 49 event_callback event_cb); 50 ssize_t (*read_event) (struct mixer_plugin *plugin, 51 struct ctl_event *ev, size_t size); 52 }; 53 54 struct snd_control { 55 ctl_elem_iface_t iface; 56 unsigned int access; 57 const char *name; 58 snd_ctl_elem_type_t type; 59 void *value; 60 int (*get) (struct mixer_plugin *plugin, 61 struct snd_control *control, 62 struct snd_ctl_elem_value *ev); 63 int (*put) (struct mixer_plugin *plugin, 64 struct snd_control *control, 65 struct snd_ctl_elem_value *ev); 66 uint32_t private_value; 67 void *private_data; 68 }; 69 70 struct mixer_plugin { 71 unsigned int card; 72 struct mixer_plugin_ops *ops; 73 void *priv; 74 75 int eventfd; 76 int subscribed; 77 int event_cnt; 78 79 struct snd_control *controls; 80 unsigned int num_controls; 81 }; 82 83 struct snd_value_enum { 84 unsigned int items; 85 char **texts; 86 }; 87 88 struct snd_value_bytes { 89 unsigned int size; 90 }; 91 92 struct snd_value_tlv_bytes { 93 unsigned int size; 94 int (*get) (struct mixer_plugin *plugin, 95 struct snd_control *control, 96 struct snd_ctl_tlv *tlv); 97 int (*put) (struct mixer_plugin *plugin, 98 struct snd_control *control, 99 struct snd_ctl_tlv *tlv); 100 }; 101 102 struct snd_value_int { 103 unsigned int count; 104 int min; 105 int max; 106 int step; 107 }; 108 109 /* static initializers */ 110 111 #define SND_VALUE_ENUM(etexts, eitems) \ 112 {.texts = etexts, .items = eitems} 113 114 #define SND_VALUE_BYTES(csize) \ 115 {.size = csize } 116 117 #define SND_VALUE_INTEGER(icount, imin, imax, istep) \ 118 {.count = icount, .min = imin, .max = imax, .step = istep } 119 120 #define SND_VALUE_TLV_BYTES(csize, cget, cput) \ 121 {.size = csize, .get = cget, .put = cput } 122 123 #define SND_CONTROL_ENUM(cname, cget, cput, cenum, priv_val, priv_data) \ 124 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 125 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 126 .type = SNDRV_CTL_ELEM_TYPE_ENUMERATED, \ 127 .name = cname, .value = &cenum, .get = cget, .put = cput, \ 128 .private_value = priv_val, .private_data = priv_data, \ 129 } 130 131 #define SND_CONTROL_BYTES(cname, cget, cput, cbytes, priv_val, priv_data) \ 132 { \ 133 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 134 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 135 .type = SNDRV_CTL_ELEM_TYPE_BYTES, \ 136 .name = cname, .value = &cbytes, .get = cget, .put = cput, \ 137 .private_value = priv_val, .private_data = priv_data, \ 138 } 139 140 #define SND_CONTROL_INTEGER(cname, cget, cput, cint, priv_val, priv_data) \ 141 { \ 142 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 143 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 144 .type = SNDRV_CTL_ELEM_TYPE_INTEGER, \ 145 .name = cname, .value = &cint, .get = cget, .put = cput, \ 146 .private_value = priv_val, .private_data = priv_data, \ 147 } 148 149 #define SND_CONTROL_TLV_BYTES(cname, cbytes, priv_val, priv_data) \ 150 { \ 151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 152 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE, \ 153 .type = SNDRV_CTL_ELEM_TYPE_BYTES, \ 154 .name = cname, .value = &cbytes, \ 155 .private_value = priv_val, .private_data = priv_data, \ 156 } 157 158 /* pointer based initializers */ 159 #define INIT_SND_CONTROL_INTEGER(c, cname, cget, cput, cint, pval, pdata) \ 160 { \ 161 c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \ 162 c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; \ 163 c->type = SNDRV_CTL_ELEM_TYPE_INTEGER; \ 164 c->name = cname; c->value = &cint; c->get = cget; c->put = cput; \ 165 c->private_value = pval; c->private_data = pdata; \ 166 } 167 168 #define INIT_SND_CONTROL_BYTES(c, cname, cget, cput, cint, pval, pdata) \ 169 { \ 170 c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \ 171 c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; \ 172 c->type = SNDRV_CTL_ELEM_TYPE_BYTES; \ 173 c->name = cname; c->value = &cint; c->get = cget; c->put = cput; \ 174 c->private_value = pval; c->private_data = pdata; \ 175 } 176 177 #define INIT_SND_CONTROL_ENUM(c, cname, cget, cput, cenum, pval, pdata) \ 178 { \ 179 c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \ 180 c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; \ 181 c->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; \ 182 c->name = cname; c->value = cenum; c->get = cget; c->put = cput; \ 183 c->private_value = pval; c->private_data = pdata; \ 184 } 185 #define INIT_SND_CONTROL_TLV_BYTES(c, cname, cbytes, priv_val, priv_data) \ 186 { \ 187 c->iface = SNDRV_CTL_ELEM_IFACE_MIXER; \ 188 c->access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE; \ 189 c->type = SNDRV_CTL_ELEM_TYPE_BYTES; \ 190 c->name = cname; c->value = &cbytes; \ 191 c->private_value = priv_val; c->private_data = priv_data; \ 192 } 193 #endif /* end of __MIXER_PLUGIN_H__ */ 194