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 void (*hook)(void *private_data, int); 41 void *hook_private_data; 42 }; 43 44 /* 45 * link slave - this contains a slave control element 46 * 47 * It fakes the control callbacsk with additional attenuation by the 48 * master control. A slave may have either one or two channels. 49 */ 50 51 struct link_slave { 52 struct list_head list; 53 struct link_master *master; 54 struct link_ctl_info info; 55 int vals[2]; /* current values */ 56 unsigned int flags; 57 struct snd_kcontrol *kctl; /* original kcontrol pointer */ 58 struct snd_kcontrol slave; /* the copy of original control entry */ 59 }; 60 61 static int slave_update(struct link_slave *slave) 62 { 63 struct snd_ctl_elem_value *uctl; 64 int err, ch; 65 66 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); 67 if (!uctl) 68 return -ENOMEM; 69 uctl->id = slave->slave.id; 70 err = slave->slave.get(&slave->slave, uctl); 71 if (err < 0) 72 goto error; 73 for (ch = 0; ch < slave->info.count; ch++) 74 slave->vals[ch] = uctl->value.integer.value[ch]; 75 error: 76 kfree(uctl); 77 return err < 0 ? err : 0; 78 } 79 80 /* get the slave ctl info and save the initial values */ 81 static int slave_init(struct link_slave *slave) 82 { 83 struct snd_ctl_elem_info *uinfo; 84 int err; 85 86 if (slave->info.count) { 87 /* already initialized */ 88 if (slave->flags & SND_CTL_SLAVE_NEED_UPDATE) 89 return slave_update(slave); 90 return 0; 91 } 92 93 uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL); 94 if (!uinfo) 95 return -ENOMEM; 96 uinfo->id = slave->slave.id; 97 err = slave->slave.info(&slave->slave, uinfo); 98 if (err < 0) { 99 kfree(uinfo); 100 return err; 101 } 102 slave->info.type = uinfo->type; 103 slave->info.count = uinfo->count; 104 if (slave->info.count > 2 || 105 (slave->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER && 106 slave->info.type != SNDRV_CTL_ELEM_TYPE_BOOLEAN)) { 107 pr_err("ALSA: vmaster: invalid slave element\n"); 108 kfree(uinfo); 109 return -EINVAL; 110 } 111 slave->info.min_val = uinfo->value.integer.min; 112 slave->info.max_val = uinfo->value.integer.max; 113 kfree(uinfo); 114 115 return slave_update(slave); 116 } 117 118 /* initialize master volume */ 119 static int master_init(struct link_master *master) 120 { 121 struct link_slave *slave; 122 123 if (master->info.count) 124 return 0; /* already initialized */ 125 126 list_for_each_entry(slave, &master->slaves, list) { 127 int err = slave_init(slave); 128 if (err < 0) 129 return err; 130 master->info = slave->info; 131 master->info.count = 1; /* always mono */ 132 /* set full volume as default (= no attenuation) */ 133 master->val = master->info.max_val; 134 if (master->hook) 135 master->hook(master->hook_private_data, master->val); 136 return 1; 137 } 138 return -ENOENT; 139 } 140 141 static int slave_get_val(struct link_slave *slave, 142 struct snd_ctl_elem_value *ucontrol) 143 { 144 int err, ch; 145 146 err = slave_init(slave); 147 if (err < 0) 148 return err; 149 for (ch = 0; ch < slave->info.count; ch++) 150 ucontrol->value.integer.value[ch] = slave->vals[ch]; 151 return 0; 152 } 153 154 static int slave_put_val(struct link_slave *slave, 155 struct snd_ctl_elem_value *ucontrol) 156 { 157 int err, ch, vol; 158 159 err = master_init(slave->master); 160 if (err < 0) 161 return err; 162 163 switch (slave->info.type) { 164 case SNDRV_CTL_ELEM_TYPE_BOOLEAN: 165 for (ch = 0; ch < slave->info.count; ch++) 166 ucontrol->value.integer.value[ch] &= 167 !!slave->master->val; 168 break; 169 case SNDRV_CTL_ELEM_TYPE_INTEGER: 170 for (ch = 0; ch < slave->info.count; ch++) { 171 /* max master volume is supposed to be 0 dB */ 172 vol = ucontrol->value.integer.value[ch]; 173 vol += slave->master->val - slave->master->info.max_val; 174 if (vol < slave->info.min_val) 175 vol = slave->info.min_val; 176 else if (vol > slave->info.max_val) 177 vol = slave->info.max_val; 178 ucontrol->value.integer.value[ch] = vol; 179 } 180 break; 181 } 182 return slave->slave.put(&slave->slave, ucontrol); 183 } 184 185 /* 186 * ctl callbacks for slaves 187 */ 188 static int slave_info(struct snd_kcontrol *kcontrol, 189 struct snd_ctl_elem_info *uinfo) 190 { 191 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 192 return slave->slave.info(&slave->slave, uinfo); 193 } 194 195 static int slave_get(struct snd_kcontrol *kcontrol, 196 struct snd_ctl_elem_value *ucontrol) 197 { 198 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 199 return slave_get_val(slave, ucontrol); 200 } 201 202 static int slave_put(struct snd_kcontrol *kcontrol, 203 struct snd_ctl_elem_value *ucontrol) 204 { 205 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 206 int err, ch, changed = 0; 207 208 err = slave_init(slave); 209 if (err < 0) 210 return err; 211 for (ch = 0; ch < slave->info.count; ch++) { 212 if (slave->vals[ch] != ucontrol->value.integer.value[ch]) { 213 changed = 1; 214 slave->vals[ch] = ucontrol->value.integer.value[ch]; 215 } 216 } 217 if (!changed) 218 return 0; 219 err = slave_put_val(slave, ucontrol); 220 if (err < 0) 221 return err; 222 return 1; 223 } 224 225 static int slave_tlv_cmd(struct snd_kcontrol *kcontrol, 226 int op_flag, unsigned int size, 227 unsigned int __user *tlv) 228 { 229 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 230 /* FIXME: this assumes that the max volume is 0 dB */ 231 return slave->slave.tlv.c(&slave->slave, op_flag, size, tlv); 232 } 233 234 static void slave_free(struct snd_kcontrol *kcontrol) 235 { 236 struct link_slave *slave = snd_kcontrol_chip(kcontrol); 237 if (slave->slave.private_free) 238 slave->slave.private_free(&slave->slave); 239 if (slave->master) 240 list_del(&slave->list); 241 kfree(slave); 242 } 243 244 /* 245 * Add a slave control to the group with the given master control 246 * 247 * All slaves must be the same type (returning the same information 248 * via info callback). The function doesn't check it, so it's your 249 * responsibility. 250 * 251 * Also, some additional limitations: 252 * - at most two channels 253 * - logarithmic volume control (dB level), no linear volume 254 * - master can only attenuate the volume, no gain 255 */ 256 int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, 257 unsigned int flags) 258 { 259 struct link_master *master_link = snd_kcontrol_chip(master); 260 struct link_slave *srec; 261 262 srec = kzalloc(struct_size(srec, slave.vd, slave->count), 263 GFP_KERNEL); 264 if (!srec) 265 return -ENOMEM; 266 srec->kctl = slave; 267 srec->slave = *slave; 268 memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); 269 srec->master = master_link; 270 srec->flags = flags; 271 272 /* override callbacks */ 273 slave->info = slave_info; 274 slave->get = slave_get; 275 slave->put = slave_put; 276 if (slave->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) 277 slave->tlv.c = slave_tlv_cmd; 278 slave->private_data = srec; 279 slave->private_free = slave_free; 280 281 list_add_tail(&srec->list, &master_link->slaves); 282 return 0; 283 } 284 EXPORT_SYMBOL(_snd_ctl_add_slave); 285 286 /* 287 * ctl callbacks for master controls 288 */ 289 static int master_info(struct snd_kcontrol *kcontrol, 290 struct snd_ctl_elem_info *uinfo) 291 { 292 struct link_master *master = snd_kcontrol_chip(kcontrol); 293 int ret; 294 295 ret = master_init(master); 296 if (ret < 0) 297 return ret; 298 uinfo->type = master->info.type; 299 uinfo->count = master->info.count; 300 uinfo->value.integer.min = master->info.min_val; 301 uinfo->value.integer.max = master->info.max_val; 302 return 0; 303 } 304 305 static int master_get(struct snd_kcontrol *kcontrol, 306 struct snd_ctl_elem_value *ucontrol) 307 { 308 struct link_master *master = snd_kcontrol_chip(kcontrol); 309 int err = master_init(master); 310 if (err < 0) 311 return err; 312 ucontrol->value.integer.value[0] = master->val; 313 return 0; 314 } 315 316 static int sync_slaves(struct link_master *master, int old_val, int new_val) 317 { 318 struct link_slave *slave; 319 struct snd_ctl_elem_value *uval; 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 = new_val; 329 slave_put_val(slave, uval); 330 } 331 kfree(uval); 332 return 0; 333 } 334 335 static int master_put(struct snd_kcontrol *kcontrol, 336 struct snd_ctl_elem_value *ucontrol) 337 { 338 struct link_master *master = snd_kcontrol_chip(kcontrol); 339 int err, new_val, old_val; 340 bool first_init; 341 342 err = master_init(master); 343 if (err < 0) 344 return err; 345 first_init = err; 346 old_val = master->val; 347 new_val = ucontrol->value.integer.value[0]; 348 if (new_val == old_val) 349 return 0; 350 351 err = sync_slaves(master, old_val, new_val); 352 if (err < 0) 353 return err; 354 if (master->hook && !first_init) 355 master->hook(master->hook_private_data, master->val); 356 return 1; 357 } 358 359 static void master_free(struct snd_kcontrol *kcontrol) 360 { 361 struct link_master *master = snd_kcontrol_chip(kcontrol); 362 struct link_slave *slave, *n; 363 364 /* free all slave links and retore the original slave kctls */ 365 list_for_each_entry_safe(slave, n, &master->slaves, list) { 366 struct snd_kcontrol *sctl = slave->kctl; 367 struct list_head olist = sctl->list; 368 memcpy(sctl, &slave->slave, sizeof(*sctl)); 369 memcpy(sctl->vd, slave->slave.vd, 370 sctl->count * sizeof(*sctl->vd)); 371 sctl->list = olist; /* keep the current linked-list */ 372 kfree(slave); 373 } 374 kfree(master); 375 } 376 377 378 /** 379 * snd_ctl_make_virtual_master - Create a virtual master control 380 * @name: name string of the control element to create 381 * @tlv: optional TLV int array for dB information 382 * 383 * Creates a virtual master control with the given name string. 384 * 385 * After creating a vmaster element, you can add the slave controls 386 * via snd_ctl_add_slave() or snd_ctl_add_slave_uncached(). 387 * 388 * The optional argument @tlv can be used to specify the TLV information 389 * for dB scale of the master control. It should be a single element 390 * with #SNDRV_CTL_TLVT_DB_SCALE, #SNDRV_CTL_TLV_DB_MINMAX or 391 * #SNDRV_CTL_TLVT_DB_MINMAX_MUTE type, and should be the max 0dB. 392 * 393 * Return: The created control element, or %NULL for errors (ENOMEM). 394 */ 395 struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, 396 const unsigned int *tlv) 397 { 398 struct link_master *master; 399 struct snd_kcontrol *kctl; 400 struct snd_kcontrol_new knew; 401 402 memset(&knew, 0, sizeof(knew)); 403 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 404 knew.name = name; 405 knew.info = master_info; 406 407 master = kzalloc(sizeof(*master), GFP_KERNEL); 408 if (!master) 409 return NULL; 410 INIT_LIST_HEAD(&master->slaves); 411 412 kctl = snd_ctl_new1(&knew, master); 413 if (!kctl) { 414 kfree(master); 415 return NULL; 416 } 417 /* override some callbacks */ 418 kctl->info = master_info; 419 kctl->get = master_get; 420 kctl->put = master_put; 421 kctl->private_free = master_free; 422 423 /* additional (constant) TLV read */ 424 if (tlv) { 425 unsigned int type = tlv[SNDRV_CTL_TLVO_TYPE]; 426 if (type == SNDRV_CTL_TLVT_DB_SCALE || 427 type == SNDRV_CTL_TLVT_DB_MINMAX || 428 type == SNDRV_CTL_TLVT_DB_MINMAX_MUTE) { 429 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 430 memcpy(master->tlv, tlv, sizeof(master->tlv)); 431 kctl->tlv.p = master->tlv; 432 } 433 } 434 435 return kctl; 436 } 437 EXPORT_SYMBOL(snd_ctl_make_virtual_master); 438 439 /** 440 * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control 441 * @kcontrol: vmaster kctl element 442 * @hook: the hook function 443 * @private_data: the private_data pointer to be saved 444 * 445 * Adds the given hook to the vmaster control element so that it's called 446 * at each time when the value is changed. 447 * 448 * Return: Zero. 449 */ 450 int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol, 451 void (*hook)(void *private_data, int), 452 void *private_data) 453 { 454 struct link_master *master = snd_kcontrol_chip(kcontrol); 455 master->hook = hook; 456 master->hook_private_data = private_data; 457 return 0; 458 } 459 EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook); 460 461 /** 462 * snd_ctl_sync_vmaster - Sync the vmaster slaves and hook 463 * @kcontrol: vmaster kctl element 464 * @hook_only: sync only the hook 465 * 466 * Forcibly call the put callback of each slave and call the hook function 467 * to synchronize with the current value of the given vmaster element. 468 * NOP when NULL is passed to @kcontrol. 469 */ 470 void snd_ctl_sync_vmaster(struct snd_kcontrol *kcontrol, bool hook_only) 471 { 472 struct link_master *master; 473 bool first_init = false; 474 475 if (!kcontrol) 476 return; 477 master = snd_kcontrol_chip(kcontrol); 478 if (!hook_only) { 479 int err = master_init(master); 480 if (err < 0) 481 return; 482 first_init = err; 483 err = sync_slaves(master, master->val, master->val); 484 if (err < 0) 485 return; 486 } 487 488 if (master->hook && !first_init) 489 master->hook(master->hook_private_data, master->val); 490 } 491 EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster); 492 493 /** 494 * snd_ctl_apply_vmaster_slaves - Apply function to each vmaster slave 495 * @kctl: vmaster kctl element 496 * @func: function to apply 497 * @arg: optional function argument 498 * 499 * Apply the function @func to each slave kctl of the given vmaster kctl. 500 * Returns 0 if successful, or a negative error code. 501 */ 502 int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, 503 int (*func)(struct snd_kcontrol *vslave, 504 struct snd_kcontrol *slave, 505 void *arg), 506 void *arg) 507 { 508 struct link_master *master; 509 struct link_slave *slave; 510 int err; 511 512 master = snd_kcontrol_chip(kctl); 513 err = master_init(master); 514 if (err < 0) 515 return err; 516 list_for_each_entry(slave, &master->slaves, list) { 517 err = func(slave->kctl, &slave->slave, arg); 518 if (err < 0) 519 return err; 520 } 521 522 return 0; 523 } 524 EXPORT_SYMBOL_GPL(snd_ctl_apply_vmaster_slaves); 525