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