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