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