1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #include <alsa/asoundlib.h> 7 #include <limits.h> 8 #include <stdio.h> 9 #include <syslog.h> 10 11 #include "cras_alsa_mixer.h" 12 #include "cras_alsa_mixer_name.h" 13 #include "cras_alsa_ucm.h" 14 #include "cras_util.h" 15 #include "utlist.h" 16 17 #define MIXER_CONTROL_VOLUME_DB_INVALID LONG_MAX 18 19 /* Represents an ALSA control element. Each device can have several of these, 20 * each potentially having independent volume and mute controls. 21 * elem - ALSA mixer element. 22 * has_volume - non-zero indicates there is a volume control. 23 * has_mute - non-zero indicates there is a mute switch. 24 * max_volume_dB - the maximum volume for this control, or 25 * MIXER_CONTROL_VOLUME_DB_INVALID. 26 * min_volume_dB - the minimum volume for this control, or 27 * MIXER_CONTROL_VOLUME_DB_INVALID. 28 */ 29 struct mixer_control_element { 30 snd_mixer_elem_t *elem; 31 int has_volume; 32 int has_mute; 33 long max_volume_dB; 34 long min_volume_dB; 35 struct mixer_control_element *prev, *next; 36 }; 37 38 /* Represents an ALSA control element related to a specific input/output 39 * node such as speakers or headphones. A device can have several of these, 40 * each potentially having independent volume and mute controls. 41 * 42 * Each will have at least one mixer_control_element. For cases where there 43 * are separate control elements for left/right channels (for example), 44 * additional mixer_control_elements are added. 45 * 46 * For controls with volume it is assumed that all elements have the same 47 * range. 48 * 49 * name - Name of the control (typicially this is the same as the name of the 50 * mixer_control_element when there is one, or the name of the UCM 51 * parent when there are multiple). 52 * dir - Control direction, OUTPUT or INPUT only. 53 * elements - The mixer_control_elements that are driven by this control. 54 * has_volume - non-zero indicates there is a volume control. 55 * has_mute - non-zero indicates there is a mute switch. 56 * max_volume_dB - Maximum volume available in the volume control. 57 * min_volume_dB - Minimum volume available in the volume control. 58 */ 59 struct mixer_control { 60 const char *name; 61 enum CRAS_STREAM_DIRECTION dir; 62 struct mixer_control_element *elements; 63 int has_volume; 64 int has_mute; 65 long max_volume_dB; 66 long min_volume_dB; 67 struct mixer_control *prev, *next; 68 }; 69 70 /* Holds a reference to the opened mixer and the volume controls. 71 * mixer - Pointer to the opened alsa mixer. 72 * main_volume_controls - List of volume controls (normally 'Master' and 'PCM'). 73 * playback_switch - Switch used to mute the device. 74 * main_capture_controls - List of capture gain controls (normally 'Capture'). 75 * capture_switch - Switch used to mute the capture stream. 76 * max_volume_dB - Maximum volume available in main volume controls. The dBFS 77 * value setting will be applied relative to this. 78 * min_volume_dB - Minimum volume available in main volume controls. 79 */ 80 struct cras_alsa_mixer { 81 snd_mixer_t *mixer; 82 struct mixer_control *main_volume_controls; 83 struct mixer_control *output_controls; 84 snd_mixer_elem_t *playback_switch; 85 struct mixer_control *main_capture_controls; 86 struct mixer_control *input_controls; 87 snd_mixer_elem_t *capture_switch; 88 long max_volume_dB; 89 long min_volume_dB; 90 }; 91 92 /* Wrapper for snd_mixer_open and helpers. 93 * Args: 94 * mixdev - Name of the device to open the mixer for. 95 * mixer - Pointer filled with the opened mixer on success, NULL on failure. 96 */ 97 static void alsa_mixer_open(const char *mixdev, 98 snd_mixer_t **mixer) 99 { 100 int rc; 101 102 *mixer = NULL; 103 rc = snd_mixer_open(mixer, 0); 104 if (rc < 0) { 105 syslog(LOG_ERR, "snd_mixer_open: %d: %s", rc, strerror(-rc)); 106 return; 107 } 108 rc = snd_mixer_attach(*mixer, mixdev); 109 if (rc < 0) { 110 syslog(LOG_ERR, "snd_mixer_attach: %d: %s", rc, strerror(-rc)); 111 goto fail_after_open; 112 } 113 rc = snd_mixer_selem_register(*mixer, NULL, NULL); 114 if (rc < 0) { 115 syslog(LOG_ERR, "snd_mixer_selem_register: %d: %s", rc, strerror(-rc)); 116 goto fail_after_open; 117 } 118 rc = snd_mixer_load(*mixer); 119 if (rc < 0) { 120 syslog(LOG_ERR, "snd_mixer_load: %d: %s", rc, strerror(-rc)); 121 goto fail_after_open; 122 } 123 return; 124 125 fail_after_open: 126 snd_mixer_close(*mixer); 127 *mixer = NULL; 128 } 129 130 static struct mixer_control_element *mixer_control_element_create( 131 snd_mixer_elem_t *elem, 132 enum CRAS_STREAM_DIRECTION dir) 133 { 134 struct mixer_control_element *c; 135 long min, max; 136 137 if (!elem) 138 return NULL; 139 140 c = (struct mixer_control_element *)calloc(1, sizeof(*c)); 141 if (!c) { 142 syslog(LOG_ERR, "No memory for mixer_control_elem."); 143 return NULL; 144 } 145 146 c->elem = elem; 147 c->max_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID; 148 c->min_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID; 149 150 if (dir == CRAS_STREAM_OUTPUT) { 151 c->has_mute = snd_mixer_selem_has_playback_switch(elem); 152 153 if (snd_mixer_selem_has_playback_volume(elem) && 154 snd_mixer_selem_get_playback_dB_range( 155 elem, &min, &max) == 0) { 156 c->max_volume_dB = max; 157 c->min_volume_dB = min; 158 c->has_volume = 1; 159 } 160 } 161 else if (dir == CRAS_STREAM_INPUT) { 162 c->has_mute = snd_mixer_selem_has_capture_switch(elem); 163 164 if (snd_mixer_selem_has_capture_volume(elem) && 165 snd_mixer_selem_get_capture_dB_range( 166 elem, &min, &max) == 0) { 167 c->max_volume_dB = max; 168 c->min_volume_dB = min; 169 c->has_volume = 1; 170 } 171 } 172 173 return c; 174 } 175 176 static void mixer_control_destroy(struct mixer_control *control) { 177 struct mixer_control_element *elem; 178 179 if (!control) 180 return; 181 182 DL_FOREACH(control->elements, elem) { 183 DL_DELETE(control->elements, elem); 184 free(elem); 185 } 186 if (control->name) 187 free((void *)control->name); 188 free(control); 189 } 190 191 static void mixer_control_destroy_list(struct mixer_control *control_list) 192 { 193 struct mixer_control *control; 194 if (!control_list) 195 return; 196 DL_FOREACH(control_list, control) { 197 DL_DELETE(control_list, control); 198 mixer_control_destroy(control); 199 } 200 } 201 202 static int mixer_control_add_element(struct mixer_control *control, 203 snd_mixer_elem_t *snd_elem) 204 { 205 struct mixer_control_element *elem; 206 207 if (!control) 208 return -EINVAL; 209 210 elem = mixer_control_element_create(snd_elem, control->dir); 211 if (!elem) 212 return -ENOMEM; 213 214 DL_APPEND(control->elements, elem); 215 216 if (elem->has_volume) { 217 if (!control->has_volume) 218 control->has_volume = 1; 219 220 /* Assume that all elements have a common volume range, and 221 * that both min and max values are valid if one of the two 222 * is valid. */ 223 if (control->min_volume_dB == 224 MIXER_CONTROL_VOLUME_DB_INVALID) { 225 control->min_volume_dB = elem->min_volume_dB; 226 control->max_volume_dB = elem->max_volume_dB; 227 } else if (control->min_volume_dB != elem->min_volume_dB || 228 control->max_volume_dB != elem->max_volume_dB) { 229 syslog(LOG_WARNING, 230 "Element '%s' of control '%s' has different" 231 "volume range: [%ld:%ld] ctrl: [%ld:%ld]", 232 snd_mixer_selem_get_name(elem->elem), 233 control->name, 234 elem->min_volume_dB, elem->max_volume_dB, 235 control->min_volume_dB, control->max_volume_dB); 236 } 237 } 238 239 if (elem->has_mute && !control->has_mute) 240 control->has_mute = 1; 241 return 0; 242 } 243 244 static int mixer_control_create(struct mixer_control **control, 245 const char *name, 246 snd_mixer_elem_t *elem, 247 enum CRAS_STREAM_DIRECTION dir) 248 { 249 struct mixer_control *c; 250 int rc = 0; 251 252 if (!control) 253 return -EINVAL; 254 255 c = (struct mixer_control *)calloc(1, sizeof(*c)); 256 if (!c) { 257 syslog(LOG_ERR, "No memory for mixer_control: %s", name); 258 rc = -ENOMEM; 259 goto error; 260 } 261 262 c->dir = dir; 263 c->min_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID; 264 c->max_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID; 265 266 if (!name && elem) 267 name = snd_mixer_selem_get_name(elem); 268 if (!name) { 269 syslog(LOG_ERR, "Control does not have a name."); 270 rc = -EINVAL; 271 goto error; 272 } 273 274 c->name = strdup(name); 275 if (!c->name) { 276 syslog(LOG_ERR, "No memory for control's name: %s", name); 277 rc = -ENOMEM; 278 goto error; 279 } 280 281 if (elem && (rc = mixer_control_add_element(c, elem))) 282 goto error; 283 284 *control = c; 285 return 0; 286 287 error: 288 mixer_control_destroy(c); 289 *control = NULL; 290 return rc; 291 } 292 293 /* Creates a mixer_control by finding mixer element names in simple mixer 294 * interface. 295 * Args: 296 * control[out] - Storage for resulting pointer to mixer_control. 297 * cmix[in] - Parent alsa mixer. 298 * name[in] - Optional name of the control. Input NULL to take the name of 299 * the first element from mixer_names. 300 * mixer_names[in] - Names of the ASLA mixer control elements. Must not 301 * be empty. 302 * dir[in] - Control direction: CRAS_STREAM_OUTPUT or CRAS_STREAM_INPUT. 303 * Returns: 304 * Returns 0 for success, negative error code otherwise. *control is 305 * initialized to NULL on error, or has a valid pointer for success. 306 */ 307 static int mixer_control_create_by_name( 308 struct mixer_control **control, 309 struct cras_alsa_mixer *cmix, 310 const char *name, 311 struct mixer_name *mixer_names, 312 enum CRAS_STREAM_DIRECTION dir) 313 { 314 snd_mixer_selem_id_t *sid; 315 snd_mixer_elem_t *elem; 316 struct mixer_control *c; 317 struct mixer_name *m_name; 318 int rc; 319 320 if (!control) 321 return -EINVAL; 322 *control = NULL; 323 if (!mixer_names) 324 return -EINVAL; 325 if (!name) { 326 /* Assume that we're using the first name in the list of mixer 327 * names. */ 328 name = mixer_names->name; 329 } 330 331 rc = mixer_control_create(&c, name, NULL, dir); 332 if (rc) 333 return rc; 334 335 snd_mixer_selem_id_malloc(&sid); 336 337 DL_FOREACH(mixer_names, m_name) { 338 snd_mixer_selem_id_set_index(sid, 0); 339 snd_mixer_selem_id_set_name(sid, m_name->name); 340 elem = snd_mixer_find_selem(cmix->mixer, sid); 341 if (!elem) { 342 mixer_control_destroy(c); 343 snd_mixer_selem_id_free(sid); 344 syslog(LOG_ERR, "Unable to find simple control %s, 0", 345 m_name->name); 346 return -ENOENT; 347 } 348 rc = mixer_control_add_element(c, elem); 349 if (rc) { 350 mixer_control_destroy(c); 351 snd_mixer_selem_id_free(sid); 352 return rc; 353 } 354 } 355 356 snd_mixer_selem_id_free(sid); 357 *control = c; 358 return 0; 359 } 360 361 static int mixer_control_set_dBFS( 362 const struct mixer_control *control, long to_set) 363 { 364 const struct mixer_control_element *elem = NULL; 365 int rc = -EINVAL; 366 if (!control) 367 return rc; 368 DL_FOREACH(control->elements, elem) { 369 if(elem->has_volume) { 370 if (control->dir == CRAS_STREAM_OUTPUT) 371 rc = snd_mixer_selem_set_playback_dB_all( 372 elem->elem, to_set, 1); 373 else if (control->dir == CRAS_STREAM_INPUT) 374 rc = snd_mixer_selem_set_capture_dB_all( 375 elem->elem, to_set, 1); 376 if (rc) 377 break; 378 syslog(LOG_DEBUG, "%s:%s volume set to %ld", 379 control->name, 380 snd_mixer_selem_get_name(elem->elem), 381 to_set); 382 } 383 } 384 if (rc && elem) { 385 syslog(LOG_ERR, "Failed to set volume of '%s:%s': %d", 386 control->name, 387 snd_mixer_selem_get_name(elem->elem), rc); 388 } 389 return rc; 390 } 391 392 static int mixer_control_get_dBFS( 393 const struct mixer_control *control, long *to_get) 394 { 395 const struct mixer_control_element *elem = NULL; 396 int rc = -EINVAL; 397 if (!control || !to_get) 398 return -EINVAL; 399 DL_FOREACH(control->elements, elem) { 400 if (elem->has_volume) { 401 if (control->dir == CRAS_STREAM_OUTPUT) 402 rc = snd_mixer_selem_get_playback_dB( 403 elem->elem, 404 SND_MIXER_SCHN_FRONT_LEFT, 405 to_get); 406 else if (control->dir == CRAS_STREAM_INPUT) 407 rc = snd_mixer_selem_get_capture_dB( 408 elem->elem, 409 SND_MIXER_SCHN_FRONT_LEFT, 410 to_get); 411 /* Assume all of the elements of this control have 412 * the same value. */ 413 break; 414 } 415 } 416 if (rc && elem) { 417 syslog(LOG_ERR, "Failed to get volume of '%s:%s': %d", 418 control->name, 419 snd_mixer_selem_get_name(elem->elem), rc); 420 } 421 return rc; 422 } 423 424 static int mixer_control_set_mute( 425 const struct mixer_control *control, int muted) 426 { 427 const struct mixer_control_element *elem = NULL; 428 int rc; 429 if (!control) 430 return -EINVAL; 431 DL_FOREACH(control->elements, elem) { 432 if(elem->has_mute) { 433 if (control->dir == CRAS_STREAM_OUTPUT) 434 rc = snd_mixer_selem_set_playback_switch_all( 435 elem->elem, !muted); 436 else if (control->dir == CRAS_STREAM_INPUT) 437 rc = snd_mixer_selem_set_capture_switch_all( 438 elem->elem, !muted); 439 if (rc) 440 break; 441 } 442 } 443 if (rc && elem) { 444 syslog(LOG_ERR, "Failed to mute '%s:%s': %d", 445 control->name, 446 snd_mixer_selem_get_name(elem->elem), rc); 447 } 448 return rc; 449 } 450 451 /* Adds the main volume control to the list and grabs the first seen playback 452 * switch to use for mute. */ 453 static int add_main_volume_control(struct cras_alsa_mixer *cmix, 454 snd_mixer_elem_t *elem) 455 { 456 if (snd_mixer_selem_has_playback_volume(elem)) { 457 long range; 458 struct mixer_control *c, *next; 459 int rc = mixer_control_create(&c, NULL, elem, CRAS_STREAM_OUTPUT); 460 if (rc) 461 return rc; 462 463 if (c->has_volume) { 464 cmix->max_volume_dB += c->max_volume_dB; 465 cmix->min_volume_dB += c->min_volume_dB; 466 } 467 468 range = c->max_volume_dB - c->min_volume_dB; 469 DL_FOREACH(cmix->main_volume_controls, next) { 470 if (range > next->max_volume_dB - next->min_volume_dB) 471 break; 472 } 473 474 syslog(LOG_DEBUG, "Add main volume control %s\n", c->name); 475 DL_INSERT(cmix->main_volume_controls, next, c); 476 } 477 478 /* If cmix doesn't yet have a playback switch and this is a playback 479 * switch, use it. */ 480 if (cmix->playback_switch == NULL && 481 snd_mixer_selem_has_playback_switch(elem)) { 482 syslog(LOG_DEBUG, "Using '%s' as playback switch.", 483 snd_mixer_selem_get_name(elem)); 484 cmix->playback_switch = elem; 485 } 486 487 return 0; 488 } 489 490 /* Adds the main capture control to the list and grabs the first seen capture 491 * switch to mute input. */ 492 static int add_main_capture_control(struct cras_alsa_mixer *cmix, 493 snd_mixer_elem_t *elem) 494 { 495 /* TODO(dgreid) handle index != 0, map to correct input. */ 496 if (snd_mixer_selem_get_index(elem) > 0) 497 return 0; 498 499 if (snd_mixer_selem_has_capture_volume(elem)) { 500 struct mixer_control *c; 501 int rc = mixer_control_create(&c, NULL, elem, CRAS_STREAM_INPUT); 502 if (rc) 503 return rc; 504 505 syslog(LOG_DEBUG, "Add main capture control %s\n", c->name); 506 DL_APPEND(cmix->main_capture_controls, c); 507 } 508 509 /* If cmix doesn't yet have a capture switch and this is a capture 510 * switch, use it. */ 511 if (cmix->capture_switch == NULL && 512 snd_mixer_selem_has_capture_switch(elem)) { 513 syslog(LOG_DEBUG, "Using '%s' as capture switch.", 514 snd_mixer_selem_get_name(elem)); 515 cmix->capture_switch = elem; 516 } 517 518 return 0; 519 } 520 521 /* Adds a control to the list. */ 522 static int add_control_with_name(struct cras_alsa_mixer *cmix, 523 enum CRAS_STREAM_DIRECTION dir, 524 snd_mixer_elem_t *elem, 525 const char *name) 526 { 527 int index; /* Index part of mixer simple element */ 528 struct mixer_control *c; 529 int rc; 530 531 index = snd_mixer_selem_get_index(elem); 532 syslog(LOG_DEBUG, "Add %s control: %s,%d\n", 533 dir == CRAS_STREAM_OUTPUT ? "output" : "input", 534 name, index); 535 536 rc = mixer_control_create(&c, name, elem, dir); 537 if (rc) 538 return rc; 539 540 if (c->has_volume) 541 syslog(LOG_DEBUG, "Control '%s' volume range: [%ld:%ld]", 542 c->name, c->min_volume_dB, c->max_volume_dB); 543 544 if (dir == CRAS_STREAM_OUTPUT) 545 DL_APPEND(cmix->output_controls, c); 546 else if (dir == CRAS_STREAM_INPUT) 547 DL_APPEND(cmix->input_controls, c); 548 return 0; 549 } 550 551 static int add_control(struct cras_alsa_mixer *cmix, 552 enum CRAS_STREAM_DIRECTION dir, 553 snd_mixer_elem_t *elem) 554 { 555 return add_control_with_name(cmix, dir, elem, 556 snd_mixer_selem_get_name(elem)); 557 } 558 559 static void list_controls(struct mixer_control *control_list, 560 cras_alsa_mixer_control_callback cb, 561 void *cb_arg) 562 { 563 struct mixer_control *control; 564 565 DL_FOREACH(control_list, control) 566 cb(control, cb_arg); 567 } 568 569 static struct mixer_control *get_control_matching_name( 570 struct mixer_control *control_list, 571 const char *name) 572 { 573 struct mixer_control *c; 574 575 DL_FOREACH(control_list, c) { 576 if (strstr(name, c->name)) 577 return c; 578 } 579 return NULL; 580 } 581 582 /* Creates a mixer_control with multiple control elements. */ 583 static int add_control_with_coupled_mixers( 584 struct cras_alsa_mixer *cmix, 585 enum CRAS_STREAM_DIRECTION dir, 586 const char *name, 587 struct mixer_name *coupled_controls) 588 { 589 struct mixer_control *c; 590 int rc; 591 592 rc = mixer_control_create_by_name( 593 &c, cmix, name, coupled_controls, dir); 594 if (rc) 595 return rc; 596 syslog(LOG_DEBUG, "Add %s control: %s\n", 597 dir == CRAS_STREAM_OUTPUT ? "output" : "input", 598 c->name); 599 mixer_name_dump(coupled_controls, " elements"); 600 601 if (c->has_volume) 602 syslog(LOG_DEBUG, "Control '%s' volume range: [%ld:%ld]", 603 c->name, c->min_volume_dB, c->max_volume_dB); 604 605 if (dir == CRAS_STREAM_OUTPUT) 606 DL_APPEND(cmix->output_controls, c); 607 else if (dir == CRAS_STREAM_INPUT) 608 DL_APPEND(cmix->input_controls, c); 609 return 0; 610 } 611 612 static int add_control_by_name(struct cras_alsa_mixer *cmix, 613 enum CRAS_STREAM_DIRECTION dir, 614 const char *name) 615 { 616 struct mixer_control *c; 617 struct mixer_name *m_name; 618 int rc; 619 620 m_name = mixer_name_add(NULL, name, dir, MIXER_NAME_VOLUME); 621 if (!m_name) 622 return -ENOMEM; 623 624 rc = mixer_control_create_by_name(&c, cmix, name, m_name, dir); 625 mixer_name_free(m_name); 626 if (rc) 627 return rc; 628 syslog(LOG_DEBUG, "Add %s control: %s\n", 629 dir == CRAS_STREAM_OUTPUT ? "output" : "input", 630 c->name); 631 632 if (c->has_volume) 633 syslog(LOG_DEBUG, "Control '%s' volume range: [%ld:%ld]", 634 c->name, c->min_volume_dB, c->max_volume_dB); 635 636 if (dir == CRAS_STREAM_OUTPUT) 637 DL_APPEND(cmix->output_controls, c); 638 else if (dir == CRAS_STREAM_INPUT) 639 DL_APPEND(cmix->input_controls, c); 640 return 0; 641 } 642 643 /* 644 * Exported interface. 645 */ 646 647 struct cras_alsa_mixer *cras_alsa_mixer_create(const char *card_name) 648 { 649 struct cras_alsa_mixer *cmix; 650 651 cmix = (struct cras_alsa_mixer *)calloc(1, sizeof(*cmix)); 652 if (cmix == NULL) 653 return NULL; 654 655 syslog(LOG_DEBUG, "Add mixer for device %s", card_name); 656 657 alsa_mixer_open(card_name, &cmix->mixer); 658 659 return cmix; 660 } 661 662 int cras_alsa_mixer_add_controls_by_name_matching( 663 struct cras_alsa_mixer *cmix, 664 struct mixer_name *extra_controls, 665 struct mixer_name *coupled_controls) 666 { 667 /* Names of controls for main system volume. */ 668 static const char * const main_volume_names[] = { 669 "Master", 670 "Digital", 671 "PCM", 672 }; 673 /* Names of controls for individual outputs. */ 674 static const char * const output_names[] = { 675 "Headphone", 676 "Headset", 677 "HDMI", 678 "Speaker", 679 }; 680 /* Names of controls for capture gain/attenuation and mute. */ 681 static const char * const main_capture_names[] = { 682 "Capture", 683 "Digital Capture", 684 }; 685 /* Names of controls for individual inputs. */ 686 static const char * const input_names[] = { 687 "Mic", 688 "Microphone", 689 }; 690 691 struct mixer_name *default_controls = NULL; 692 snd_mixer_elem_t *elem; 693 int extra_main_volume = 0; 694 snd_mixer_elem_t *other_elem = NULL; 695 long other_dB_range = 0; 696 int rc = 0; 697 698 /* Note that there is no mixer on some cards. This is acceptable. */ 699 if (cmix->mixer == NULL) { 700 syslog(LOG_DEBUG, "Couldn't open mixer."); 701 return 0; 702 } 703 704 default_controls = mixer_name_add_array(default_controls, 705 output_names, ARRAY_SIZE(output_names), 706 CRAS_STREAM_OUTPUT, MIXER_NAME_VOLUME); 707 default_controls = mixer_name_add_array(default_controls, 708 input_names, ARRAY_SIZE(input_names), 709 CRAS_STREAM_INPUT, MIXER_NAME_VOLUME); 710 default_controls = 711 mixer_name_add_array(default_controls, 712 main_volume_names, ARRAY_SIZE(main_volume_names), 713 CRAS_STREAM_OUTPUT, MIXER_NAME_MAIN_VOLUME); 714 default_controls = 715 mixer_name_add_array(default_controls, 716 main_capture_names, ARRAY_SIZE(main_capture_names), 717 CRAS_STREAM_INPUT, MIXER_NAME_MAIN_VOLUME); 718 extra_main_volume = 719 mixer_name_find(extra_controls, NULL, 720 CRAS_STREAM_OUTPUT, 721 MIXER_NAME_MAIN_VOLUME) != NULL; 722 723 /* Find volume and mute controls. */ 724 for(elem = snd_mixer_first_elem(cmix->mixer); 725 elem != NULL; elem = snd_mixer_elem_next(elem)) { 726 const char *name; 727 struct mixer_name *control; 728 int found = 0; 729 730 name = snd_mixer_selem_get_name(elem); 731 if (name == NULL) 732 continue; 733 734 /* Find a matching control. */ 735 control = mixer_name_find(default_controls, name, 736 CRAS_STREAM_OUTPUT, 737 MIXER_NAME_UNDEFINED); 738 739 /* If our extra controls contain a main volume 740 * entry, and we found a main volume entry, then 741 * skip it. */ 742 if (extra_main_volume && 743 control && control->type == MIXER_NAME_MAIN_VOLUME) 744 control = NULL; 745 746 /* If we didn't match any of the defaults, match 747 * the extras list. */ 748 if (!control) 749 control = mixer_name_find(extra_controls, name, 750 CRAS_STREAM_OUTPUT, 751 MIXER_NAME_UNDEFINED); 752 753 if (control) { 754 int rc = -1; 755 switch(control->type) { 756 case MIXER_NAME_MAIN_VOLUME: 757 rc = add_main_volume_control(cmix, elem); 758 break; 759 case MIXER_NAME_VOLUME: 760 /* TODO(dgreid) - determine device index. */ 761 rc = add_control( 762 cmix, CRAS_STREAM_OUTPUT, elem); 763 break; 764 case MIXER_NAME_UNDEFINED: 765 rc = -EINVAL; 766 break; 767 } 768 if (rc) { 769 syslog(LOG_ERR, 770 "Failed to add mixer control '%s'" 771 " with type '%d'", 772 control->name, control->type); 773 return rc; 774 } 775 found = 1; 776 } 777 778 /* Find a matching input control. */ 779 control = mixer_name_find(default_controls, name, 780 CRAS_STREAM_INPUT, 781 MIXER_NAME_UNDEFINED); 782 783 /* If we didn't match any of the defaults, match 784 the extras list */ 785 if (!control) 786 control = mixer_name_find(extra_controls, name, 787 CRAS_STREAM_INPUT, 788 MIXER_NAME_UNDEFINED); 789 790 if (control) { 791 int rc = -1; 792 switch(control->type) { 793 case MIXER_NAME_MAIN_VOLUME: 794 rc = add_main_capture_control(cmix, elem); 795 break; 796 case MIXER_NAME_VOLUME: 797 rc = add_control( 798 cmix, CRAS_STREAM_INPUT, elem); 799 break; 800 case MIXER_NAME_UNDEFINED: 801 rc = -EINVAL; 802 break; 803 } 804 if (rc) { 805 syslog(LOG_ERR, 806 "Failed to add mixer control '%s'" 807 " with type '%d'", 808 control->name, control->type); 809 return rc; 810 } 811 found = 1; 812 } 813 814 if (!found && snd_mixer_selem_has_playback_volume(elem)) { 815 /* Temporarily cache one elem whose name is not 816 * in the list above, but has a playback volume 817 * control and the largest volume range. */ 818 long min, max, range; 819 if (snd_mixer_selem_get_playback_dB_range(elem, 820 &min, 821 &max) != 0) 822 continue; 823 824 range = max - min; 825 if (other_dB_range < range) { 826 other_dB_range = range; 827 other_elem = elem; 828 } 829 } 830 } 831 832 /* Handle coupled output names for speaker */ 833 if (coupled_controls) { 834 rc = add_control_with_coupled_mixers( 835 cmix, CRAS_STREAM_OUTPUT, 836 "Speaker", coupled_controls); 837 if (rc) { 838 syslog(LOG_ERR, "Could not add coupled output"); 839 return rc; 840 } 841 } 842 843 /* If there is no volume control and output control found, 844 * use the volume control which has the largest volume range 845 * in the mixer as a main volume control. */ 846 if (!cmix->main_volume_controls && !cmix->output_controls && 847 other_elem) { 848 rc = add_main_volume_control(cmix, other_elem); 849 if (rc) { 850 syslog(LOG_ERR, "Could not add other volume control"); 851 return rc; 852 } 853 } 854 855 return rc; 856 } 857 858 int cras_alsa_mixer_add_controls_in_section( 859 struct cras_alsa_mixer *cmix, 860 struct ucm_section *section) 861 { 862 int rc; 863 864 /* Note that there is no mixer on some cards. This is acceptable. */ 865 if (cmix->mixer == NULL) { 866 syslog(LOG_DEBUG, "Couldn't open mixer."); 867 return 0; 868 } 869 870 if (!section) { 871 syslog(LOG_ERR, "No UCM SectionDevice specified."); 872 return -EINVAL; 873 } 874 875 /* TODO(muirj) - Extra main volume controls when fully-specified. */ 876 877 if (section->mixer_name) { 878 rc = add_control_by_name( 879 cmix, section->dir, section->mixer_name); 880 if (rc) { 881 syslog(LOG_ERR, "Could not add mixer control '%s': %s", 882 section->mixer_name, strerror(-rc)); 883 return rc; 884 } 885 } 886 887 if (section->coupled) { 888 rc = add_control_with_coupled_mixers( 889 cmix, section->dir, 890 section->name, section->coupled); 891 if (rc) { 892 syslog(LOG_ERR, "Could not add coupled control: %s", 893 strerror(-rc)); 894 return rc; 895 } 896 } 897 return 0; 898 } 899 900 void cras_alsa_mixer_destroy(struct cras_alsa_mixer *cras_mixer) 901 { 902 assert(cras_mixer); 903 904 mixer_control_destroy_list(cras_mixer->main_volume_controls); 905 mixer_control_destroy_list(cras_mixer->main_capture_controls); 906 mixer_control_destroy_list(cras_mixer->output_controls); 907 mixer_control_destroy_list(cras_mixer->input_controls); 908 if (cras_mixer->mixer) 909 snd_mixer_close(cras_mixer->mixer); 910 free(cras_mixer); 911 } 912 913 int cras_alsa_mixer_has_main_volume( 914 const struct cras_alsa_mixer *cras_mixer) 915 { 916 return !!cras_mixer->main_volume_controls; 917 } 918 919 int cras_alsa_mixer_has_volume(const struct mixer_control *mixer_control) 920 { 921 return mixer_control && mixer_control->has_volume; 922 } 923 924 void cras_alsa_mixer_set_dBFS(struct cras_alsa_mixer *cras_mixer, 925 long dBFS, 926 struct mixer_control *mixer_output) 927 { 928 struct mixer_control *c; 929 long to_set; 930 931 assert(cras_mixer); 932 933 /* dBFS is normally < 0 to specify the attenuation from max. max is the 934 * combined max of the master controls and the current output. 935 */ 936 to_set = dBFS + cras_mixer->max_volume_dB; 937 if (cras_alsa_mixer_has_volume(mixer_output)) 938 to_set += mixer_output->max_volume_dB; 939 /* Go through all the controls, set the volume level for each, 940 * taking the value closest but greater than the desired volume. If the 941 * entire volume can't be set on the current control, move on to the 942 * next one until we have the exact volume, or gotten as close as we 943 * can. Once all of the volume is set the rest of the controls should be 944 * set to 0dB. */ 945 DL_FOREACH(cras_mixer->main_volume_controls, c) { 946 long actual_dB; 947 948 if (!c->has_volume) 949 continue; 950 mixer_control_set_dBFS(c, to_set); 951 mixer_control_get_dBFS(c, &actual_dB); 952 to_set -= actual_dB; 953 } 954 /* Apply the rest to the output-specific control. */ 955 if (cras_alsa_mixer_has_volume(mixer_output)) 956 mixer_control_set_dBFS(mixer_output, to_set); 957 } 958 959 long cras_alsa_mixer_get_dB_range(struct cras_alsa_mixer *cras_mixer) 960 { 961 if (!cras_mixer) 962 return 0; 963 return cras_mixer->max_volume_dB - cras_mixer->min_volume_dB; 964 } 965 966 long cras_alsa_mixer_get_output_dB_range( 967 struct mixer_control *mixer_output) 968 { 969 if (!cras_alsa_mixer_has_volume(mixer_output)) 970 return 0; 971 972 return mixer_output->max_volume_dB - mixer_output->min_volume_dB; 973 } 974 975 void cras_alsa_mixer_set_capture_dBFS(struct cras_alsa_mixer *cras_mixer, 976 long dBFS, 977 struct mixer_control *mixer_input) 978 { 979 struct mixer_control *c; 980 long to_set; 981 982 assert(cras_mixer); 983 to_set = dBFS; 984 /* Go through all the controls, set the gain for each, taking the value 985 * closest but greater than the desired gain. If the entire gain can't 986 * be set on the current control, move on to the next one until we have 987 * the exact gain, or gotten as close as we can. Once all of the gain is 988 * set the rest of the controls should be set to 0dB. */ 989 DL_FOREACH(cras_mixer->main_capture_controls, c) { 990 long actual_dB; 991 992 if (!c->has_volume) 993 continue; 994 mixer_control_set_dBFS(c, to_set); 995 mixer_control_get_dBFS(c, &actual_dB); 996 to_set -= actual_dB; 997 } 998 999 /* Apply the reset to input specific control */ 1000 if (cras_alsa_mixer_has_volume(mixer_input)) 1001 mixer_control_set_dBFS(mixer_input, to_set); 1002 } 1003 1004 long cras_alsa_mixer_get_minimum_capture_gain( 1005 struct cras_alsa_mixer *cmix, 1006 struct mixer_control *mixer_input) 1007 { 1008 struct mixer_control *c; 1009 long total_min = 0; 1010 1011 assert(cmix); 1012 DL_FOREACH(cmix->main_capture_controls, c) 1013 if (c->has_volume) 1014 total_min += c->min_volume_dB; 1015 if (mixer_input && 1016 mixer_input->has_volume) 1017 total_min += mixer_input->min_volume_dB; 1018 1019 return total_min; 1020 } 1021 1022 long cras_alsa_mixer_get_maximum_capture_gain( 1023 struct cras_alsa_mixer *cmix, 1024 struct mixer_control *mixer_input) 1025 { 1026 struct mixer_control *c; 1027 long total_max = 0; 1028 1029 assert(cmix); 1030 DL_FOREACH(cmix->main_capture_controls, c) 1031 if (c->has_volume) 1032 total_max += c->max_volume_dB; 1033 1034 if (mixer_input && 1035 mixer_input->has_volume) 1036 total_max += mixer_input->max_volume_dB; 1037 1038 return total_max; 1039 } 1040 1041 void cras_alsa_mixer_set_mute(struct cras_alsa_mixer *cras_mixer, 1042 int muted, 1043 struct mixer_control *mixer_output) 1044 { 1045 assert(cras_mixer); 1046 1047 if (cras_mixer->playback_switch) { 1048 snd_mixer_selem_set_playback_switch_all( 1049 cras_mixer->playback_switch, !muted); 1050 } 1051 if (mixer_output && mixer_output->has_mute) { 1052 mixer_control_set_mute(mixer_output, muted); 1053 } 1054 } 1055 1056 void cras_alsa_mixer_set_capture_mute(struct cras_alsa_mixer *cras_mixer, 1057 int muted, 1058 struct mixer_control *mixer_input) 1059 { 1060 assert(cras_mixer); 1061 if (cras_mixer->capture_switch) { 1062 snd_mixer_selem_set_capture_switch_all( 1063 cras_mixer->capture_switch, !muted); 1064 return; 1065 } 1066 if (mixer_input && mixer_input->has_mute) 1067 mixer_control_set_mute(mixer_input, muted); 1068 } 1069 1070 void cras_alsa_mixer_list_outputs(struct cras_alsa_mixer *cras_mixer, 1071 cras_alsa_mixer_control_callback cb, 1072 void *cb_arg) 1073 { 1074 assert(cras_mixer); 1075 list_controls(cras_mixer->output_controls, cb, cb_arg); 1076 } 1077 1078 void cras_alsa_mixer_list_inputs(struct cras_alsa_mixer *cras_mixer, 1079 cras_alsa_mixer_control_callback cb, 1080 void *cb_arg) 1081 { 1082 assert(cras_mixer); 1083 list_controls(cras_mixer->input_controls, cb, cb_arg); 1084 } 1085 1086 const char *cras_alsa_mixer_get_control_name( 1087 const struct mixer_control *control) 1088 { 1089 if (!control) 1090 return NULL; 1091 return control->name; 1092 } 1093 1094 struct mixer_control *cras_alsa_mixer_get_control_matching_name( 1095 struct cras_alsa_mixer *cras_mixer, 1096 enum CRAS_STREAM_DIRECTION dir, const char *name, 1097 int create_missing) 1098 { 1099 struct mixer_control *c; 1100 1101 assert(cras_mixer); 1102 if (!name) 1103 return NULL; 1104 1105 if (dir == CRAS_STREAM_OUTPUT) { 1106 c = get_control_matching_name( 1107 cras_mixer->output_controls, name); 1108 } else if (dir == CRAS_STREAM_INPUT) { 1109 c = get_control_matching_name( 1110 cras_mixer->input_controls, name); 1111 } else { 1112 return NULL; 1113 } 1114 1115 /* TODO: Allowing creation of a new control is a workaround: we 1116 * should pass the input names in ucm config to 1117 * cras_alsa_mixer_create. */ 1118 if (!c && cras_mixer->mixer && create_missing) { 1119 int rc = add_control_by_name(cras_mixer, dir, name); 1120 if (rc) 1121 return NULL; 1122 c = cras_alsa_mixer_get_control_matching_name( 1123 cras_mixer, dir, name, 0); 1124 } 1125 return c; 1126 } 1127 1128 struct mixer_control *cras_alsa_mixer_get_control_for_section( 1129 struct cras_alsa_mixer *cras_mixer, 1130 const struct ucm_section *section) 1131 { 1132 assert(cras_mixer && section); 1133 if (section->mixer_name) { 1134 return cras_alsa_mixer_get_control_matching_name( 1135 cras_mixer, section->dir, section->mixer_name, 0); 1136 } else if (section->coupled) { 1137 return cras_alsa_mixer_get_control_matching_name( 1138 cras_mixer, section->dir, section->name, 0); 1139 } 1140 return NULL; 1141 } 1142 1143 struct mixer_control *cras_alsa_mixer_get_output_matching_name( 1144 struct cras_alsa_mixer *cras_mixer, 1145 const char * const name) 1146 { 1147 return cras_alsa_mixer_get_control_matching_name( 1148 cras_mixer, CRAS_STREAM_OUTPUT, name, 0); 1149 } 1150 1151 struct mixer_control *cras_alsa_mixer_get_input_matching_name( 1152 struct cras_alsa_mixer *cras_mixer, 1153 const char *name) 1154 { 1155 /* TODO: Allowing creation of a new control is a workaround: we 1156 * should pass the input names in ucm config to 1157 * cras_alsa_mixer_create. */ 1158 return cras_alsa_mixer_get_control_matching_name( 1159 cras_mixer, CRAS_STREAM_INPUT, name, 1); 1160 } 1161 1162 int cras_alsa_mixer_set_output_active_state( 1163 struct mixer_control *output, 1164 int active) 1165 { 1166 assert(output); 1167 if (!output->has_mute) 1168 return -1; 1169 return mixer_control_set_mute(output, !active); 1170 } 1171