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