1 /* 2 * Copyright (C) 2010 Red Hat, Inc. 3 * 4 * written by Gerd Hoffmann <kraxel@redhat.com> 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; either version 2 or 9 * (at your option) version 3 of the License. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "hw/hw.h" 21 #include "hw/pci/pci.h" 22 #include "intel-hda.h" 23 #include "intel-hda-defs.h" 24 #include "audio/audio.h" 25 26 /* -------------------------------------------------------------------------- */ 27 28 typedef struct desc_param { 29 uint32_t id; 30 uint32_t val; 31 } desc_param; 32 33 typedef struct desc_node { 34 uint32_t nid; 35 const char *name; 36 const desc_param *params; 37 uint32_t nparams; 38 uint32_t config; 39 uint32_t pinctl; 40 uint32_t *conn; 41 uint32_t stindex; 42 } desc_node; 43 44 typedef struct desc_codec { 45 const char *name; 46 uint32_t iid; 47 const desc_node *nodes; 48 uint32_t nnodes; 49 } desc_codec; 50 51 static const desc_param* hda_codec_find_param(const desc_node *node, uint32_t id) 52 { 53 int i; 54 55 for (i = 0; i < node->nparams; i++) { 56 if (node->params[i].id == id) { 57 return &node->params[i]; 58 } 59 } 60 return NULL; 61 } 62 63 static const desc_node* hda_codec_find_node(const desc_codec *codec, uint32_t nid) 64 { 65 int i; 66 67 for (i = 0; i < codec->nnodes; i++) { 68 if (codec->nodes[i].nid == nid) { 69 return &codec->nodes[i]; 70 } 71 } 72 return NULL; 73 } 74 75 static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as) 76 { 77 if (format & AC_FMT_TYPE_NON_PCM) { 78 return; 79 } 80 81 as->freq = (format & AC_FMT_BASE_44K) ? 44100 : 48000; 82 83 switch ((format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT) { 84 case 1: as->freq *= 2; break; 85 case 2: as->freq *= 3; break; 86 case 3: as->freq *= 4; break; 87 } 88 89 switch ((format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT) { 90 case 1: as->freq /= 2; break; 91 case 2: as->freq /= 3; break; 92 case 3: as->freq /= 4; break; 93 case 4: as->freq /= 5; break; 94 case 5: as->freq /= 6; break; 95 case 6: as->freq /= 7; break; 96 case 7: as->freq /= 8; break; 97 } 98 99 switch (format & AC_FMT_BITS_MASK) { 100 case AC_FMT_BITS_8: as->fmt = AUD_FMT_S8; break; 101 case AC_FMT_BITS_16: as->fmt = AUD_FMT_S16; break; 102 case AC_FMT_BITS_32: as->fmt = AUD_FMT_S32; break; 103 } 104 105 as->nchannels = ((format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT) + 1; 106 } 107 108 /* -------------------------------------------------------------------------- */ 109 /* 110 * HDA codec descriptions 111 */ 112 113 /* some defines */ 114 115 #define QEMU_HDA_ID_VENDOR 0x1af4 116 #define QEMU_HDA_PCM_FORMATS (AC_SUPPCM_BITS_16 | \ 117 0x1fc /* 16 -> 96 kHz */) 118 #define QEMU_HDA_AMP_NONE (0) 119 #define QEMU_HDA_AMP_STEPS 0x4a 120 121 #ifdef CONFIG_MIXEMU 122 # define QEMU_HDA_ID_OUTPUT ((QEMU_HDA_ID_VENDOR << 16) | 0x12) 123 # define QEMU_HDA_ID_DUPLEX ((QEMU_HDA_ID_VENDOR << 16) | 0x22) 124 # define QEMU_HDA_ID_MICRO ((QEMU_HDA_ID_VENDOR << 16) | 0x32) 125 # define QEMU_HDA_AMP_CAPS \ 126 (AC_AMPCAP_MUTE | \ 127 (QEMU_HDA_AMP_STEPS << AC_AMPCAP_OFFSET_SHIFT) | \ 128 (QEMU_HDA_AMP_STEPS << AC_AMPCAP_NUM_STEPS_SHIFT) | \ 129 (3 << AC_AMPCAP_STEP_SIZE_SHIFT)) 130 #else 131 # define QEMU_HDA_ID_OUTPUT ((QEMU_HDA_ID_VENDOR << 16) | 0x11) 132 # define QEMU_HDA_ID_DUPLEX ((QEMU_HDA_ID_VENDOR << 16) | 0x21) 133 # define QEMU_HDA_ID_MICRO ((QEMU_HDA_ID_VENDOR << 16) | 0x31) 134 # define QEMU_HDA_AMP_CAPS QEMU_HDA_AMP_NONE 135 #endif 136 137 /* common: audio output widget */ 138 static const desc_param common_params_audio_dac[] = { 139 { 140 .id = AC_PAR_AUDIO_WIDGET_CAP, 141 .val = ((AC_WID_AUD_OUT << AC_WCAP_TYPE_SHIFT) | 142 AC_WCAP_FORMAT_OVRD | 143 AC_WCAP_AMP_OVRD | 144 AC_WCAP_OUT_AMP | 145 AC_WCAP_STEREO), 146 },{ 147 .id = AC_PAR_PCM, 148 .val = QEMU_HDA_PCM_FORMATS, 149 },{ 150 .id = AC_PAR_STREAM, 151 .val = AC_SUPFMT_PCM, 152 },{ 153 .id = AC_PAR_AMP_IN_CAP, 154 .val = QEMU_HDA_AMP_NONE, 155 },{ 156 .id = AC_PAR_AMP_OUT_CAP, 157 .val = QEMU_HDA_AMP_CAPS, 158 }, 159 }; 160 161 /* common: audio input widget */ 162 static const desc_param common_params_audio_adc[] = { 163 { 164 .id = AC_PAR_AUDIO_WIDGET_CAP, 165 .val = ((AC_WID_AUD_IN << AC_WCAP_TYPE_SHIFT) | 166 AC_WCAP_CONN_LIST | 167 AC_WCAP_FORMAT_OVRD | 168 AC_WCAP_AMP_OVRD | 169 AC_WCAP_IN_AMP | 170 AC_WCAP_STEREO), 171 },{ 172 .id = AC_PAR_CONNLIST_LEN, 173 .val = 1, 174 },{ 175 .id = AC_PAR_PCM, 176 .val = QEMU_HDA_PCM_FORMATS, 177 },{ 178 .id = AC_PAR_STREAM, 179 .val = AC_SUPFMT_PCM, 180 },{ 181 .id = AC_PAR_AMP_IN_CAP, 182 .val = QEMU_HDA_AMP_CAPS, 183 },{ 184 .id = AC_PAR_AMP_OUT_CAP, 185 .val = QEMU_HDA_AMP_NONE, 186 }, 187 }; 188 189 /* common: pin widget (line-out) */ 190 static const desc_param common_params_audio_lineout[] = { 191 { 192 .id = AC_PAR_AUDIO_WIDGET_CAP, 193 .val = ((AC_WID_PIN << AC_WCAP_TYPE_SHIFT) | 194 AC_WCAP_CONN_LIST | 195 AC_WCAP_STEREO), 196 },{ 197 .id = AC_PAR_PIN_CAP, 198 .val = AC_PINCAP_OUT, 199 },{ 200 .id = AC_PAR_CONNLIST_LEN, 201 .val = 1, 202 },{ 203 .id = AC_PAR_AMP_IN_CAP, 204 .val = QEMU_HDA_AMP_NONE, 205 },{ 206 .id = AC_PAR_AMP_OUT_CAP, 207 .val = QEMU_HDA_AMP_NONE, 208 }, 209 }; 210 211 /* common: pin widget (line-in) */ 212 static const desc_param common_params_audio_linein[] = { 213 { 214 .id = AC_PAR_AUDIO_WIDGET_CAP, 215 .val = ((AC_WID_PIN << AC_WCAP_TYPE_SHIFT) | 216 AC_WCAP_STEREO), 217 },{ 218 .id = AC_PAR_PIN_CAP, 219 .val = AC_PINCAP_IN, 220 },{ 221 .id = AC_PAR_AMP_IN_CAP, 222 .val = QEMU_HDA_AMP_NONE, 223 },{ 224 .id = AC_PAR_AMP_OUT_CAP, 225 .val = QEMU_HDA_AMP_NONE, 226 }, 227 }; 228 229 /* output: root node */ 230 static const desc_param output_params_root[] = { 231 { 232 .id = AC_PAR_VENDOR_ID, 233 .val = QEMU_HDA_ID_OUTPUT, 234 },{ 235 .id = AC_PAR_SUBSYSTEM_ID, 236 .val = QEMU_HDA_ID_OUTPUT, 237 },{ 238 .id = AC_PAR_REV_ID, 239 .val = 0x00100101, 240 },{ 241 .id = AC_PAR_NODE_COUNT, 242 .val = 0x00010001, 243 }, 244 }; 245 246 /* output: audio function */ 247 static const desc_param output_params_audio_func[] = { 248 { 249 .id = AC_PAR_FUNCTION_TYPE, 250 .val = AC_GRP_AUDIO_FUNCTION, 251 },{ 252 .id = AC_PAR_SUBSYSTEM_ID, 253 .val = QEMU_HDA_ID_OUTPUT, 254 },{ 255 .id = AC_PAR_NODE_COUNT, 256 .val = 0x00020002, 257 },{ 258 .id = AC_PAR_PCM, 259 .val = QEMU_HDA_PCM_FORMATS, 260 },{ 261 .id = AC_PAR_STREAM, 262 .val = AC_SUPFMT_PCM, 263 },{ 264 .id = AC_PAR_AMP_IN_CAP, 265 .val = QEMU_HDA_AMP_NONE, 266 },{ 267 .id = AC_PAR_AMP_OUT_CAP, 268 .val = QEMU_HDA_AMP_NONE, 269 },{ 270 .id = AC_PAR_GPIO_CAP, 271 .val = 0, 272 },{ 273 .id = AC_PAR_AUDIO_FG_CAP, 274 .val = 0x00000808, 275 },{ 276 .id = AC_PAR_POWER_STATE, 277 .val = 0, 278 }, 279 }; 280 281 /* output: nodes */ 282 static const desc_node output_nodes[] = { 283 { 284 .nid = AC_NODE_ROOT, 285 .name = "root", 286 .params = output_params_root, 287 .nparams = ARRAY_SIZE(output_params_root), 288 },{ 289 .nid = 1, 290 .name = "func", 291 .params = output_params_audio_func, 292 .nparams = ARRAY_SIZE(output_params_audio_func), 293 },{ 294 .nid = 2, 295 .name = "dac", 296 .params = common_params_audio_dac, 297 .nparams = ARRAY_SIZE(common_params_audio_dac), 298 .stindex = 0, 299 },{ 300 .nid = 3, 301 .name = "out", 302 .params = common_params_audio_lineout, 303 .nparams = ARRAY_SIZE(common_params_audio_lineout), 304 .config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) | 305 (AC_JACK_LINE_OUT << AC_DEFCFG_DEVICE_SHIFT) | 306 (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) | 307 (AC_JACK_COLOR_GREEN << AC_DEFCFG_COLOR_SHIFT) | 308 0x10), 309 .pinctl = AC_PINCTL_OUT_EN, 310 .conn = (uint32_t[]) { 2 }, 311 } 312 }; 313 314 /* output: codec */ 315 static const desc_codec output = { 316 .name = "output", 317 .iid = QEMU_HDA_ID_OUTPUT, 318 .nodes = output_nodes, 319 .nnodes = ARRAY_SIZE(output_nodes), 320 }; 321 322 /* duplex: root node */ 323 static const desc_param duplex_params_root[] = { 324 { 325 .id = AC_PAR_VENDOR_ID, 326 .val = QEMU_HDA_ID_DUPLEX, 327 },{ 328 .id = AC_PAR_SUBSYSTEM_ID, 329 .val = QEMU_HDA_ID_DUPLEX, 330 },{ 331 .id = AC_PAR_REV_ID, 332 .val = 0x00100101, 333 },{ 334 .id = AC_PAR_NODE_COUNT, 335 .val = 0x00010001, 336 }, 337 }; 338 339 /* duplex: audio function */ 340 static const desc_param duplex_params_audio_func[] = { 341 { 342 .id = AC_PAR_FUNCTION_TYPE, 343 .val = AC_GRP_AUDIO_FUNCTION, 344 },{ 345 .id = AC_PAR_SUBSYSTEM_ID, 346 .val = QEMU_HDA_ID_DUPLEX, 347 },{ 348 .id = AC_PAR_NODE_COUNT, 349 .val = 0x00020004, 350 },{ 351 .id = AC_PAR_PCM, 352 .val = QEMU_HDA_PCM_FORMATS, 353 },{ 354 .id = AC_PAR_STREAM, 355 .val = AC_SUPFMT_PCM, 356 },{ 357 .id = AC_PAR_AMP_IN_CAP, 358 .val = QEMU_HDA_AMP_NONE, 359 },{ 360 .id = AC_PAR_AMP_OUT_CAP, 361 .val = QEMU_HDA_AMP_NONE, 362 },{ 363 .id = AC_PAR_GPIO_CAP, 364 .val = 0, 365 },{ 366 .id = AC_PAR_AUDIO_FG_CAP, 367 .val = 0x00000808, 368 },{ 369 .id = AC_PAR_POWER_STATE, 370 .val = 0, 371 }, 372 }; 373 374 /* duplex: nodes */ 375 static const desc_node duplex_nodes[] = { 376 { 377 .nid = AC_NODE_ROOT, 378 .name = "root", 379 .params = duplex_params_root, 380 .nparams = ARRAY_SIZE(duplex_params_root), 381 },{ 382 .nid = 1, 383 .name = "func", 384 .params = duplex_params_audio_func, 385 .nparams = ARRAY_SIZE(duplex_params_audio_func), 386 },{ 387 .nid = 2, 388 .name = "dac", 389 .params = common_params_audio_dac, 390 .nparams = ARRAY_SIZE(common_params_audio_dac), 391 .stindex = 0, 392 },{ 393 .nid = 3, 394 .name = "out", 395 .params = common_params_audio_lineout, 396 .nparams = ARRAY_SIZE(common_params_audio_lineout), 397 .config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) | 398 (AC_JACK_LINE_OUT << AC_DEFCFG_DEVICE_SHIFT) | 399 (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) | 400 (AC_JACK_COLOR_GREEN << AC_DEFCFG_COLOR_SHIFT) | 401 0x10), 402 .pinctl = AC_PINCTL_OUT_EN, 403 .conn = (uint32_t[]) { 2 }, 404 },{ 405 .nid = 4, 406 .name = "adc", 407 .params = common_params_audio_adc, 408 .nparams = ARRAY_SIZE(common_params_audio_adc), 409 .stindex = 1, 410 .conn = (uint32_t[]) { 5 }, 411 },{ 412 .nid = 5, 413 .name = "in", 414 .params = common_params_audio_linein, 415 .nparams = ARRAY_SIZE(common_params_audio_linein), 416 .config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) | 417 (AC_JACK_LINE_IN << AC_DEFCFG_DEVICE_SHIFT) | 418 (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) | 419 (AC_JACK_COLOR_RED << AC_DEFCFG_COLOR_SHIFT) | 420 0x20), 421 .pinctl = AC_PINCTL_IN_EN, 422 } 423 }; 424 425 /* duplex: codec */ 426 static const desc_codec duplex = { 427 .name = "duplex", 428 .iid = QEMU_HDA_ID_DUPLEX, 429 .nodes = duplex_nodes, 430 .nnodes = ARRAY_SIZE(duplex_nodes), 431 }; 432 433 /* micro: root node */ 434 static const desc_param micro_params_root[] = { 435 { 436 .id = AC_PAR_VENDOR_ID, 437 .val = QEMU_HDA_ID_MICRO, 438 },{ 439 .id = AC_PAR_SUBSYSTEM_ID, 440 .val = QEMU_HDA_ID_MICRO, 441 },{ 442 .id = AC_PAR_REV_ID, 443 .val = 0x00100101, 444 },{ 445 .id = AC_PAR_NODE_COUNT, 446 .val = 0x00010001, 447 }, 448 }; 449 450 /* micro: audio function */ 451 static const desc_param micro_params_audio_func[] = { 452 { 453 .id = AC_PAR_FUNCTION_TYPE, 454 .val = AC_GRP_AUDIO_FUNCTION, 455 },{ 456 .id = AC_PAR_SUBSYSTEM_ID, 457 .val = QEMU_HDA_ID_MICRO, 458 },{ 459 .id = AC_PAR_NODE_COUNT, 460 .val = 0x00020004, 461 },{ 462 .id = AC_PAR_PCM, 463 .val = QEMU_HDA_PCM_FORMATS, 464 },{ 465 .id = AC_PAR_STREAM, 466 .val = AC_SUPFMT_PCM, 467 },{ 468 .id = AC_PAR_AMP_IN_CAP, 469 .val = QEMU_HDA_AMP_NONE, 470 },{ 471 .id = AC_PAR_AMP_OUT_CAP, 472 .val = QEMU_HDA_AMP_NONE, 473 },{ 474 .id = AC_PAR_GPIO_CAP, 475 .val = 0, 476 },{ 477 .id = AC_PAR_AUDIO_FG_CAP, 478 .val = 0x00000808, 479 },{ 480 .id = AC_PAR_POWER_STATE, 481 .val = 0, 482 }, 483 }; 484 485 /* micro: nodes */ 486 static const desc_node micro_nodes[] = { 487 { 488 .nid = AC_NODE_ROOT, 489 .name = "root", 490 .params = micro_params_root, 491 .nparams = ARRAY_SIZE(micro_params_root), 492 },{ 493 .nid = 1, 494 .name = "func", 495 .params = micro_params_audio_func, 496 .nparams = ARRAY_SIZE(micro_params_audio_func), 497 },{ 498 .nid = 2, 499 .name = "dac", 500 .params = common_params_audio_dac, 501 .nparams = ARRAY_SIZE(common_params_audio_dac), 502 .stindex = 0, 503 },{ 504 .nid = 3, 505 .name = "out", 506 .params = common_params_audio_lineout, 507 .nparams = ARRAY_SIZE(common_params_audio_lineout), 508 .config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) | 509 (AC_JACK_SPEAKER << AC_DEFCFG_DEVICE_SHIFT) | 510 (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) | 511 (AC_JACK_COLOR_GREEN << AC_DEFCFG_COLOR_SHIFT) | 512 0x10), 513 .pinctl = AC_PINCTL_OUT_EN, 514 .conn = (uint32_t[]) { 2 }, 515 },{ 516 .nid = 4, 517 .name = "adc", 518 .params = common_params_audio_adc, 519 .nparams = ARRAY_SIZE(common_params_audio_adc), 520 .stindex = 1, 521 .conn = (uint32_t[]) { 5 }, 522 },{ 523 .nid = 5, 524 .name = "in", 525 .params = common_params_audio_linein, 526 .nparams = ARRAY_SIZE(common_params_audio_linein), 527 .config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) | 528 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT) | 529 (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) | 530 (AC_JACK_COLOR_RED << AC_DEFCFG_COLOR_SHIFT) | 531 0x20), 532 .pinctl = AC_PINCTL_IN_EN, 533 } 534 }; 535 536 /* micro: codec */ 537 static const desc_codec micro = { 538 .name = "micro", 539 .iid = QEMU_HDA_ID_MICRO, 540 .nodes = micro_nodes, 541 .nnodes = ARRAY_SIZE(micro_nodes), 542 }; 543 544 /* -------------------------------------------------------------------------- */ 545 546 static const char *fmt2name[] = { 547 [ AUD_FMT_U8 ] = "PCM-U8", 548 [ AUD_FMT_S8 ] = "PCM-S8", 549 [ AUD_FMT_U16 ] = "PCM-U16", 550 [ AUD_FMT_S16 ] = "PCM-S16", 551 [ AUD_FMT_U32 ] = "PCM-U32", 552 [ AUD_FMT_S32 ] = "PCM-S32", 553 }; 554 555 typedef struct HDAAudioState HDAAudioState; 556 typedef struct HDAAudioStream HDAAudioStream; 557 558 struct HDAAudioStream { 559 HDAAudioState *state; 560 const desc_node *node; 561 bool output, running; 562 uint32_t stream; 563 uint32_t channel; 564 uint32_t format; 565 uint32_t gain_left, gain_right; 566 bool mute_left, mute_right; 567 struct audsettings as; 568 union { 569 SWVoiceIn *in; 570 SWVoiceOut *out; 571 } voice; 572 uint8_t buf[HDA_BUFFER_SIZE]; 573 uint32_t bpos; 574 }; 575 576 struct HDAAudioState { 577 HDACodecDevice hda; 578 const char *name; 579 580 QEMUSoundCard card; 581 const desc_codec *desc; 582 HDAAudioStream st[4]; 583 bool running_compat[16]; 584 bool running_real[2 * 16]; 585 586 /* properties */ 587 uint32_t debug; 588 }; 589 590 static void hda_audio_input_cb(void *opaque, int avail) 591 { 592 HDAAudioStream *st = opaque; 593 int recv = 0; 594 int len; 595 bool rc; 596 597 while (avail - recv >= sizeof(st->buf)) { 598 if (st->bpos != sizeof(st->buf)) { 599 len = AUD_read(st->voice.in, st->buf + st->bpos, 600 sizeof(st->buf) - st->bpos); 601 st->bpos += len; 602 recv += len; 603 if (st->bpos != sizeof(st->buf)) { 604 break; 605 } 606 } 607 rc = hda_codec_xfer(&st->state->hda, st->stream, false, 608 st->buf, sizeof(st->buf)); 609 if (!rc) { 610 break; 611 } 612 st->bpos = 0; 613 } 614 } 615 616 static void hda_audio_output_cb(void *opaque, int avail) 617 { 618 HDAAudioStream *st = opaque; 619 int sent = 0; 620 int len; 621 bool rc; 622 623 while (avail - sent >= sizeof(st->buf)) { 624 if (st->bpos == sizeof(st->buf)) { 625 rc = hda_codec_xfer(&st->state->hda, st->stream, true, 626 st->buf, sizeof(st->buf)); 627 if (!rc) { 628 break; 629 } 630 st->bpos = 0; 631 } 632 len = AUD_write(st->voice.out, st->buf + st->bpos, 633 sizeof(st->buf) - st->bpos); 634 st->bpos += len; 635 sent += len; 636 if (st->bpos != sizeof(st->buf)) { 637 break; 638 } 639 } 640 } 641 642 static void hda_audio_set_running(HDAAudioStream *st, bool running) 643 { 644 if (st->node == NULL) { 645 return; 646 } 647 if (st->running == running) { 648 return; 649 } 650 st->running = running; 651 dprint(st->state, 1, "%s: %s (stream %d)\n", st->node->name, 652 st->running ? "on" : "off", st->stream); 653 if (st->output) { 654 AUD_set_active_out(st->voice.out, st->running); 655 } else { 656 AUD_set_active_in(st->voice.in, st->running); 657 } 658 } 659 660 static void hda_audio_set_amp(HDAAudioStream *st) 661 { 662 bool muted; 663 uint32_t left, right; 664 665 if (st->node == NULL) { 666 return; 667 } 668 669 muted = st->mute_left && st->mute_right; 670 left = st->mute_left ? 0 : st->gain_left; 671 right = st->mute_right ? 0 : st->gain_right; 672 673 left = left * 255 / QEMU_HDA_AMP_STEPS; 674 right = right * 255 / QEMU_HDA_AMP_STEPS; 675 676 if (st->output) { 677 AUD_set_volume_out(st->voice.out, muted, left, right); 678 } else { 679 AUD_set_volume_in(st->voice.in, muted, left, right); 680 } 681 } 682 683 static void hda_audio_setup(HDAAudioStream *st) 684 { 685 if (st->node == NULL) { 686 return; 687 } 688 689 dprint(st->state, 1, "%s: format: %d x %s @ %d Hz\n", 690 st->node->name, st->as.nchannels, 691 fmt2name[st->as.fmt], st->as.freq); 692 693 if (st->output) { 694 st->voice.out = AUD_open_out(&st->state->card, st->voice.out, 695 st->node->name, st, 696 hda_audio_output_cb, &st->as); 697 } else { 698 st->voice.in = AUD_open_in(&st->state->card, st->voice.in, 699 st->node->name, st, 700 hda_audio_input_cb, &st->as); 701 } 702 } 703 704 static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data) 705 { 706 HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); 707 HDAAudioStream *st; 708 const desc_node *node = NULL; 709 const desc_param *param; 710 uint32_t verb, payload, response, count, shift; 711 712 if ((data & 0x70000) == 0x70000) { 713 /* 12/8 id/payload */ 714 verb = (data >> 8) & 0xfff; 715 payload = data & 0x00ff; 716 } else { 717 /* 4/16 id/payload */ 718 verb = (data >> 8) & 0xf00; 719 payload = data & 0xffff; 720 } 721 722 node = hda_codec_find_node(a->desc, nid); 723 if (node == NULL) { 724 goto fail; 725 } 726 dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n", 727 __FUNCTION__, nid, node->name, verb, payload); 728 729 switch (verb) { 730 /* all nodes */ 731 case AC_VERB_PARAMETERS: 732 param = hda_codec_find_param(node, payload); 733 if (param == NULL) { 734 goto fail; 735 } 736 hda_codec_response(hda, true, param->val); 737 break; 738 case AC_VERB_GET_SUBSYSTEM_ID: 739 hda_codec_response(hda, true, a->desc->iid); 740 break; 741 742 /* all functions */ 743 case AC_VERB_GET_CONNECT_LIST: 744 param = hda_codec_find_param(node, AC_PAR_CONNLIST_LEN); 745 count = param ? param->val : 0; 746 response = 0; 747 shift = 0; 748 while (payload < count && shift < 32) { 749 response |= node->conn[payload] << shift; 750 payload++; 751 shift += 8; 752 } 753 hda_codec_response(hda, true, response); 754 break; 755 756 /* pin widget */ 757 case AC_VERB_GET_CONFIG_DEFAULT: 758 hda_codec_response(hda, true, node->config); 759 break; 760 case AC_VERB_GET_PIN_WIDGET_CONTROL: 761 hda_codec_response(hda, true, node->pinctl); 762 break; 763 case AC_VERB_SET_PIN_WIDGET_CONTROL: 764 if (node->pinctl != payload) { 765 dprint(a, 1, "unhandled pin control bit\n"); 766 } 767 hda_codec_response(hda, true, 0); 768 break; 769 770 /* audio in/out widget */ 771 case AC_VERB_SET_CHANNEL_STREAMID: 772 st = a->st + node->stindex; 773 if (st->node == NULL) { 774 goto fail; 775 } 776 hda_audio_set_running(st, false); 777 st->stream = (payload >> 4) & 0x0f; 778 st->channel = payload & 0x0f; 779 dprint(a, 2, "%s: stream %d, channel %d\n", 780 st->node->name, st->stream, st->channel); 781 hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]); 782 hda_codec_response(hda, true, 0); 783 break; 784 case AC_VERB_GET_CONV: 785 st = a->st + node->stindex; 786 if (st->node == NULL) { 787 goto fail; 788 } 789 response = st->stream << 4 | st->channel; 790 hda_codec_response(hda, true, response); 791 break; 792 case AC_VERB_SET_STREAM_FORMAT: 793 st = a->st + node->stindex; 794 if (st->node == NULL) { 795 goto fail; 796 } 797 st->format = payload; 798 hda_codec_parse_fmt(st->format, &st->as); 799 hda_audio_setup(st); 800 hda_codec_response(hda, true, 0); 801 break; 802 case AC_VERB_GET_STREAM_FORMAT: 803 st = a->st + node->stindex; 804 if (st->node == NULL) { 805 goto fail; 806 } 807 hda_codec_response(hda, true, st->format); 808 break; 809 case AC_VERB_GET_AMP_GAIN_MUTE: 810 st = a->st + node->stindex; 811 if (st->node == NULL) { 812 goto fail; 813 } 814 if (payload & AC_AMP_GET_LEFT) { 815 response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0); 816 } else { 817 response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0); 818 } 819 hda_codec_response(hda, true, response); 820 break; 821 case AC_VERB_SET_AMP_GAIN_MUTE: 822 st = a->st + node->stindex; 823 if (st->node == NULL) { 824 goto fail; 825 } 826 dprint(a, 1, "amp (%s): %s%s%s%s index %d gain %3d %s\n", 827 st->node->name, 828 (payload & AC_AMP_SET_OUTPUT) ? "o" : "-", 829 (payload & AC_AMP_SET_INPUT) ? "i" : "-", 830 (payload & AC_AMP_SET_LEFT) ? "l" : "-", 831 (payload & AC_AMP_SET_RIGHT) ? "r" : "-", 832 (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT, 833 (payload & AC_AMP_GAIN), 834 (payload & AC_AMP_MUTE) ? "muted" : ""); 835 if (payload & AC_AMP_SET_LEFT) { 836 st->gain_left = payload & AC_AMP_GAIN; 837 st->mute_left = payload & AC_AMP_MUTE; 838 } 839 if (payload & AC_AMP_SET_RIGHT) { 840 st->gain_right = payload & AC_AMP_GAIN; 841 st->mute_right = payload & AC_AMP_MUTE; 842 } 843 hda_audio_set_amp(st); 844 hda_codec_response(hda, true, 0); 845 break; 846 847 /* not supported */ 848 case AC_VERB_SET_POWER_STATE: 849 case AC_VERB_GET_POWER_STATE: 850 case AC_VERB_GET_SDI_SELECT: 851 hda_codec_response(hda, true, 0); 852 break; 853 default: 854 goto fail; 855 } 856 return; 857 858 fail: 859 dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n", 860 __FUNCTION__, nid, node ? node->name : "?", verb, payload); 861 hda_codec_response(hda, true, 0); 862 } 863 864 static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output) 865 { 866 HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); 867 int s; 868 869 a->running_compat[stnr] = running; 870 a->running_real[output * 16 + stnr] = running; 871 for (s = 0; s < ARRAY_SIZE(a->st); s++) { 872 if (a->st[s].node == NULL) { 873 continue; 874 } 875 if (a->st[s].output != output) { 876 continue; 877 } 878 if (a->st[s].stream != stnr) { 879 continue; 880 } 881 hda_audio_set_running(&a->st[s], running); 882 } 883 } 884 885 static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc) 886 { 887 HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); 888 HDAAudioStream *st; 889 const desc_node *node; 890 const desc_param *param; 891 uint32_t i, type; 892 893 a->desc = desc; 894 a->name = object_get_typename(OBJECT(a)); 895 dprint(a, 1, "%s: cad %d\n", __FUNCTION__, a->hda.cad); 896 897 AUD_register_card("hda", &a->card); 898 for (i = 0; i < a->desc->nnodes; i++) { 899 node = a->desc->nodes + i; 900 param = hda_codec_find_param(node, AC_PAR_AUDIO_WIDGET_CAP); 901 if (NULL == param) 902 continue; 903 type = (param->val & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 904 switch (type) { 905 case AC_WID_AUD_OUT: 906 case AC_WID_AUD_IN: 907 assert(node->stindex < ARRAY_SIZE(a->st)); 908 st = a->st + node->stindex; 909 st->state = a; 910 st->node = node; 911 if (type == AC_WID_AUD_OUT) { 912 /* unmute output by default */ 913 st->gain_left = QEMU_HDA_AMP_STEPS; 914 st->gain_right = QEMU_HDA_AMP_STEPS; 915 st->bpos = sizeof(st->buf); 916 st->output = true; 917 } else { 918 st->output = false; 919 } 920 st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 | 921 (1 << AC_FMT_CHAN_SHIFT); 922 hda_codec_parse_fmt(st->format, &st->as); 923 hda_audio_setup(st); 924 break; 925 } 926 } 927 return 0; 928 } 929 930 static int hda_audio_exit(HDACodecDevice *hda) 931 { 932 HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); 933 HDAAudioStream *st; 934 int i; 935 936 dprint(a, 1, "%s\n", __FUNCTION__); 937 for (i = 0; i < ARRAY_SIZE(a->st); i++) { 938 st = a->st + i; 939 if (st->node == NULL) { 940 continue; 941 } 942 if (st->output) { 943 AUD_close_out(&a->card, st->voice.out); 944 } else { 945 AUD_close_in(&a->card, st->voice.in); 946 } 947 } 948 AUD_remove_card(&a->card); 949 return 0; 950 } 951 952 static int hda_audio_post_load(void *opaque, int version) 953 { 954 HDAAudioState *a = opaque; 955 HDAAudioStream *st; 956 int i; 957 958 dprint(a, 1, "%s\n", __FUNCTION__); 959 if (version == 1) { 960 /* assume running_compat[] is for output streams */ 961 for (i = 0; i < ARRAY_SIZE(a->running_compat); i++) 962 a->running_real[16 + i] = a->running_compat[i]; 963 } 964 965 for (i = 0; i < ARRAY_SIZE(a->st); i++) { 966 st = a->st + i; 967 if (st->node == NULL) 968 continue; 969 hda_codec_parse_fmt(st->format, &st->as); 970 hda_audio_setup(st); 971 hda_audio_set_amp(st); 972 hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]); 973 } 974 return 0; 975 } 976 977 static const VMStateDescription vmstate_hda_audio_stream = { 978 .name = "hda-audio-stream", 979 .version_id = 1, 980 .fields = (VMStateField []) { 981 VMSTATE_UINT32(stream, HDAAudioStream), 982 VMSTATE_UINT32(channel, HDAAudioStream), 983 VMSTATE_UINT32(format, HDAAudioStream), 984 VMSTATE_UINT32(gain_left, HDAAudioStream), 985 VMSTATE_UINT32(gain_right, HDAAudioStream), 986 VMSTATE_BOOL(mute_left, HDAAudioStream), 987 VMSTATE_BOOL(mute_right, HDAAudioStream), 988 VMSTATE_UINT32(bpos, HDAAudioStream), 989 VMSTATE_BUFFER(buf, HDAAudioStream), 990 VMSTATE_END_OF_LIST() 991 } 992 }; 993 994 static const VMStateDescription vmstate_hda_audio = { 995 .name = "hda-audio", 996 .version_id = 2, 997 .post_load = hda_audio_post_load, 998 .fields = (VMStateField []) { 999 VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0, 1000 vmstate_hda_audio_stream, 1001 HDAAudioStream), 1002 VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16), 1003 VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2), 1004 VMSTATE_END_OF_LIST() 1005 } 1006 }; 1007 1008 static Property hda_audio_properties[] = { 1009 DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0), 1010 DEFINE_PROP_END_OF_LIST(), 1011 }; 1012 1013 static int hda_audio_init_output(HDACodecDevice *hda) 1014 { 1015 return hda_audio_init(hda, &output); 1016 } 1017 1018 static int hda_audio_init_duplex(HDACodecDevice *hda) 1019 { 1020 return hda_audio_init(hda, &duplex); 1021 } 1022 1023 static int hda_audio_init_micro(HDACodecDevice *hda) 1024 { 1025 return hda_audio_init(hda, µ); 1026 } 1027 1028 static void hda_audio_output_class_init(ObjectClass *klass, void *data) 1029 { 1030 DeviceClass *dc = DEVICE_CLASS(klass); 1031 HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); 1032 1033 k->init = hda_audio_init_output; 1034 k->exit = hda_audio_exit; 1035 k->command = hda_audio_command; 1036 k->stream = hda_audio_stream; 1037 dc->desc = "HDA Audio Codec, output-only (line-out)"; 1038 dc->vmsd = &vmstate_hda_audio; 1039 dc->props = hda_audio_properties; 1040 } 1041 1042 static const TypeInfo hda_audio_output_info = { 1043 .name = "hda-output", 1044 .parent = TYPE_HDA_CODEC_DEVICE, 1045 .instance_size = sizeof(HDAAudioState), 1046 .class_init = hda_audio_output_class_init, 1047 }; 1048 1049 static void hda_audio_duplex_class_init(ObjectClass *klass, void *data) 1050 { 1051 DeviceClass *dc = DEVICE_CLASS(klass); 1052 HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); 1053 1054 k->init = hda_audio_init_duplex; 1055 k->exit = hda_audio_exit; 1056 k->command = hda_audio_command; 1057 k->stream = hda_audio_stream; 1058 dc->desc = "HDA Audio Codec, duplex (line-out, line-in)"; 1059 dc->vmsd = &vmstate_hda_audio; 1060 dc->props = hda_audio_properties; 1061 } 1062 1063 static const TypeInfo hda_audio_duplex_info = { 1064 .name = "hda-duplex", 1065 .parent = TYPE_HDA_CODEC_DEVICE, 1066 .instance_size = sizeof(HDAAudioState), 1067 .class_init = hda_audio_duplex_class_init, 1068 }; 1069 1070 static void hda_audio_micro_class_init(ObjectClass *klass, void *data) 1071 { 1072 DeviceClass *dc = DEVICE_CLASS(klass); 1073 HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); 1074 1075 k->init = hda_audio_init_micro; 1076 k->exit = hda_audio_exit; 1077 k->command = hda_audio_command; 1078 k->stream = hda_audio_stream; 1079 dc->desc = "HDA Audio Codec, duplex (speaker, microphone)"; 1080 dc->vmsd = &vmstate_hda_audio; 1081 dc->props = hda_audio_properties; 1082 } 1083 1084 static const TypeInfo hda_audio_micro_info = { 1085 .name = "hda-micro", 1086 .parent = TYPE_HDA_CODEC_DEVICE, 1087 .instance_size = sizeof(HDAAudioState), 1088 .class_init = hda_audio_micro_class_init, 1089 }; 1090 1091 static void hda_audio_register_types(void) 1092 { 1093 type_register_static(&hda_audio_output_info); 1094 type_register_static(&hda_audio_duplex_info); 1095 type_register_static(&hda_audio_micro_info); 1096 } 1097 1098 type_init(hda_audio_register_types) 1099