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 "qemu/osdep.h" 21 #include "hw/hw.h" 22 #include "hw/pci/pci.h" 23 #include "intel-hda.h" 24 #include "intel-hda-defs.h" 25 #include "audio/audio.h" 26 #include "trace.h" 27 28 /* -------------------------------------------------------------------------- */ 29 30 typedef struct desc_param { 31 uint32_t id; 32 uint32_t val; 33 } desc_param; 34 35 typedef struct desc_node { 36 uint32_t nid; 37 const char *name; 38 const desc_param *params; 39 uint32_t nparams; 40 uint32_t config; 41 uint32_t pinctl; 42 uint32_t *conn; 43 uint32_t stindex; 44 } desc_node; 45 46 typedef struct desc_codec { 47 const char *name; 48 uint32_t iid; 49 const desc_node *nodes; 50 uint32_t nnodes; 51 } desc_codec; 52 53 static const desc_param* hda_codec_find_param(const desc_node *node, uint32_t id) 54 { 55 int i; 56 57 for (i = 0; i < node->nparams; i++) { 58 if (node->params[i].id == id) { 59 return &node->params[i]; 60 } 61 } 62 return NULL; 63 } 64 65 static const desc_node* hda_codec_find_node(const desc_codec *codec, uint32_t nid) 66 { 67 int i; 68 69 for (i = 0; i < codec->nnodes; i++) { 70 if (codec->nodes[i].nid == nid) { 71 return &codec->nodes[i]; 72 } 73 } 74 return NULL; 75 } 76 77 static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as) 78 { 79 if (format & AC_FMT_TYPE_NON_PCM) { 80 return; 81 } 82 83 as->freq = (format & AC_FMT_BASE_44K) ? 44100 : 48000; 84 85 switch ((format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT) { 86 case 1: as->freq *= 2; break; 87 case 2: as->freq *= 3; break; 88 case 3: as->freq *= 4; break; 89 } 90 91 switch ((format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT) { 92 case 1: as->freq /= 2; break; 93 case 2: as->freq /= 3; break; 94 case 3: as->freq /= 4; break; 95 case 4: as->freq /= 5; break; 96 case 5: as->freq /= 6; break; 97 case 6: as->freq /= 7; break; 98 case 7: as->freq /= 8; break; 99 } 100 101 switch (format & AC_FMT_BITS_MASK) { 102 case AC_FMT_BITS_8: as->fmt = AUD_FMT_S8; break; 103 case AC_FMT_BITS_16: as->fmt = AUD_FMT_S16; break; 104 case AC_FMT_BITS_32: as->fmt = AUD_FMT_S32; break; 105 } 106 107 as->nchannels = ((format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT) + 1; 108 } 109 110 /* -------------------------------------------------------------------------- */ 111 /* 112 * HDA codec descriptions 113 */ 114 115 /* some defines */ 116 117 #define QEMU_HDA_ID_VENDOR 0x1af4 118 #define QEMU_HDA_PCM_FORMATS (AC_SUPPCM_BITS_16 | \ 119 0x1fc /* 16 -> 96 kHz */) 120 #define QEMU_HDA_AMP_NONE (0) 121 #define QEMU_HDA_AMP_STEPS 0x4a 122 123 #define PARAM mixemu 124 #define HDA_MIXER 125 #include "hda-codec-common.h" 126 127 #define PARAM nomixemu 128 #include "hda-codec-common.h" 129 130 #define HDA_TIMER_TICKS (SCALE_MS) 131 #define B_SIZE sizeof(st->buf) 132 #define B_MASK (sizeof(st->buf) - 1) 133 134 /* -------------------------------------------------------------------------- */ 135 136 static const char *fmt2name[] = { 137 [ AUD_FMT_U8 ] = "PCM-U8", 138 [ AUD_FMT_S8 ] = "PCM-S8", 139 [ AUD_FMT_U16 ] = "PCM-U16", 140 [ AUD_FMT_S16 ] = "PCM-S16", 141 [ AUD_FMT_U32 ] = "PCM-U32", 142 [ AUD_FMT_S32 ] = "PCM-S32", 143 }; 144 145 typedef struct HDAAudioState HDAAudioState; 146 typedef struct HDAAudioStream HDAAudioStream; 147 148 struct HDAAudioStream { 149 HDAAudioState *state; 150 const desc_node *node; 151 bool output, running; 152 uint32_t stream; 153 uint32_t channel; 154 uint32_t format; 155 uint32_t gain_left, gain_right; 156 bool mute_left, mute_right; 157 struct audsettings as; 158 union { 159 SWVoiceIn *in; 160 SWVoiceOut *out; 161 } voice; 162 uint8_t compat_buf[HDA_BUFFER_SIZE]; 163 uint32_t compat_bpos; 164 uint8_t buf[8192]; /* size must be power of two */ 165 int64_t rpos; 166 int64_t wpos; 167 QEMUTimer *buft; 168 int64_t buft_start; 169 }; 170 171 #define TYPE_HDA_AUDIO "hda-audio" 172 #define HDA_AUDIO(obj) OBJECT_CHECK(HDAAudioState, (obj), TYPE_HDA_AUDIO) 173 174 struct HDAAudioState { 175 HDACodecDevice hda; 176 const char *name; 177 178 QEMUSoundCard card; 179 const desc_codec *desc; 180 HDAAudioStream st[4]; 181 bool running_compat[16]; 182 bool running_real[2 * 16]; 183 184 /* properties */ 185 uint32_t debug; 186 bool mixer; 187 bool use_timer; 188 }; 189 190 static inline int64_t hda_bytes_per_second(HDAAudioStream *st) 191 { 192 return 2 * st->as.nchannels * st->as.freq; 193 } 194 195 static inline void hda_timer_sync_adjust(HDAAudioStream *st, int64_t target_pos) 196 { 197 int64_t limit = B_SIZE / 8; 198 int64_t corr = 0; 199 200 if (target_pos > limit) { 201 corr = HDA_TIMER_TICKS; 202 } 203 if (target_pos < -limit) { 204 corr = -HDA_TIMER_TICKS; 205 } 206 if (corr == 0) { 207 return; 208 } 209 210 trace_hda_audio_adjust(st->node->name, target_pos); 211 st->buft_start += corr; 212 } 213 214 static void hda_audio_input_timer(void *opaque) 215 { 216 HDAAudioStream *st = opaque; 217 218 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 219 220 int64_t buft_start = st->buft_start; 221 int64_t wpos = st->wpos; 222 int64_t rpos = st->rpos; 223 224 int64_t wanted_rpos = hda_bytes_per_second(st) * (now - buft_start) 225 / NANOSECONDS_PER_SECOND; 226 wanted_rpos &= -4; /* IMPORTANT! clip to frames */ 227 228 if (wanted_rpos <= rpos) { 229 /* we already transmitted the data */ 230 goto out_timer; 231 } 232 233 int64_t to_transfer = audio_MIN(wpos - rpos, wanted_rpos - rpos); 234 while (to_transfer) { 235 uint32_t start = (rpos & B_MASK); 236 uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer); 237 int rc = hda_codec_xfer( 238 &st->state->hda, st->stream, false, st->buf + start, chunk); 239 if (!rc) { 240 break; 241 } 242 rpos += chunk; 243 to_transfer -= chunk; 244 st->rpos += chunk; 245 } 246 247 out_timer: 248 249 if (st->running) { 250 timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS); 251 } 252 } 253 254 static void hda_audio_input_cb(void *opaque, int avail) 255 { 256 HDAAudioStream *st = opaque; 257 258 int64_t wpos = st->wpos; 259 int64_t rpos = st->rpos; 260 261 int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), avail); 262 263 hda_timer_sync_adjust(st, -((wpos - rpos) + to_transfer - (B_SIZE >> 1))); 264 265 while (to_transfer) { 266 uint32_t start = (uint32_t) (wpos & B_MASK); 267 uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer); 268 uint32_t read = AUD_read(st->voice.in, st->buf + start, chunk); 269 wpos += read; 270 to_transfer -= read; 271 st->wpos += read; 272 if (chunk != read) { 273 break; 274 } 275 } 276 } 277 278 static void hda_audio_output_timer(void *opaque) 279 { 280 HDAAudioStream *st = opaque; 281 282 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 283 284 int64_t buft_start = st->buft_start; 285 int64_t wpos = st->wpos; 286 int64_t rpos = st->rpos; 287 288 int64_t wanted_wpos = hda_bytes_per_second(st) * (now - buft_start) 289 / NANOSECONDS_PER_SECOND; 290 wanted_wpos &= -4; /* IMPORTANT! clip to frames */ 291 292 if (wanted_wpos <= wpos) { 293 /* we already received the data */ 294 goto out_timer; 295 } 296 297 int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), wanted_wpos - wpos); 298 while (to_transfer) { 299 uint32_t start = (wpos & B_MASK); 300 uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer); 301 int rc = hda_codec_xfer( 302 &st->state->hda, st->stream, true, st->buf + start, chunk); 303 if (!rc) { 304 break; 305 } 306 wpos += chunk; 307 to_transfer -= chunk; 308 st->wpos += chunk; 309 } 310 311 out_timer: 312 313 if (st->running) { 314 timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS); 315 } 316 } 317 318 static void hda_audio_output_cb(void *opaque, int avail) 319 { 320 HDAAudioStream *st = opaque; 321 322 int64_t wpos = st->wpos; 323 int64_t rpos = st->rpos; 324 325 int64_t to_transfer = audio_MIN(wpos - rpos, avail); 326 327 if (wpos - rpos == B_SIZE) { 328 /* drop buffer, reset timer adjust */ 329 st->rpos = 0; 330 st->wpos = 0; 331 st->buft_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 332 trace_hda_audio_overrun(st->node->name); 333 return; 334 } 335 336 hda_timer_sync_adjust(st, (wpos - rpos) - to_transfer - (B_SIZE >> 1)); 337 338 while (to_transfer) { 339 uint32_t start = (uint32_t) (rpos & B_MASK); 340 uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer); 341 uint32_t written = AUD_write(st->voice.out, st->buf + start, chunk); 342 rpos += written; 343 to_transfer -= written; 344 st->rpos += written; 345 if (chunk != written) { 346 break; 347 } 348 } 349 } 350 351 static void hda_audio_compat_input_cb(void *opaque, int avail) 352 { 353 HDAAudioStream *st = opaque; 354 int recv = 0; 355 int len; 356 bool rc; 357 358 while (avail - recv >= sizeof(st->compat_buf)) { 359 if (st->compat_bpos != sizeof(st->compat_buf)) { 360 len = AUD_read(st->voice.in, st->compat_buf + st->compat_bpos, 361 sizeof(st->compat_buf) - st->compat_bpos); 362 st->compat_bpos += len; 363 recv += len; 364 if (st->compat_bpos != sizeof(st->compat_buf)) { 365 break; 366 } 367 } 368 rc = hda_codec_xfer(&st->state->hda, st->stream, false, 369 st->compat_buf, sizeof(st->compat_buf)); 370 if (!rc) { 371 break; 372 } 373 st->compat_bpos = 0; 374 } 375 } 376 377 static void hda_audio_compat_output_cb(void *opaque, int avail) 378 { 379 HDAAudioStream *st = opaque; 380 int sent = 0; 381 int len; 382 bool rc; 383 384 while (avail - sent >= sizeof(st->compat_buf)) { 385 if (st->compat_bpos == sizeof(st->compat_buf)) { 386 rc = hda_codec_xfer(&st->state->hda, st->stream, true, 387 st->compat_buf, sizeof(st->compat_buf)); 388 if (!rc) { 389 break; 390 } 391 st->compat_bpos = 0; 392 } 393 len = AUD_write(st->voice.out, st->compat_buf + st->compat_bpos, 394 sizeof(st->compat_buf) - st->compat_bpos); 395 st->compat_bpos += len; 396 sent += len; 397 if (st->compat_bpos != sizeof(st->compat_buf)) { 398 break; 399 } 400 } 401 } 402 403 static void hda_audio_set_running(HDAAudioStream *st, bool running) 404 { 405 if (st->node == NULL) { 406 return; 407 } 408 if (st->running == running) { 409 return; 410 } 411 st->running = running; 412 trace_hda_audio_running(st->node->name, st->stream, st->running); 413 if (st->state->use_timer) { 414 if (running) { 415 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 416 st->rpos = 0; 417 st->wpos = 0; 418 st->buft_start = now; 419 timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS); 420 } else { 421 timer_del(st->buft); 422 } 423 } 424 if (st->output) { 425 AUD_set_active_out(st->voice.out, st->running); 426 } else { 427 AUD_set_active_in(st->voice.in, st->running); 428 } 429 } 430 431 static void hda_audio_set_amp(HDAAudioStream *st) 432 { 433 bool muted; 434 uint32_t left, right; 435 436 if (st->node == NULL) { 437 return; 438 } 439 440 muted = st->mute_left && st->mute_right; 441 left = st->mute_left ? 0 : st->gain_left; 442 right = st->mute_right ? 0 : st->gain_right; 443 444 left = left * 255 / QEMU_HDA_AMP_STEPS; 445 right = right * 255 / QEMU_HDA_AMP_STEPS; 446 447 if (!st->state->mixer) { 448 return; 449 } 450 if (st->output) { 451 AUD_set_volume_out(st->voice.out, muted, left, right); 452 } else { 453 AUD_set_volume_in(st->voice.in, muted, left, right); 454 } 455 } 456 457 static void hda_audio_setup(HDAAudioStream *st) 458 { 459 bool use_timer = st->state->use_timer; 460 audio_callback_fn cb; 461 462 if (st->node == NULL) { 463 return; 464 } 465 466 trace_hda_audio_format(st->node->name, st->as.nchannels, 467 fmt2name[st->as.fmt], st->as.freq); 468 469 if (st->output) { 470 if (use_timer) { 471 cb = hda_audio_output_cb; 472 st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL, 473 hda_audio_output_timer, st); 474 } else { 475 cb = hda_audio_compat_output_cb; 476 } 477 st->voice.out = AUD_open_out(&st->state->card, st->voice.out, 478 st->node->name, st, cb, &st->as); 479 } else { 480 if (use_timer) { 481 cb = hda_audio_input_cb; 482 st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL, 483 hda_audio_input_timer, st); 484 } else { 485 cb = hda_audio_compat_input_cb; 486 } 487 st->voice.in = AUD_open_in(&st->state->card, st->voice.in, 488 st->node->name, st, cb, &st->as); 489 } 490 } 491 492 static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data) 493 { 494 HDAAudioState *a = HDA_AUDIO(hda); 495 HDAAudioStream *st; 496 const desc_node *node = NULL; 497 const desc_param *param; 498 uint32_t verb, payload, response, count, shift; 499 500 if ((data & 0x70000) == 0x70000) { 501 /* 12/8 id/payload */ 502 verb = (data >> 8) & 0xfff; 503 payload = data & 0x00ff; 504 } else { 505 /* 4/16 id/payload */ 506 verb = (data >> 8) & 0xf00; 507 payload = data & 0xffff; 508 } 509 510 node = hda_codec_find_node(a->desc, nid); 511 if (node == NULL) { 512 goto fail; 513 } 514 dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n", 515 __func__, nid, node->name, verb, payload); 516 517 switch (verb) { 518 /* all nodes */ 519 case AC_VERB_PARAMETERS: 520 param = hda_codec_find_param(node, payload); 521 if (param == NULL) { 522 goto fail; 523 } 524 hda_codec_response(hda, true, param->val); 525 break; 526 case AC_VERB_GET_SUBSYSTEM_ID: 527 hda_codec_response(hda, true, a->desc->iid); 528 break; 529 530 /* all functions */ 531 case AC_VERB_GET_CONNECT_LIST: 532 param = hda_codec_find_param(node, AC_PAR_CONNLIST_LEN); 533 count = param ? param->val : 0; 534 response = 0; 535 shift = 0; 536 while (payload < count && shift < 32) { 537 response |= node->conn[payload] << shift; 538 payload++; 539 shift += 8; 540 } 541 hda_codec_response(hda, true, response); 542 break; 543 544 /* pin widget */ 545 case AC_VERB_GET_CONFIG_DEFAULT: 546 hda_codec_response(hda, true, node->config); 547 break; 548 case AC_VERB_GET_PIN_WIDGET_CONTROL: 549 hda_codec_response(hda, true, node->pinctl); 550 break; 551 case AC_VERB_SET_PIN_WIDGET_CONTROL: 552 if (node->pinctl != payload) { 553 dprint(a, 1, "unhandled pin control bit\n"); 554 } 555 hda_codec_response(hda, true, 0); 556 break; 557 558 /* audio in/out widget */ 559 case AC_VERB_SET_CHANNEL_STREAMID: 560 st = a->st + node->stindex; 561 if (st->node == NULL) { 562 goto fail; 563 } 564 hda_audio_set_running(st, false); 565 st->stream = (payload >> 4) & 0x0f; 566 st->channel = payload & 0x0f; 567 dprint(a, 2, "%s: stream %d, channel %d\n", 568 st->node->name, st->stream, st->channel); 569 hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]); 570 hda_codec_response(hda, true, 0); 571 break; 572 case AC_VERB_GET_CONV: 573 st = a->st + node->stindex; 574 if (st->node == NULL) { 575 goto fail; 576 } 577 response = st->stream << 4 | st->channel; 578 hda_codec_response(hda, true, response); 579 break; 580 case AC_VERB_SET_STREAM_FORMAT: 581 st = a->st + node->stindex; 582 if (st->node == NULL) { 583 goto fail; 584 } 585 st->format = payload; 586 hda_codec_parse_fmt(st->format, &st->as); 587 hda_audio_setup(st); 588 hda_codec_response(hda, true, 0); 589 break; 590 case AC_VERB_GET_STREAM_FORMAT: 591 st = a->st + node->stindex; 592 if (st->node == NULL) { 593 goto fail; 594 } 595 hda_codec_response(hda, true, st->format); 596 break; 597 case AC_VERB_GET_AMP_GAIN_MUTE: 598 st = a->st + node->stindex; 599 if (st->node == NULL) { 600 goto fail; 601 } 602 if (payload & AC_AMP_GET_LEFT) { 603 response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0); 604 } else { 605 response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0); 606 } 607 hda_codec_response(hda, true, response); 608 break; 609 case AC_VERB_SET_AMP_GAIN_MUTE: 610 st = a->st + node->stindex; 611 if (st->node == NULL) { 612 goto fail; 613 } 614 dprint(a, 1, "amp (%s): %s%s%s%s index %d gain %3d %s\n", 615 st->node->name, 616 (payload & AC_AMP_SET_OUTPUT) ? "o" : "-", 617 (payload & AC_AMP_SET_INPUT) ? "i" : "-", 618 (payload & AC_AMP_SET_LEFT) ? "l" : "-", 619 (payload & AC_AMP_SET_RIGHT) ? "r" : "-", 620 (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT, 621 (payload & AC_AMP_GAIN), 622 (payload & AC_AMP_MUTE) ? "muted" : ""); 623 if (payload & AC_AMP_SET_LEFT) { 624 st->gain_left = payload & AC_AMP_GAIN; 625 st->mute_left = payload & AC_AMP_MUTE; 626 } 627 if (payload & AC_AMP_SET_RIGHT) { 628 st->gain_right = payload & AC_AMP_GAIN; 629 st->mute_right = payload & AC_AMP_MUTE; 630 } 631 hda_audio_set_amp(st); 632 hda_codec_response(hda, true, 0); 633 break; 634 635 /* not supported */ 636 case AC_VERB_SET_POWER_STATE: 637 case AC_VERB_GET_POWER_STATE: 638 case AC_VERB_GET_SDI_SELECT: 639 hda_codec_response(hda, true, 0); 640 break; 641 default: 642 goto fail; 643 } 644 return; 645 646 fail: 647 dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n", 648 __func__, nid, node ? node->name : "?", verb, payload); 649 hda_codec_response(hda, true, 0); 650 } 651 652 static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output) 653 { 654 HDAAudioState *a = HDA_AUDIO(hda); 655 int s; 656 657 a->running_compat[stnr] = running; 658 a->running_real[output * 16 + stnr] = running; 659 for (s = 0; s < ARRAY_SIZE(a->st); s++) { 660 if (a->st[s].node == NULL) { 661 continue; 662 } 663 if (a->st[s].output != output) { 664 continue; 665 } 666 if (a->st[s].stream != stnr) { 667 continue; 668 } 669 hda_audio_set_running(&a->st[s], running); 670 } 671 } 672 673 static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc) 674 { 675 HDAAudioState *a = HDA_AUDIO(hda); 676 HDAAudioStream *st; 677 const desc_node *node; 678 const desc_param *param; 679 uint32_t i, type; 680 681 a->desc = desc; 682 a->name = object_get_typename(OBJECT(a)); 683 dprint(a, 1, "%s: cad %d\n", __func__, a->hda.cad); 684 685 AUD_register_card("hda", &a->card); 686 for (i = 0; i < a->desc->nnodes; i++) { 687 node = a->desc->nodes + i; 688 param = hda_codec_find_param(node, AC_PAR_AUDIO_WIDGET_CAP); 689 if (param == NULL) { 690 continue; 691 } 692 type = (param->val & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 693 switch (type) { 694 case AC_WID_AUD_OUT: 695 case AC_WID_AUD_IN: 696 assert(node->stindex < ARRAY_SIZE(a->st)); 697 st = a->st + node->stindex; 698 st->state = a; 699 st->node = node; 700 if (type == AC_WID_AUD_OUT) { 701 /* unmute output by default */ 702 st->gain_left = QEMU_HDA_AMP_STEPS; 703 st->gain_right = QEMU_HDA_AMP_STEPS; 704 st->compat_bpos = sizeof(st->compat_buf); 705 st->output = true; 706 } else { 707 st->output = false; 708 } 709 st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 | 710 (1 << AC_FMT_CHAN_SHIFT); 711 hda_codec_parse_fmt(st->format, &st->as); 712 hda_audio_setup(st); 713 break; 714 } 715 } 716 return 0; 717 } 718 719 static void hda_audio_exit(HDACodecDevice *hda) 720 { 721 HDAAudioState *a = HDA_AUDIO(hda); 722 HDAAudioStream *st; 723 int i; 724 725 dprint(a, 1, "%s\n", __func__); 726 for (i = 0; i < ARRAY_SIZE(a->st); i++) { 727 st = a->st + i; 728 if (st->node == NULL) { 729 continue; 730 } 731 if (a->use_timer) { 732 timer_del(st->buft); 733 } 734 if (st->output) { 735 AUD_close_out(&a->card, st->voice.out); 736 } else { 737 AUD_close_in(&a->card, st->voice.in); 738 } 739 } 740 AUD_remove_card(&a->card); 741 } 742 743 static int hda_audio_post_load(void *opaque, int version) 744 { 745 HDAAudioState *a = opaque; 746 HDAAudioStream *st; 747 int i; 748 749 dprint(a, 1, "%s\n", __func__); 750 if (version == 1) { 751 /* assume running_compat[] is for output streams */ 752 for (i = 0; i < ARRAY_SIZE(a->running_compat); i++) 753 a->running_real[16 + i] = a->running_compat[i]; 754 } 755 756 for (i = 0; i < ARRAY_SIZE(a->st); i++) { 757 st = a->st + i; 758 if (st->node == NULL) 759 continue; 760 hda_codec_parse_fmt(st->format, &st->as); 761 hda_audio_setup(st); 762 hda_audio_set_amp(st); 763 hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]); 764 } 765 return 0; 766 } 767 768 static void hda_audio_reset(DeviceState *dev) 769 { 770 HDAAudioState *a = HDA_AUDIO(dev); 771 HDAAudioStream *st; 772 int i; 773 774 dprint(a, 1, "%s\n", __func__); 775 for (i = 0; i < ARRAY_SIZE(a->st); i++) { 776 st = a->st + i; 777 if (st->node != NULL) { 778 hda_audio_set_running(st, false); 779 } 780 } 781 } 782 783 static bool vmstate_hda_audio_stream_buf_needed(void *opaque) 784 { 785 HDAAudioStream *st = opaque; 786 return st->state->use_timer; 787 } 788 789 static const VMStateDescription vmstate_hda_audio_stream_buf = { 790 .name = "hda-audio-stream/buffer", 791 .version_id = 1, 792 .needed = vmstate_hda_audio_stream_buf_needed, 793 .fields = (VMStateField[]) { 794 VMSTATE_BUFFER(buf, HDAAudioStream), 795 VMSTATE_INT64(rpos, HDAAudioStream), 796 VMSTATE_INT64(wpos, HDAAudioStream), 797 VMSTATE_TIMER_PTR(buft, HDAAudioStream), 798 VMSTATE_INT64(buft_start, HDAAudioStream), 799 VMSTATE_END_OF_LIST() 800 } 801 }; 802 803 static const VMStateDescription vmstate_hda_audio_stream = { 804 .name = "hda-audio-stream", 805 .version_id = 1, 806 .fields = (VMStateField[]) { 807 VMSTATE_UINT32(stream, HDAAudioStream), 808 VMSTATE_UINT32(channel, HDAAudioStream), 809 VMSTATE_UINT32(format, HDAAudioStream), 810 VMSTATE_UINT32(gain_left, HDAAudioStream), 811 VMSTATE_UINT32(gain_right, HDAAudioStream), 812 VMSTATE_BOOL(mute_left, HDAAudioStream), 813 VMSTATE_BOOL(mute_right, HDAAudioStream), 814 VMSTATE_UINT32(compat_bpos, HDAAudioStream), 815 VMSTATE_BUFFER(compat_buf, HDAAudioStream), 816 VMSTATE_END_OF_LIST() 817 }, 818 .subsections = (const VMStateDescription * []) { 819 &vmstate_hda_audio_stream_buf, 820 NULL 821 } 822 }; 823 824 static const VMStateDescription vmstate_hda_audio = { 825 .name = "hda-audio", 826 .version_id = 2, 827 .post_load = hda_audio_post_load, 828 .fields = (VMStateField[]) { 829 VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0, 830 vmstate_hda_audio_stream, 831 HDAAudioStream), 832 VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16), 833 VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2), 834 VMSTATE_END_OF_LIST() 835 } 836 }; 837 838 static Property hda_audio_properties[] = { 839 DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0), 840 DEFINE_PROP_BOOL("mixer", HDAAudioState, mixer, true), 841 DEFINE_PROP_BOOL("use-timer", HDAAudioState, use_timer, true), 842 DEFINE_PROP_END_OF_LIST(), 843 }; 844 845 static int hda_audio_init_output(HDACodecDevice *hda) 846 { 847 HDAAudioState *a = HDA_AUDIO(hda); 848 849 if (!a->mixer) { 850 return hda_audio_init(hda, &output_nomixemu); 851 } else { 852 return hda_audio_init(hda, &output_mixemu); 853 } 854 } 855 856 static int hda_audio_init_duplex(HDACodecDevice *hda) 857 { 858 HDAAudioState *a = HDA_AUDIO(hda); 859 860 if (!a->mixer) { 861 return hda_audio_init(hda, &duplex_nomixemu); 862 } else { 863 return hda_audio_init(hda, &duplex_mixemu); 864 } 865 } 866 867 static int hda_audio_init_micro(HDACodecDevice *hda) 868 { 869 HDAAudioState *a = HDA_AUDIO(hda); 870 871 if (!a->mixer) { 872 return hda_audio_init(hda, µ_nomixemu); 873 } else { 874 return hda_audio_init(hda, µ_mixemu); 875 } 876 } 877 878 static void hda_audio_base_class_init(ObjectClass *klass, void *data) 879 { 880 DeviceClass *dc = DEVICE_CLASS(klass); 881 HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); 882 883 k->exit = hda_audio_exit; 884 k->command = hda_audio_command; 885 k->stream = hda_audio_stream; 886 set_bit(DEVICE_CATEGORY_SOUND, dc->categories); 887 dc->reset = hda_audio_reset; 888 dc->vmsd = &vmstate_hda_audio; 889 dc->props = hda_audio_properties; 890 } 891 892 static const TypeInfo hda_audio_info = { 893 .name = TYPE_HDA_AUDIO, 894 .parent = TYPE_HDA_CODEC_DEVICE, 895 .class_init = hda_audio_base_class_init, 896 .abstract = true, 897 }; 898 899 static void hda_audio_output_class_init(ObjectClass *klass, void *data) 900 { 901 DeviceClass *dc = DEVICE_CLASS(klass); 902 HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); 903 904 k->init = hda_audio_init_output; 905 dc->desc = "HDA Audio Codec, output-only (line-out)"; 906 } 907 908 static const TypeInfo hda_audio_output_info = { 909 .name = "hda-output", 910 .parent = TYPE_HDA_AUDIO, 911 .instance_size = sizeof(HDAAudioState), 912 .class_init = hda_audio_output_class_init, 913 }; 914 915 static void hda_audio_duplex_class_init(ObjectClass *klass, void *data) 916 { 917 DeviceClass *dc = DEVICE_CLASS(klass); 918 HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); 919 920 k->init = hda_audio_init_duplex; 921 dc->desc = "HDA Audio Codec, duplex (line-out, line-in)"; 922 } 923 924 static const TypeInfo hda_audio_duplex_info = { 925 .name = "hda-duplex", 926 .parent = TYPE_HDA_AUDIO, 927 .instance_size = sizeof(HDAAudioState), 928 .class_init = hda_audio_duplex_class_init, 929 }; 930 931 static void hda_audio_micro_class_init(ObjectClass *klass, void *data) 932 { 933 DeviceClass *dc = DEVICE_CLASS(klass); 934 HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); 935 936 k->init = hda_audio_init_micro; 937 dc->desc = "HDA Audio Codec, duplex (speaker, microphone)"; 938 } 939 940 static const TypeInfo hda_audio_micro_info = { 941 .name = "hda-micro", 942 .parent = TYPE_HDA_AUDIO, 943 .instance_size = sizeof(HDAAudioState), 944 .class_init = hda_audio_micro_class_init, 945 }; 946 947 static void hda_audio_register_types(void) 948 { 949 type_register_static(&hda_audio_info); 950 type_register_static(&hda_audio_output_info); 951 type_register_static(&hda_audio_duplex_info); 952 type_register_static(&hda_audio_micro_info); 953 } 954 955 type_init(hda_audio_register_types) 956