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