1 /* 2 * Virtual master and slave controls 3 * 4 * Copyright (c) 2008 by Takashi Iwai <tiwai@suse.de> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation, version 2. 9 * 10 */ 11 12 #include <linux/slab.h> 13 #include <linux/export.h> 14 #include <sound/core.h> 15 #include <sound/control.h> 16 #include <sound/tlv.h> 17 18 /* 19 * a subset of information returned via ctl info callback 20 */ 21 struct link_ctl_info { 22 snd_ctl_elem_type_t type; /* value type */ 23 int count; /* item count */ 24 int min_val, max_val; /* min, max values */ 25 }; 26 27 /* 28 * link master - this contains a list of slave controls that are 29 * identical types, i.e. info returns the same value type and value 30 * ranges, but may have different number of counts. 31 * 32 * The master control is so far only mono volume/switch for simplicity. 33 * The same value will be applied to all slaves. 34 */ 35 struct link_master { 36 struct list_head slaves; 37 struct link_ctl_info info; 38 int val; /* the master value */ 39 unsigned int tlv[4]; 40 }; 41 42 /* 43 * link slave - this contains a slave control element 44 * 45 * It fakes the control callbacsk with additional attenuation by the 46 * master control. A slave may have either one or two channels. 47 */ 48 49 struct link_slave { 50 struct list_head list; 51 struct link_master *master; 52 struct link_ctl_info info; 53 int vals[2]; /* current values */ 54 unsigned int flags; 55 struct snd_kcontrol *kctl; /* original kcontrol pointer */ 56 struct snd_kcontrol slave; /* the copy of original control entry */ 57 }; 58 59 static int slave_update(struct link_slave *slave) 60 { 61 struct snd_ctl_elem_value *uctl; 62 int err, ch; 63 64 uctl = kmalloc(sizeof(*uctl), GFP_KERNEL); 65 if (!uctl) 66 return -ENOMEM; 67 uctl->id = slave->slave.id; 68 err = slave->slave.get(&slave->slave, uctl); 69 for (ch = 0; ch < slave->info.count; ch++) 70 slave->vals[ch] = uctl->value.integer.value[ch]; 71 kfree(uctl); 72 return 0; 73 } 74 75 /* get the slave ctl info and save the initial values */ 76 static int slave_init(struct link_slave *slave) 77 { 78 struct snd_ctl_elem_info *uinfo; 79 int err; 80 81 if (slave->info.count) { 82 /* already initialized */ 83 if (slave->flags & SND_CTL_SLAVE_NEED_UPDATE) 84 return slave_update(slave); 85 return 0; 86 } 87 88 uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL); 89 if (!uinfo) 90 return -ENOMEM; 91 uinfo->id = slave->slave.id; 92 err = slave->slave.info(&slave->slave, uinfo); 93 if (err < 0) { 94 kfree(uinfo); 95 return err; 96 } 97 slave->info.type = uinfo->type; 98 slave->info.count = uinfo->count; 99 if (slave->info.count > 2 || 100 (slave->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER && 101 slave->info.type != SNDRV_CTL_ELEM_TYPE_BOOLEAN)) { 102 snd_printk(KERN_ERR "invalid slave element\n"); 103 kfree(uinfo); 104 return -EINVAL; 105 } 106 slave->info.min_val = uinfo->value.integer.min; 107 slave->info.max_val = uinfo->value.integer.max; 108 kfree(uinfo); 109 110 return slave_update(slave); 111 } 112 113 /* initialize master volume */ 114 static int master_init(struct link_master *master) 115 { 116 struct link_slave *slave; 117 118 if (master->info.count) 119 return 0; /* already initialized */ 120 121 list_for_each_entry(slave, &master->slaves, list) { 122 int err = slave_init(slave); 123 if (err < 0) 124 return err; 125 master->info = slave->info; 126 master->info.count = 1; /* always mono */ 127 /* set full volume as default (= no attenuation) */ 128 master->val = master->info.max_val; 129 return 0; 130 } 131 return -ENOENT; 132 } 133 134 static int slave_get_val(struct link_slave *slave, 135 struct snd_ctl_elem_value *ucontrol) 136 { 137 int err, ch; 138 139 err = slave_init(slave); 140 if (err < 0) 141 return err; 142 for (ch = 0; ch < slave->info.count; ch++) 143 ucontrol->value.integer.value[ch] = slave->vals[ch]; 144 return 0; 145 } 146 147 static int slave_put_val(struct link_slave *slave, 148 struct snd_ctl_elem_value *ucontrol) 149 { 150 int err, ch, vol; 151 152 err = master_init(slave->master); 153 if (err < 0) 154 return err; 155 156 switch (slave->info.type) { 157 case SNDRV_CTL_ELEM_TYPE_BOOLEAN: 158 for (ch = 0; ch < slave->info.count; ch++) 159 ucontrol->value.integer.value[ch] &= 160 !!slave->master->val; 161 break; 162 case SNDRV_CTL_ELEM_TYPE_INTEGER: 163 for (ch = 0; ch < slave->info.count; ch++) { 164 /* max master volume is supposed to be 0 dB */ 165 vol = ucontrol->value.integer.value[ch]; 166 vol += slave->master->val - slave->master->info.max_val; 167 if (vol < slave->info.min_val) 168 vol = slave->info.min_val; 169 else if (vol > slave->info.max_val) 170 vol = slave->info.max_val; 171 ucontrol->value.integer.value[ch] = vol; 172 } 173 break; 174 } 175 return slave->slave.put(&slave->slave, ucontrol); 176 } 177 178 /* 179 * ctl callbacks for slaves 180 */ 181 static int slave_info(struct snd_kcontrol *kcontrol, 182 struct snd_ctl_elem_info *uinfo) 183 { 184 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 185 return slave->slave.info(&slave->slave, uinfo); 186 } 187 188 static int slave_get(struct snd_kcontrol *kcontrol, 189 struct snd_ctl_elem_value *ucontrol) 190 { 191 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 192 return slave_get_val(slave, ucontrol); 193 } 194 195 static int slave_put(struct snd_kcontrol *kcontrol, 196 struct snd_ctl_elem_value *ucontrol) 197 { 198 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 199 int err, ch, changed = 0; 200 201 err = slave_init(slave); 202 if (err < 0) 203 return err; 204 for (ch = 0; ch < slave->info.count; ch++) { 205 if (slave->vals[ch] != ucontrol->value.integer.value[ch]) { 206 changed = 1; 207 slave->vals[ch] = ucontrol->value.integer.value[ch]; 208 } 209 } 210 if (!changed) 211 return 0; 212 return slave_put_val(slave, ucontrol); 213 } 214 215 static int slave_tlv_cmd(struct snd_kcontrol *kcontrol, 216 int op_flag, unsigned int size, 217 unsigned int __user *tlv) 218 { 219 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 220 /* FIXME: this assumes that the max volume is 0 dB */ 221 return slave->slave.tlv.c(&slave->slave, op_flag, size, tlv); 222 } 223 224 static void slave_free(struct snd_kcontrol *kcontrol) 225 { 226 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 227 if (slave->slave.private_free) 228 slave->slave.private_free(&slave->slave); 229 if (slave->master) 230 list_del(&slave->list); 231 kfree(slave); 232 } 233 234 /* 235 * Add a slave control to the group with the given master control 236 * 237 * All slaves must be the same type (returning the same information 238 * via info callback). The function doesn't check it, so it's your 239 * responsibility. 240 * 241 * Also, some additional limitations: 242 * - at most two channels 243 * - logarithmic volume control (dB level), no linear volume 244 * - master can only attenuate the volume, no gain 245 */ 246 int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, 247 unsigned int flags) 248 { 249 struct link_master *master_link = snd_kcontrol_chip(master); 250 struct link_slave *srec; 251 252 srec = kzalloc(sizeof(*srec) + 253 slave->count * sizeof(*slave->vd), GFP_KERNEL); 254 if (!srec) 255 return -ENOMEM; 256 srec->kctl = slave; 257 srec->slave = *slave; 258 memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); 259 srec->master = master_link; 260 srec->flags = flags; 261 262 /* override callbacks */ 263 slave->info = slave_info; 264 slave->get = slave_get; 265 slave->put = slave_put; 266 if (slave->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) 267 slave->tlv.c = slave_tlv_cmd; 268 slave->private_data = srec; 269 slave->private_free = slave_free; 270 271 list_add_tail(&srec->list, &master_link->slaves); 272 return 0; 273 } 274 EXPORT_SYMBOL(_snd_ctl_add_slave); 275 276 /* 277 * ctl callbacks for master controls 278 */ 279 static int master_info(struct snd_kcontrol *kcontrol, 280 struct snd_ctl_elem_info *uinfo) 281 { 282 struct link_master *master = snd_kcontrol_chip(kcontrol); 283 int ret; 284 285 ret = master_init(master); 286 if (ret < 0) 287 return ret; 288 uinfo->type = master->info.type; 289 uinfo->count = master->info.count; 290 uinfo->value.integer.min = master->info.min_val; 291 uinfo->value.integer.max = master->info.max_val; 292 return 0; 293 } 294 295 static int master_get(struct snd_kcontrol *kcontrol, 296 struct snd_ctl_elem_value *ucontrol) 297 { 298 struct link_master *master = snd_kcontrol_chip(kcontrol); 299 int err = master_init(master); 300 if (err < 0) 301 return err; 302 ucontrol->value.integer.value[0] = master->val; 303 return 0; 304 } 305 306 static int master_put(struct snd_kcontrol *kcontrol, 307 struct snd_ctl_elem_value *ucontrol) 308 { 309 struct link_master *master = snd_kcontrol_chip(kcontrol); 310 struct link_slave *slave; 311 struct snd_ctl_elem_value *uval; 312 int err, old_val; 313 314 err = master_init(master); 315 if (err < 0) 316 return err; 317 old_val = master->val; 318 if (ucontrol->value.integer.value[0] == old_val) 319 return 0; 320 321 uval = kmalloc(sizeof(*uval), GFP_KERNEL); 322 if (!uval) 323 return -ENOMEM; 324 list_for_each_entry(slave, &master->slaves, list) { 325 master->val = old_val; 326 uval->id = slave->slave.id; 327 slave_get_val(slave, uval); 328 master->val = ucontrol->value.integer.value[0]; 329 slave_put_val(slave, uval); 330 } 331 kfree(uval); 332 return 1; 333 } 334 335 static void master_free(struct snd_kcontrol *kcontrol) 336 { 337 struct link_master *master = snd_kcontrol_chip(kcontrol); 338 struct link_slave *slave, *n; 339 340 /* free all slave links and retore the original slave kctls */ 341 list_for_each_entry_safe(slave, n, &master->slaves, list) { 342 struct snd_kcontrol *sctl = slave->kctl; 343 struct list_head olist = sctl->list; 344 memcpy(sctl, &slave->slave, sizeof(*sctl)); 345 memcpy(sctl->vd, slave->slave.vd, 346 sctl->count * sizeof(*sctl->vd)); 347 sctl->list = olist; /* keep the current linked-list */ 348 kfree(slave); 349 } 350 kfree(master); 351 } 352 353 354 /** 355 * snd_ctl_make_virtual_master - Create a virtual master control 356 * @name: name string of the control element to create 357 * @tlv: optional TLV int array for dB information 358 * 359 * Creates a virtual matster control with the given name string. 360 * Returns the created control element, or NULL for errors (ENOMEM). 361 * 362 * After creating a vmaster element, you can add the slave controls 363 * via snd_ctl_add_slave() or snd_ctl_add_slave_uncached(). 364 * 365 * The optional argument @tlv can be used to specify the TLV information 366 * for dB scale of the master control. It should be a single element 367 * with #SNDRV_CTL_TLVT_DB_SCALE, #SNDRV_CTL_TLV_DB_MINMAX or 368 * #SNDRV_CTL_TLVT_DB_MINMAX_MUTE type, and should be the max 0dB. 369 */ 370 struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, 371 const unsigned int *tlv) 372 { 373 struct link_master *master; 374 struct snd_kcontrol *kctl; 375 struct snd_kcontrol_new knew; 376 377 memset(&knew, 0, sizeof(knew)); 378 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 379 knew.name = name; 380 knew.info = master_info; 381 382 master = kzalloc(sizeof(*master), GFP_KERNEL); 383 if (!master) 384 return NULL; 385 INIT_LIST_HEAD(&master->slaves); 386 387 kctl = snd_ctl_new1(&knew, master); 388 if (!kctl) { 389 kfree(master); 390 return NULL; 391 } 392 /* override some callbacks */ 393 kctl->info = master_info; 394 kctl->get = master_get; 395 kctl->put = master_put; 396 kctl->private_free = master_free; 397 398 /* additional (constant) TLV read */ 399 if (tlv && 400 (tlv[0] == SNDRV_CTL_TLVT_DB_SCALE || 401 tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX || 402 tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX_MUTE)) { 403 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 404 memcpy(master->tlv, tlv, sizeof(master->tlv)); 405 kctl->tlv.p = master->tlv; 406 } 407 408 return kctl; 409 } 410 EXPORT_SYMBOL(snd_ctl_make_virtual_master); 411