VirtualBox

Changeset 60353 in vbox for trunk


Ignore:
Timestamp:
Apr 6, 2016 11:54:39 AM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
106428
Message:

Audio: Added HDA support for newer Linux guests; more work on surround support (disabled by default).

Location:
trunk
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmaudioifs.h

    r59987 r60353  
    109109} PDMAUDIOENDIANNESS;
    110110
     111/**
     112 * Audio direction.
     113 */
     114typedef enum PDMAUDIODIR
     115{
     116    PDMAUDIODIR_UNKNOWN    = 0,
     117    PDMAUDIODIR_IN         = 1,
     118    PDMAUDIODIR_OUT        = 2,
     119    PDMAUDIODIR_DUPLEX     = 3,
     120    /** Hack to blow the type up to 32-bit. */
     121    PDMAUDIODIR_32BIT_HACK = 0x7fffffff
     122} PDMAUDIODIR;
     123
     124/**
     125 * Audio playback destinations.
     126 */
     127typedef enum PDMAUDIOPLAYBACKDEST
     128{
     129    PDMAUDIOPLAYBACKDEST_UNKNOWN = 0,
     130    PDMAUDIOPLAYBACKDEST_FRONT,
     131    PDMAUDIOPLAYBACKDEST_CENTER_LFE,
     132    PDMAUDIOPLAYBACKDEST_REAR,
     133    /** Hack to blow the type up to 32-bit. */
     134    PDMAUDIOPLAYBACKDEST_32BIT_HACK = 0x7fffffff
     135} PDMAUDIOPLAYBACKDEST;
     136
     137/**
     138 * Audio recording sources.
     139 */
     140typedef enum PDMAUDIORECSOURCE
     141{
     142    PDMAUDIORECSOURCE_UNKNOWN = 0,
     143    PDMAUDIORECSOURCE_MIC,
     144    PDMAUDIORECSOURCE_CD,
     145    PDMAUDIORECSOURCE_VIDEO,
     146    PDMAUDIORECSOURCE_AUX,
     147    PDMAUDIORECSOURCE_LINE,
     148    PDMAUDIORECSOURCE_PHONE,
     149    /** Hack to blow the type up to 32-bit. */
     150    PDMAUDIORECSOURCE_32BIT_HACK = 0x7fffffff
     151} PDMAUDIORECSOURCE;
     152
     153/**
     154 * Structure for keeping an audio stream configuration.
     155 */
    111156typedef struct PDMAUDIOSTREAMCFG
    112157{
     158    /** Friendly name of the stream. */
     159    char                    *pszName;
     160    /** Direction of the stream. */
     161    PDMAUDIODIR              enmDir;
     162    union
     163    {
     164        /** Desired playback destination (for an output stream). */
     165        PDMAUDIOPLAYBACKDEST Dest;
     166        /** Desired recording source (for an input stream). */
     167        PDMAUDIORECSOURCE    Source;
     168    } DestSource;
    113169    /** Frequency in Hertz (Hz). */
    114     uint32_t uHz;
    115     /** Number of channels (2 for stereo). */
    116     uint8_t cChannels;
     170    uint32_t                 uHz;
     171    /** Number of channels (2 for stereo, 1 for mono). */
     172    uint8_t                  cChannels;
    117173    /** Audio format. */
    118     PDMAUDIOFMT enmFormat;
     174    PDMAUDIOFMT              enmFormat;
    119175    /** @todo Use RT_LE2H_*? */
    120     PDMAUDIOENDIANNESS enmEndianness;
     176    PDMAUDIOENDIANNESS       enmEndianness;
    121177} PDMAUDIOSTREAMCFG, *PPDMAUDIOSTREAMCFG;
    122178
     
    130186
    131187/**
    132  * Audio direction.
    133  */
    134 typedef enum PDMAUDIODIR
    135 {
    136     PDMAUDIODIR_UNKNOWN    = 0,
    137     PDMAUDIODIR_IN         = 1,
    138     PDMAUDIODIR_OUT        = 2,
    139     PDMAUDIODIR_DUPLEX     = 3,
    140     /** Hack to blow the type up to 32-bit. */
    141     PDMAUDIODIR_32BIT_HACK = 0x7fffffff
    142 } PDMAUDIODIR;
    143 
    144 /**
    145188 * Audio mixer controls.
    146189 */
     
    149192    PDMAUDIOMIXERCTL_UNKNOWN = 0,
    150193    PDMAUDIOMIXERCTL_VOLUME,
    151     PDMAUDIOMIXERCTL_PCM,
     194    PDMAUDIOMIXERCTL_FRONT,
     195    PDMAUDIOMIXERCTL_CENTER_LFE,
     196    PDMAUDIOMIXERCTL_REAR,
    152197    PDMAUDIOMIXERCTL_LINE_IN,
    153198    PDMAUDIOMIXERCTL_MIC_IN,
     
    155200    PDMAUDIOMIXERCTL_32BIT_HACK = 0x7fffffff
    156201} PDMAUDIOMIXERCTL;
    157 
    158 /**
    159  * Audio recording sources.
    160  */
    161 typedef enum PDMAUDIORECSOURCE
    162 {
    163     PDMAUDIORECSOURCE_UNKNOWN = 0,
    164     PDMAUDIORECSOURCE_MIC,
    165     PDMAUDIORECSOURCE_CD,
    166     PDMAUDIORECSOURCE_VIDEO,
    167     PDMAUDIORECSOURCE_AUX,
    168     PDMAUDIORECSOURCE_LINE_IN,
    169     PDMAUDIORECSOURCE_PHONE,
    170     /** Hack to blow the type up to 32-bit. */
    171     PDMAUDIORECSOURCE_32BIT_HACK = 0x7fffffff
    172 } PDMAUDIORECSOURCE;
    173202
    174203/**
     
    586615     * @returns VBox status code.
    587616     * @param   pInterface           Pointer to the interface structure containing the called function pointer.
    588      * @param   pszName              Name of the audio channel.
    589      * @param   enmRecSource         Specifies the type of recording source to be opened.
     617     * @param   pszName              Friendly name of this input stream.
    590618     * @param   pCfg                 Pointer to PDMAUDIOSTREAMCFG to use.
    591619     * @param   ppGstStrmIn          Pointer where to return the guest guest input stream on success.
    592620     */
    593621    DECLR3CALLBACKMEMBER(int, pfnCreateIn, (PPDMIAUDIOCONNECTOR pInterface, const char *pszName,
    594                                             PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg,
    595                                             PPDMAUDIOGSTSTRMIN *ppGstStrmIn));
     622                                            PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOGSTSTRMIN *ppGstStrmIn));
    596623    /**
    597624     * Creates a guest output stream.
     
    599626     * @returns VBox status code.
    600627     * @param   pInterface           Pointer to the interface structure containing the called function pointer.
    601      * @param   pszName              Name of the audio channel.
     628     * @param   pszName              Friendly name of this output stream.
    602629     * @param   pCfg                 Pointer to PDMAUDIOSTREAMCFG to use.
    603630     * @param   ppGstStrmOut         Pointer where to return the guest guest input stream on success.
     
    639666
    640667/** PDMIAUDIOCONNECTOR interface ID. */
    641 #define PDMIAUDIOCONNECTOR_IID                  "8f8ca10e-9039-423c-9a77-0014aaa98626"
     668#define PDMIAUDIOCONNECTOR_IID                  "f0ef4012-ae89-4528-9dad-4ef496894df8"
    642669
    643670
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp

    r57451 r60353  
    66
    77/*
    8  * Copyright (C) 2014-2015 Oracle Corporation
     8 * Copyright (C) 2014-2016 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1919#include <VBox/log.h>
    2020
     21#if 0
    2122/*
    2223 * DEBUG_DUMP_PCM_DATA enables dumping the raw PCM data
     
    2425 * to your needs before using this!
    2526 */
    26 #ifdef DEBUG
    27 //# define DEBUG_DUMP_PCM_DATA
    28 # define DEBUG_DUMP_PCM_DATA_PATH "c:\\temp\\"
     27# define AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
     28# ifdef RT_OS_WINDOWS
     29#  define AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "c:\\temp\\"
     30# else
     31#  define AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "/tmp/"
     32# endif
     33/* Warning: Enabling this will generate *huge* logs! */
     34//# define AUDIOMIXBUF_DEBUG_MACROS
    2935#endif
    3036
    3137#include <iprt/asm-math.h>
    3238#include <iprt/assert.h>
    33 #ifdef DEBUG_DUMP_PCM_DATA
     39#ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
    3440# include <iprt/file.h>
    3541#endif
     
    3743#include <iprt/string.h> /* For RT_BZERO. */
    3844
    39 #ifdef TESTCASE
     45#ifdef VBOX_AUDIO_TESTCASE
    4046# define LOG_ENABLED
    4147# include <iprt/stream.h>
     
    4551#include "AudioMixBuffer.h"
    4652
    47 #if 0
    48 # define AUDMIXBUF_LOG(x) LogFlowFunc(x)
    49 #else
    50 # if defined(TESTCASE)
    51 #  define AUDMIXBUF_LOG(x) LogFunc(x)
     53#ifndef VBOX_AUDIO_TESTCASE
     54# ifdef DEBUG
     55#  define AUDMIXBUF_LOG(x) LogFlowFunc(x)
    5256# else
    53 #  define AUDMIXBUF_LOG(x) do {} while (0)
     57# define AUDMIXBUF_LOG(x) do {} while (0)
    5458# endif
     59#else /* VBOX_AUDIO_TESTCASE */
     60# define AUDMIXBUF_LOG(x) RTPrintf x
    5561#endif
    5662
     
    144150 * inlined + static.
    145151 */
    146 #ifdef TESTCASE
     152#ifdef VBOX_AUDIO_TESTCASE
    147153# define AUDMIXBUF_MACRO_FN
    148154#else
     
    404410}
    405411
    406 /** Note: Enabling this will generate huge logs! */
    407 //#define DEBUG_MACROS
    408 
    409 #ifdef DEBUG_MACROS
     412#ifdef AUDIOMIXBUF_DEBUG_MACROS
    410413# define AUDMIXBUF_MACRO_LOG(x) AUDMIXBUF_LOG(x)
    411 #elif defined(TESTCASE)
     414#elif defined(VBOX_AUDIO_TESTCASE_VERBOSE) /* Warning: VBOX_AUDIO_TESTCASE_VERBOSE will generate huge logs! */
    412415# define AUDMIXBUF_MACRO_LOG(x) RTPrintf x
    413416#else
     
    449452        _aType *pSrc = (_aType *)pvSrc; \
    450453        uint32_t cSamples = (uint32_t)RT_MIN(pOpts->cSamples, cbSrc / sizeof(_aType)); \
    451         AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, sizeof(%zu), lVol=%RU32, rVol=%RU32\n", \
     454        AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, BpS=%zu, lVol=%RU32, rVol=%RU32\n", \
    452455                             pOpts->cSamples, sizeof(_aType), pOpts->Volume.uLeft, pOpts->Volume.uRight)); \
    453456        for (uint32_t i = 0; i < cSamples; i++) \
    454457        { \
    455             AUDMIXBUF_MACRO_LOG(("%p: l=%RI16, r=%RI16\n", paDst, *pSrc, *(pSrc + 1))); \
     458            AUDMIXBUF_MACRO_LOG(("l=%#5RI16 (0x%x), r=%#5RI16 (0x%x)", paDst, *pSrc, *pSrc, *(pSrc + 1), *(pSrc + 1))); \
    456459            paDst->i64LSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc++), pOpts->Volume.uLeft ) >> AUDIOMIXBUF_VOL_SHIFT; \
    457460            paDst->i64RSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc++), pOpts->Volume.uRight) >> AUDIOMIXBUF_VOL_SHIFT; \
    458             AUDMIXBUF_MACRO_LOG(("\t-> l=%RI64, r=%RI64\n", paDst->i64LSample, paDst->i64RSample)); \
     461            AUDMIXBUF_MACRO_LOG((" -> l=%#10RI64, r=%#10RI64\n", paDst->i64LSample, paDst->i64RSample)); \
    459462            paDst++; \
    460463        } \
     
    467470    { \
    468471        _aType *pSrc = (_aType *)pvSrc; \
    469         uint32_t cSamples = (uint32_t)RT_MIN(pOpts->cSamples, cbSrc / sizeof(_aType)); \
    470         AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, sizeof(%zu), lVol=%RU32, rVol=%RU32\n", \
    471                              cSamples, sizeof(_aType), pOpts->Volume.uLeft, pOpts->Volume.uRight)); \
     472        const uint32_t cSamples = (uint32_t)RT_MIN(pOpts->cSamples, cbSrc / sizeof(_aType)); \
     473        AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, BpS=%zu, lVol=%RU32, rVol=%RU32\n", \
     474                             cSamples, sizeof(_aType), pOpts->Volume.uLeft >> 14, pOpts->Volume.uRight)); \
    472475        for (uint32_t i = 0; i < cSamples; i++) \
    473476        { \
    474             AUDMIXBUF_MACRO_LOG(("%p: s=%RI16\n", paDst, *pSrc)); \
    475477            paDst->i64LSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc), pOpts->Volume.uLeft)  >> AUDIOMIXBUF_VOL_SHIFT; \
    476478            paDst->i64RSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc), pOpts->Volume.uRight) >> AUDIOMIXBUF_VOL_SHIFT; \
    477             ++pSrc; \
    478             AUDMIXBUF_MACRO_LOG(("\t-> l=%RI64, r=%RI64\n", paDst->i64LSample, paDst->i64RSample)); \
     479            AUDMIXBUF_MACRO_LOG(("%#5RI16 (0x%x) -> l=%#10RI64, r=%#10RI64\n", *pSrc, *pSrc, paDst->i64LSample, paDst->i64RSample)); \
     480            pSrc++; \
    479481            paDst++; \
    480482        } \
     
    537539    { \
    538540        AUDMIXBUF_MACRO_LOG(("cSrcSamples=%RU32, cDstSamples=%RU32\n", cSrcSamples, cDstSamples)); \
    539         AUDMIXBUF_MACRO_LOG(("pRate=%p: srcOffset=0x%RX32 (%RU32), dstOffset=0x%RX32 (%RU32), dstInc=0x%RX64 (%RU64)\n", \
    540                              pRate, pRate->srcOffset, pRate->srcOffset, \
    541                              (uint32_t)(pRate->dstOffset >> 32), (uint32_t)(pRate->dstOffset >> 32), \
    542                              pRate->dstInc, pRate->dstInc)); \
     541        AUDMIXBUF_MACRO_LOG(("Rate: srcOffset=%RU32, dstOffset=%RU32, dstInc=%RU32\n", \
     542                             pRate->srcOffset, \
     543                             (uint32_t)(pRate->dstOffset >> 32), (uint32_t)(pRate->dstInc >> 32))); \
    543544        \
    544545        if (pRate->dstInc == (UINT64_C(1) + UINT32_MAX)) /* No conversion needed? */ \
     
    563564        PPDMAUDIOSAMPLE paDstStart = paDst; \
    564565        PPDMAUDIOSAMPLE paDstEnd   = paDst + cDstSamples; \
    565         PDMAUDIOSAMPLE  samCur = { 0 }; \
     566        PDMAUDIOSAMPLE  samCur     = { 0 }; \
    566567        PDMAUDIOSAMPLE  samOut; \
    567568        PDMAUDIOSAMPLE  samLast    = pRate->srcSampleLast; \
    568         uint64_t        lDelta = 0; \
    569         \
    570         AUDMIXBUF_MACRO_LOG(("Start: paDstEnd=%p - paDstStart=%p -> %zu\n", paDstEnd, paDst, paDstEnd - paDstStart)); \
    571         AUDMIXBUF_MACRO_LOG(("Start: paSrcEnd=%p - paSrcStart=%p -> %zu\n", paSrcEnd, paSrc, paSrcEnd - paSrcStart)); \
    572569        \
    573570        while (paDst < paDstEnd) \
     
    575572            Assert(paSrc <= paSrcEnd); \
    576573            Assert(paDst <= paDstEnd); \
    577             if (paSrc == paSrcEnd) \
     574            if (paSrc >= paSrcEnd) \
    578575                break; \
    579576            \
    580             lDelta = 0; \
    581577            while (pRate->srcOffset <= (pRate->dstOffset >> 32)) \
    582578            { \
     
    584580                samLast = *paSrc++; \
    585581                pRate->srcOffset++; \
    586                 lDelta++; \
    587582                if (paSrc == paSrcEnd) \
    588583                    break; \
     
    604599            paDst->i64RSample _aOp samOut.i64RSample; \
    605600            \
    606             AUDMIXBUF_MACRO_LOG(("\tlDelta=0x%RX64 (%RU64), iDstOffInt=0x%RX64 (%RI64), l=%RI64, r=%RI64 (cur l=%RI64, r=%RI64)\n", \
    607                                  lDelta, lDelta, iDstOffInt, iDstOffInt, \
    608                                  paDst->i64LSample, paDst->i64RSample, \
    609                                  samCur.i64LSample, samCur.i64RSample)); \
     601            AUDMIXBUF_MACRO_LOG(("\tiDstOffInt=%RI64, l=%RI64, r=%RI64 (cur l=%RI64, r=%RI64)\n", \
     602                                 iDstOffInt, \
     603                                 paDst->i64LSample >> 32, paDst->i64RSample >> 32, \
     604                                 samCur.i64LSample >> 32, samCur.i64RSample >> 32)); \
    610605            \
    611606            paDst++; \
    612607            pRate->dstOffset += pRate->dstInc; \
    613608            \
    614             AUDMIXBUF_MACRO_LOG(("\t\tpRate->dstOffset=0x%RX32 (%RU32)\n", pRate->dstOffset, pRate->dstOffset >> 32)); \
     609            AUDMIXBUF_MACRO_LOG(("\t\tpRate->dstOffset=%RU32\n", pRate->dstOffset >> 32)); \
    615610            \
    616611        } \
    617612        \
    618         AUDMIXBUF_MACRO_LOG(("End: paDst=%p - paDstStart=%p -> %zu\n", paDst, paDstStart, paDst - paDstStart)); \
    619         AUDMIXBUF_MACRO_LOG(("End: paSrc=%p - paSrcStart=%p -> %zu\n", paSrc, paSrcStart, paSrc - paSrcStart)); \
     613        AUDMIXBUF_MACRO_LOG(("%zu source samples -> %zu dest samples\n", paSrc - paSrcStart, paDst - paDstStart)); \
    620614        \
    621615        pRate->srcSampleLast = samLast; \
    622616        \
    623         AUDMIXBUF_MACRO_LOG(("pRate->srcSampleLast l=%RI64, r=%RI64, lDelta=0x%RX64 (%RU64)\n", \
    624                               pRate->srcSampleLast.i64LSample, pRate->srcSampleLast.i64RSample, lDelta, lDelta)); \
     617        AUDMIXBUF_MACRO_LOG(("pRate->srcSampleLast l=%RI64, r=%RI64\n", \
     618                              pRate->srcSampleLast.i64LSample, pRate->srcSampleLast.i64RSample)); \
    625619        \
    626620        if (pcDstWritten) \
     
    643637{
    644638    /* Internally zero always corresponds to silence. */
    645     memset(paDst, 0, pOpts->cSamples * sizeof(paDst[0]));
     639    RT_BZERO(paDst, pOpts->cSamples * sizeof(paDst[0]));
    646640    return pOpts->cSamples;
    647641}
     
    674668            }
    675669        }
    676         else if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 1)
     670        else
    677671        {
    678672            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
     
    697691            }
    698692        }
    699         else if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 1)
     693        else
    700694        {
    701695            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
     
    735729            }
    736730        }
    737         else if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 1)
     731        else
    738732        {
    739733            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
     
    758752            }
    759753        }
    760         else if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 1)
     754        else
    761755        {
    762756            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
     
    856850 *
    857851 * The audio format of each mixing buffer can vary; the internal mixing code
    858  * then will autiomatically do the (needed) conversion.
     852 * then will automatically do the (needed) conversion.
    859853 *
    860854 * @return  IPRT status code.
     
    996990     * will not be needed, that is, are not needed in order to process the live
    997991     * samples of the source buffer. */
    998     uint32_t cDead = pDst->cSamples - cLive;
    999 
    1000     uint32_t cToReadTotal = (uint32_t)RT_MIN(cSamples, AUDIOMIXBUF_S2S_RATIO(pSrc, cDead));
    1001     uint32_t offRead = 0;
    1002 
    1003     uint32_t cReadTotal = 0;
     992    uint32_t cDead         = pDst->cSamples - cLive;
     993
     994    uint32_t cToReadTotal  = (uint32_t)RT_MIN(cSamples, AUDIOMIXBUF_S2S_RATIO(pSrc, cDead));
     995    uint32_t offRead       = 0;
     996
     997    uint32_t cReadTotal    = 0;
    1004998    uint32_t cWrittenTotal = 0;
    1005     uint32_t offWrite = (pDst->offReadWrite + cLive) % pDst->cSamples;
    1006 
    1007     AUDMIXBUF_LOG(("pSrc=%s (%RU32 samples), pDst=%s (%RU32 samples), cLive=%RU32, cDead=%RU32, cToReadTotal=%RU32, offWrite=%RU32\n",
    1008                    pSrc->pszName, pSrc->cSamples, pDst->pszName, pDst->cSamples, cLive, cDead, cToReadTotal, offWrite));
     999    uint32_t offWrite      = (pDst->offReadWrite + cLive) % pDst->cSamples;
     1000
     1001    AUDMIXBUF_LOG(("pSrc=%s (%RU32 samples, %RU8 chan), pDst=%s (%RU32 samples, %RU8 chan), " \
     1002                   "cLive=%RU32, cDead=%RU32, cToReadTotal=%RU32, offWrite=%RU32\n",
     1003                   pSrc->pszName, pSrc->cSamples, AUDMIXBUF_FMT_CHANNELS(pSrc->AudioFmt),
     1004                   pDst->pszName, pDst->cSamples, AUDMIXBUF_FMT_CHANNELS(pDst->AudioFmt),
     1005                   cLive, cDead, cToReadTotal, offWrite));
    10091006
    10101007    uint32_t cToRead, cToWrite;
     
    10301027                       cDead, offWrite, cToWrite, offRead, cToRead));
    10311028
    1032         audioMixBufOpBlend(pDst->pSamples + offWrite, cToWrite,
    1033                            pSrc->pSamples + offRead, cToRead,
    1034                            pSrc->pRate, &cWritten, &cRead);
     1029        audioMixBufOpAssign(pDst->pSamples + offWrite, cToWrite,
     1030                            pSrc->pSamples + offRead, cToRead,
     1031                            pSrc->pRate, &cWritten, &cRead);
    10351032
    10361033        AUDMIXBUF_LOG(("\t\tcWritten=%RU32, cRead=%RU32\n", cWritten, cRead));
     
    11381135
    11391136    AUDMIXBUF_LOG(("********************************************\n"));
    1140     AUDMIXBUF_LOG(("%s: offReadWrite=%RU32, cProcessed=%RU32, cMixed=%RU32 (BpS=%RU32)\n",
     1137    AUDMIXBUF_LOG(("[PARENT] %s: offReadWrite=%RU32, cProcessed=%RU32, cMixed=%RU32 (BpS=%RU32)\n",
    11411138                   pParent->pszName,
    11421139                   pParent->offReadWrite, pParent->cProcessed, pParent->cMixed,
     
    11461143    RTListForEach(&pParent->lstBuffers, pIter, PDMAUDIOMIXBUF, Node)
    11471144    {
    1148         AUDMIXBUF_LOG(("\t%s: offReadWrite=%RU32, cProcessed=%RU32, cMixed=%RU32 (BpS=%RU32)\n",
     1145        AUDMIXBUF_LOG(("\t[CHILD] %s: offReadWrite=%RU32, cProcessed=%RU32, cMixed=%RU32 (BpS=%RU32)\n",
    11491146                       pIter->pszName,
    11501147                       pIter->offReadWrite, pIter->cProcessed, pIter->cMixed,
     
    13631360    if (RT_SUCCESS(rc))
    13641361    {
    1365 #ifdef DEBUG_DUMP_PCM_DATA
     1362#ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
    13661363        RTFILE fh;
    1367         rc = RTFileOpen(&fh, DEBUG_DUMP_PCM_DATA_PATH "mixbuf_readcirc.pcm",
     1364        rc = RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_readcirc.pcm",
    13681365                        RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    13691366        if (RT_SUCCESS(rc))
     
    15071504 * @return  IPRT status code.
    15081505 * @param   pMixBuf                 Pointer to mixing buffer to write to.
    1509  * @param   enmFmt                  Audio format supplied in the buffer.
    15101506 * @param   offSamples              Offset (in samples) starting to write at.
    15111507 * @param   pvBuf                   Pointer to audio buffer to be written.
     
    15131509 * @param   pcWritten               Returns number of audio samples written. Optional.
    15141510 */
    1515 int AudioMixBufWriteAt(PPDMAUDIOMIXBUF pMixBuf,
    1516                        uint32_t offSamples,
    1517                        const void *pvBuf, uint32_t cbBuf,
    1518                        uint32_t *pcWritten)
     1511int AudioMixBufWriteAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten)
    15191512{
    15201513    return AudioMixBufWriteAtEx(pMixBuf, pMixBuf->AudioFmt,
     
    15651558    uint32_t cWritten;
    15661559
    1567 #ifdef DEBUG_DUMP_PCM_DATA
     1560#ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
    15681561    RTFILE fh;
    1569     rc = RTFileOpen(&fh, DEBUG_DUMP_PCM_DATA_PATH "mixbuf_writeat.pcm",
     1562    rc = RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_writeat.pcm",
    15701563                    RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    15711564    if (RT_SUCCESS(rc))
     
    17181711    }
    17191712
    1720 #ifdef DEBUG_DUMP_PCM_DATA
     1713#ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
    17211714        RTFILE fh;
    1722         RTFileOpen(&fh, DEBUG_DUMP_PCM_DATA_PATH "mixbuf_writeex.pcm",
     1715        RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_writeex.pcm",
    17231716                   RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    17241717        RTFileWrite(fh, pSamplesDst1, AUDIOMIXBUF_S2B(pMixBuf, cLenDst1), NULL);
  • trunk/src/VBox/Devices/Audio/AudioMixer.cpp

    r59275 r60353  
    310310    RTListForEach(&pSink->lstStreams, pStream, AUDMIXSTREAM, Node)
    311311    {
    312         /** @todo Support output sinks as well! */
    313312        if (!pStream->pConn->pfnIsActiveIn(pStream->pConn, pStream->pIn))
    314313            continue;
     
    327326                break;
    328327
     328            /** @todo Right now we only handle one stream (the last one added in fact). */
     329
    329330            AssertBreakStmt(cbRead <= cbToRead, rc = VERR_BUFFER_OVERFLOW);
    330331            cbToRead -= cbRead;
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r59987 r60353  
    616616            pSink = pThis->pSinkMicIn;
    617617            break;
    618         case PDMAUDIORECSOURCE_LINE_IN:
     618        case PDMAUDIORECSOURCE_LINE:
    619619            pSink = pThis->pSinkLineIn;
    620620            break;
     
    642642            pStrmIn = &pDrv->LineIn;
    643643
    644         int rc2 = pDrv->pConnector->pfnCreateIn(pDrv->pConnector, pszDesc, enmRecSource, pCfg, &pStrmIn->pStrmIn);
    645 
    646         LogFlowFunc(("LUN#%RU8: Created input \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc));
    647         if (rc2 == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */
     644        int rc2 = pDrv->pConnector->pfnCreateIn(pDrv->pConnector, pszDesc, pCfg, &pStrmIn->pStrmIn);
     645        LogFlowFunc(("LUN#%RU8: Created input \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc2));
     646        if (RT_SUCCESS(rc2))
    648647        {
    649648            AudioMixerRemoveStream(pSink, pStrmIn->phStrmIn);
     
    653652        }
    654653
     654        if (RT_SUCCESS(rc))
     655            rc = rc2;
     656
    655657        RTStrFree(pszDesc);
    656658    }
     
    679681        }
    680682
    681         rc = pDrv->pConnector->pfnCreateOut(pDrv->pConnector, pszDesc, pCfg, &pDrv->Out.pStrmOut);
    682         LogFlowFunc(("LUN#%RU8: Created output \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc));
    683         if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */
     683        int rc2 = pDrv->pConnector->pfnCreateOut(pDrv->pConnector, pszDesc, pCfg, &pDrv->Out.pStrmOut);
     684        LogFlowFunc(("LUN#%RU8: Created output \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc2));
     685        if (RT_SUCCESS(rc2))
    684686        {
    685687            AudioMixerRemoveStream(pThis->pSinkOutput, pDrv->Out.phStrmOut);
    686             rc = AudioMixerAddStreamOut(pThis->pSinkOutput,
    687                                         pDrv->pConnector, pDrv->Out.pStrmOut,
    688                                         0 /* uFlags */, &pDrv->Out.phStrmOut);
    689         }
     688            rc2 = AudioMixerAddStreamOut(pThis->pSinkOutput,
     689                                         pDrv->pConnector, pDrv->Out.pStrmOut,
     690                                         0 /* uFlags */, &pDrv->Out.phStrmOut);
     691        }
     692
     693        if (RT_SUCCESS(rc))
     694            rc = rc2;
    690695
    691696        RTStrFree(pszDesc);
     
    712717    {
    713718        case PI_INDEX:
    714             rc = ichac97OpenIn(pThis, "ac97.pi", PDMAUDIORECSOURCE_LINE_IN, pCfg);
     719            rc = ichac97OpenIn(pThis, "ac97.pi", PDMAUDIORECSOURCE_LINE, pCfg);
    715720            break;
    716721
     
    820825                break;
    821826
    822             case PDMAUDIOMIXERCTL_PCM:
     827            case PDMAUDIOMIXERCTL_FRONT:
    823828                rc = AudioMixerSetSinkVolume(pThis->pSinkOutput, &vol);
    824829                break;
     
    875880        case REC_VIDEO:   return PDMAUDIORECSOURCE_VIDEO;
    876881        case REC_AUX:     return PDMAUDIORECSOURCE_AUX;
    877         case REC_LINE_IN: return PDMAUDIORECSOURCE_LINE_IN;
     882        case REC_LINE_IN: return PDMAUDIORECSOURCE_LINE;
    878883        case REC_PHONE:   return PDMAUDIORECSOURCE_PHONE;
    879884        default:
     
    893898        case PDMAUDIORECSOURCE_VIDEO:   return REC_VIDEO;
    894899        case PDMAUDIORECSOURCE_AUX:     return REC_AUX;
    895         case PDMAUDIORECSOURCE_LINE_IN: return REC_LINE_IN;
     900        case PDMAUDIORECSOURCE_LINE: return REC_LINE_IN;
    896901        case PDMAUDIORECSOURCE_PHONE:   return REC_PHONE;
    897902        default:
     
    969974
    970975    ichac97MixerSetVolume(pThis, AC97_Master_Volume_Mute,  PDMAUDIOMIXERCTL_VOLUME,  0x8000);
    971     ichac97MixerSetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_PCM,     0x8808);
     976    ichac97MixerSetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT,   0x8808);
    972977    ichac97MixerSetVolume(pThis, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN, 0x8808);
    973978
     
    18061811                    break;
    18071812                case AC97_PCM_Out_Volume_Mute:
    1808                     ichac97MixerSetVolume(pThis, index, PDMAUDIOMIXERCTL_PCM, u32Val);
     1813                    ichac97MixerSetVolume(pThis, index, PDMAUDIOMIXERCTL_FRONT, u32Val);
    18091814                    break;
    18101815                case AC97_Line_In_Volume_Mute:
     
    20452050# define V_(a, b) ichac97MixerSetVolume(pThis, a, b, ichac97MixerGet(pThis, a))
    20462051    V_(AC97_Master_Volume_Mute,  PDMAUDIOMIXERCTL_VOLUME);
    2047     V_(AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_PCM);
     2052    V_(AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT);
    20482053    V_(AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN);
    20492054# undef V_
  • trunk/src/VBox/Devices/Audio/DevIchHda.cpp

    r59987 r60353  
    3333#include <iprt/asm.h>
    3434#include <iprt/asm-math.h>
     35#include <iprt/file.h>
    3536#include <iprt/list.h>
    3637#ifdef IN_RING3
     
    4647#include "AudioMixer.h"
    4748#include "DevIchHdaCodec.h"
     49#include "DevIchHdaCommon.h"
    4850#include "DrvAudio.h"
    4951
     
    8587#define BIRD_THINKS_CORBRP_IS_MOSTLY_RO
    8688
    87 #define HDA_NREGS           114
    88 #define HDA_NREGS_SAVED     112
     89/* Make sure that interleaving streams support is enabled if the 5.1 code
     90 * is being used. */
     91#ifdef VBOX_WITH_HDA_51_SURROUND
     92# define VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT
     93#endif
    8994
    9095/**
    91  *  NB: Register values stored in memory (au32Regs[]) are indexed through
    92  *  the HDA_RMX_xxx macros (also HDA_MEM_IND_NAME()). On the other hand, the
    93  *  register descriptors in g_aHdaRegMap[] are indexed through the
    94  *  HDA_REG_xxx macros (also HDA_REG_IND_NAME()).
     96 * At the moment we support 4 input + 4 output streams (for 7.1 support) max,
     97 * which is 12 in total. Bidirectional streams are currently *not* supported.
    9598 *
    96  *  The au32Regs[] layout is kept unchanged for saved state
    97  *  compatibility. */
     99 * Note: When changing any of those values, be prepared for some saved state
     100 *       fixups / trouble!
     101 */
     102#define HDA_MAX_SDI             4
     103#define HDA_MAX_SDO             4
     104#define HDA_MAX_STREAMS         (HDA_MAX_SDI + HDA_MAX_SDO)
     105AssertCompile(HDA_MAX_SDI <= HDA_MAX_SDO);
     106
     107/** Number of general registers. */
     108#define HDA_NUM_GENERAL_REGS    34
     109/** Number of total registers in the HDA's register map. */
     110#define HDA_NUM_REGS            (HDA_NUM_GENERAL_REGS + (HDA_MAX_STREAMS * 10 /* Each stream descriptor has 10 registers */))
     111/** Total number of stream tags (channels). Index 0 is reserved / invalid. */
     112#define HDA_MAX_TAGS            16
     113
     114/**
     115 * NB: Register values stored in memory (au32Regs[]) are indexed through
     116 * the HDA_RMX_xxx macros (also HDA_MEM_IND_NAME()). On the other hand, the
     117 * register descriptors in g_aHdaRegMap[] are indexed through the
     118 * HDA_REG_xxx macros (also HDA_REG_IND_NAME()).
     119 *
     120 * The au32Regs[] layout is kept unchanged for saved state
     121 * compatibility.
     122 */
    98123
    99124/* Registers */
     
    114139 * iss (11:8)  - number of input streams supported
    115140 * bss (7:3)   - number of bidirectional streams supported
    116  * bds (2:1)   - number of serial data out signals supported
     141 * bds (2:1)   - number of serial data out (SDO) signals supported
    117142 * b64sup (0)  - 64 bit addressing supported.
    118143 */
    119144#define HDA_MAKE_GCAP(oss, iss, bss, bds, b64sup) \
    120     (  (((oss) & 0xF)  << 12)  \
    121      | (((iss) & 0xF)  << 8)    \
    122      | (((bss) & 0x1F) << 3)    \
    123      | (((bds) & 0x3)  << 2)    \
     145    (  (((oss)   & 0xF) << 12) \
     146     | (((iss)   & 0xF) << 8)  \
     147     | (((bss)   & 0xF) << 3)  \
     148     | (((bds)   & 0x3) << 1)  \
    124149     | ((b64sup) & 1))
    125150
     
    187212#define HDA_INTSTS_S_MASK(num)      RT_BIT(HDA_REG_FIELD_SHIFT(S##num))
    188213
    189 #define HDA_REG_WALCLK              13 /* 0x24 */
     214#define HDA_REG_WALCLK              13 /* 0x30 */
    190215#define HDA_RMX_WALCLK              /* Not defined! */
    191216
     
    194219 * the datasheet.
    195220 */
    196 #define HDA_REG_SSYNC               14 /* 0x34 */
     221#define HDA_REG_SSYNC               14 /* 0x38 */
    197222#define HDA_RMX_SSYNC               12
    198223
     
    290315#define HDA_SD_NUM_FROM_REG(pThis, func, reg)   ((reg - HDA_STREAM_REG_DEF(func, 0)) / 10)
    291316
    292 #define HDA_REG_SD0CTL              34 /* 0x80 */
    293 #define HDA_REG_SD1CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 10) /* 0xA0 */
    294 #define HDA_REG_SD2CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 20) /* 0xC0 */
    295 #define HDA_REG_SD3CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 30) /* 0xE0 */
    296 #define HDA_REG_SD4CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 40) /* 0x100 */
    297 #define HDA_REG_SD5CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 50) /* 0x120 */
    298 #define HDA_REG_SD6CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 60) /* 0x140 */
    299 #define HDA_REG_SD7CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 70) /* 0x160 */
     317/** @todo Condense marcos! */
     318
     319#define HDA_REG_SD0CTL              HDA_NUM_GENERAL_REGS /* 0x80 */
     320#define HDA_REG_SD1CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 10)  /* 0xA0 */
     321#define HDA_REG_SD2CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 20)  /* 0xC0 */
     322#define HDA_REG_SD3CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 30)  /* 0xE0 */
     323#define HDA_REG_SD4CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 40)  /* 0x100 */
     324#define HDA_REG_SD5CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 50)  /* 0x120 */
     325#define HDA_REG_SD6CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 60)  /* 0x140 */
     326#define HDA_REG_SD7CTL              (HDA_STREAM_REG_DEF(CTL, 0) + 70)  /* 0x160 */
    300327#define HDA_RMX_SD0CTL              32
    301328#define HDA_RMX_SD1CTL              (HDA_STREAM_RMX_DEF(CTL, 0) + 10)
     
    471498#define HDA_RMX_SD7FMT              (HDA_STREAM_RMX_DEF(FMT, 0) + 70)
    472499
    473 #define SDFMT(pThis, num)           (HDA_REG((pThis), SD(FMT, num)))
    474 #define HDA_SDFMT_BASE_RATE_SHIFT   14
    475 #define HDA_SDFMT_MULT_SHIFT        11
    476 #define HDA_SDFMT_MULT_MASK         0x7
    477 #define HDA_SDFMT_DIV_SHIFT         8
    478 #define HDA_SDFMT_DIV_MASK          0x7
    479 #define HDA_SDFMT_BITS_SHIFT        4
    480 #define HDA_SDFMT_BITS_MASK         0x7
    481 #define SDFMT_BASE_RATE(pThis, num) ((SDFMT(pThis, num) & HDA_REG_FIELD_FLAG_MASK(SDFMT, BASE_RATE)) >> HDA_REG_FIELD_SHIFT(SDFMT, BASE_RATE))
    482 #define SDFMT_MULT(pThis, num)      ((SDFMT((pThis), num) & HDA_REG_FIELD_MASK(SDFMT,MULT)) >> HDA_REG_FIELD_SHIFT(SDFMT, MULT))
    483 #define SDFMT_DIV(pThis, num)       ((SDFMT((pThis), num) & HDA_REG_FIELD_MASK(SDFMT,DIV)) >> HDA_REG_FIELD_SHIFT(SDFMT, DIV))
     500#define SDFMT(pThis, num)               (HDA_REG((pThis), SD(FMT, num)))
     501#define HDA_SDFMT_BASE_RATE(pThis, num) ((SDFMT(pThis, num)   & HDA_REG_FIELD_FLAG_MASK(SDFMT, BASE_RATE)) >> HDA_REG_FIELD_SHIFT(SDFMT, BASE_RATE))
     502#define HDA_SDFMT_MULT(pThis, num)      ((SDFMT((pThis), num) & HDA_REG_FIELD_MASK(SDFMT,MULT)) >> HDA_REG_FIELD_SHIFT(SDFMT, MULT))
     503#define HDA_SDFMT_DIV(pThis, num)       ((SDFMT((pThis), num) & HDA_REG_FIELD_MASK(SDFMT,DIV)) >> HDA_REG_FIELD_SHIFT(SDFMT, DIV))
    484504
    485505#define HDA_REG_SD0BDPL             42 /* 0x98 */
     
    585605    /** Unused, padding. */
    586606    bool                fPadding;
     607    /** Mutex semaphore handle to serialize access. */
     608    RTSEMMUTEX          hMtx;
    587609    /** Event signalling that the stream's state has been changed. */
    588610    RTSEMEVENT          hStateChangedEvent;
     
    599621typedef struct HDASTREAM
    600622{
    601     /** Stream number (SDn). */
    602     uint8_t        u8Strm;
    603     uint8_t        Padding0[7];
     623    /** Stream descriptor number (SDn). */
     624    uint8_t                 u8SD;
     625    uint8_t                 Padding0[7];
    604626    /** DMA base address (SDnBDPU - SDnBDPL). */
    605     uint64_t       u64BDLBase;
     627    uint64_t                u64BDLBase;
    606628    /** Cyclic Buffer Length (SDnCBL).
    607629     *  Represents the size of the ring buffer. */
    608     uint32_t       u32CBL;
     630    uint32_t                u32CBL;
    609631    /** Format (SDnFMT). */
    610     uint16_t       u16FMT;
     632    uint16_t                u16FMT;
    611633    /** FIFO Size (FIFOS).
    612634     *  Maximum number of bytes that may have been DMA'd into
     
    614636     *
    615637     *  Must be a power of two. */
    616     uint16_t       u16FIFOS;
     638    uint16_t                u16FIFOS;
    617639    /** Last Valid Index (SDnLVI). */
    618     uint16_t       u16LVI;
    619     uint16_t       Padding1[3];
     640    uint16_t                u16LVI;
     641    uint16_t                Padding1[3];
     642    /** Pointer to mixer sink this stream is attached to. */
     643    R3PTRTYPE(PAUDMIXSINK)  pSink;
    620644    /** Internal state of this stream. */
    621     HDASTREAMSTATE State;
     645    HDASTREAMSTATE          State;
    622646} HDASTREAM, *PHDASTREAM;
    623647
     648/**
     649 * Structure for mapping a stream tag to
     650 * an internal stream state.
     651 */
     652typedef struct HDATAG
     653{
     654    /** Own Tag. */
     655    uint8_t               uTag;
     656    uint8_t               Padding[7];
     657    /** Pointer to associated stream. */
     658    R3PTRTYPE(PHDASTREAM) pStrm;
     659} HDATAG, *PHDATAG;
     660
    624661typedef struct HDAINPUTSTREAM
    625662{
    626     /** PCM line input stream. */
    627     R3PTRTYPE(PPDMAUDIOGSTSTRMIN)      pStrmIn;
    628     /** Mixer handle for line input stream. */
    629     R3PTRTYPE(PAUDMIXSTREAM)           phStrmIn;
     663    /** Pointer to guest input stream. */
     664    R3PTRTYPE(PPDMAUDIOGSTSTRMIN) pGstStrm;
     665    /** Associated mixer handle. */
     666    R3PTRTYPE(PAUDMIXSTREAM)      pMixStrm;
    630667} HDAINPUTSTREAM, *PHDAINPUTSTREAM;
    631668
    632669typedef struct HDAOUTPUTSTREAM
    633670{
    634     /** PCM output stream. */
    635     R3PTRTYPE(PPDMAUDIOGSTSTRMOUT)     pStrmOut;
    636     /** Mixer handle for line output stream. */
    637     R3PTRTYPE(PAUDMIXSTREAM)           phStrmOut;
     671    /** Pointer to guest output stream. */
     672    R3PTRTYPE(PPDMAUDIOGSTSTRMOUT) pGstStrm;
     673    /** Associated mixer handle. */
     674    R3PTRTYPE(PAUDMIXSTREAM)       pMixStrm;
    638675} HDAOUTPUTSTREAM, *PHDAOUTPUTSTREAM;
    639676
     
    666703    /** Stream for line input. */
    667704    HDAINPUTSTREAM                     LineIn;
     705#ifdef VBOX_WITH_HDA_MIC_IN
    668706    /** Stream for mic input. */
    669707    HDAINPUTSTREAM                     MicIn;
    670     /** Stream for output. */
    671     HDAOUTPUTSTREAM                    Out;
     708#endif
     709    /** Stream for front output. */
     710    HDAOUTPUTSTREAM                    Front;
     711#ifdef VBOX_WITH_HDA_51_SURROUND
     712    /** Stream for center/LFE output. */
     713    HDAOUTPUTSTREAM                    CenterLFE;
     714    /** Stream for rear output. */
     715    HDAOUTPUTSTREAM                    Rear;
     716#endif
    672717} HDADRIVER;
    673718
     
    691736    RTGCPHYS                           MMIOBaseAddr;
    692737    /** The HDA's register set. */
    693     uint32_t                           au32Regs[HDA_NREGS];
    694     /** Stream state for line-in. */
    695     HDASTREAM                          StrmStLineIn;
    696     /** Stream state for microphone-in. */
    697     HDASTREAM                          StrmStMicIn;
    698     /** Stream state for output. */
    699     HDASTREAM                          StrmStOut;
     738    uint32_t                           au32Regs[HDA_NUM_REGS];
     739    /** Internal stream states. */
     740    HDASTREAM                          aStreams[HDA_MAX_STREAMS];
     741    /** Mapping table between stream tags and stream states. */
     742    HDATAG                             aTags[HDA_MAX_TAGS];
    700743    /** CORB buffer base address. */
    701744    uint64_t                           u64CORBBase;
     
    719762    /** Size in bytes of RIRB buffer. */
    720763    uint32_t                           cbRirbBuf;
    721     /** Indicates if HDA is in reset. */
     764    /** Indicates if HDA controller is in reset mode. */
    722765    bool                               fInReset;
    723766    /** Flag whether the R0 part is enabled. */
     
    748791    R3PTRTYPE(PAUDIOMIXER)             pMixer;
    749792    /** Audio sink for PCM output. */
    750     R3PTRTYPE(PAUDMIXSINK)             pSinkOutput;
     793    R3PTRTYPE(PAUDMIXSINK)             pSinkFront;
     794#ifdef VBOX_WITH_HDA_51_SURROUND
     795    R3PTRTYPE(PAUDMIXSINK)             pSinkCenterLFE;
     796    R3PTRTYPE(PAUDMIXSINK)             pSinkRear;
     797#endif
    751798    /** Audio mixer sink for line input. */
    752799    R3PTRTYPE(PAUDMIXSINK)             pSinkLineIn;
     800#ifdef VBOX_WITH_HDA_MIC_IN
    753801    /** Audio mixer sink for microphone input. */
    754802    R3PTRTYPE(PAUDMIXSINK)             pSinkMicIn;
     803#endif
    755804    uint64_t                           u64BaseTS;
    756805    /** Response Interrupt Count (RINTCNT). */
     
    758807    /** Padding for alignment. */
    759808    uint8_t                            au8Padding2[7];
     809#ifdef VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT
     810    /** Circular buffer for interleaving streams support.
     811     *  This is needed for extracting multiple channels out of a single HDA stream. */
     812    R3PTRTYPE(PRTCIRCBUF)              pCircBuf;
     813#endif
    760814} HDASTATE;
    761815/** Pointer to the ICH Intel HD Audio Controller state. */
     
    785839 * Global register set read/write functions.
    786840 */
    787 static int hdaRegWriteGCTL(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     841static int hdaRegWriteGCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    788842static int hdaRegReadINTSTS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    789843static int hdaRegReadLPIB(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    790844static int hdaRegReadWALCLK(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    791 static int hdaRegWriteINTSTS(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
    792 static int hdaRegWriteCORBWP(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     845static int hdaRegReadSSYNC(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
     846static int hdaRegWriteSSYNC(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     847static int hdaRegWriteINTSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     848static int hdaRegWriteCORBWP(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    793849static int hdaRegWriteCORBRP(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    794850static int hdaRegWriteCORBCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    795851static int hdaRegWriteCORBSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    796 static int hdaRegWriteRIRBWP(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     852static int hdaRegWriteRIRBWP(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    797853static int hdaRegWriteRIRBSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    798 static int hdaRegWriteSTATESTS(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     854static int hdaRegWriteSTATESTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     855static int hdaRegReadOUTPAY(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
     856static int hdaRegWriteOUTPAY(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     857static int hdaRegReadOUTSTRMPAY(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
     858static int hdaRegWriteOUTSTRMPAY(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    799859static int hdaRegWriteIRS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    800860static int hdaRegReadIRS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
     
    804864 * {IOB}SDn read/write functions.
    805865 */
    806 static int  hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    807 static int  hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    808 static int  hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    809 static int  hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    810 static int  hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    811 static int  hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    812 static int  hdaRegWriteSDFMT(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    813 static int  hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    814 static int  hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    815 inline bool hdaRegWriteSDIsAllowed(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     866static int       hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     867static int       hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     868static int       hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     869static int       hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     870static int       hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     871static int       hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     872static int       hdaRegWriteSDFMT(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     873static int       hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     874static int       hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     875DECLINLINE(int)  hdaRegWriteSDLock(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t iReg, uint32_t u32Value);
     876DECLINLINE(void) hdaRegWriteSDUnlock(PHDASTREAM pStrmSt);
    816877
    817878/*
     
    819880 */
    820881static int hdaRegReadU32(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    821 static int hdaRegWriteU32(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     882static int hdaRegWriteU32(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    822883static int hdaRegReadU24(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    823 static int hdaRegWriteU24(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     884static int hdaRegWriteU24(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    824885static int hdaRegReadU16(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    825 static int hdaRegWriteU16(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     886static int hdaRegWriteU16(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    826887static int hdaRegReadU8(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    827 static int hdaRegWriteU8(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     888static int hdaRegWriteU8(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    828889
    829890#ifdef IN_RING3
     
    832893static int hdaStreamStop(PHDASTREAM pStrmSt);
    833894static int hdaStreamWaitForStateChange(PHDASTREAM pStrmSt, RTMSINTERVAL msTimeout);
    834 static int hdaTransfer(PHDASTATE pThis, ENMSOUNDSOURCE enmSrc, uint32_t cbToProcess, uint32_t *pcbProcessed);
     895static int hdaTransfer(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t cbToProcess, uint32_t *pcbProcessed);
    835896#endif
    836897
     
    911972    /** Descripton. */
    912973    const char *desc;
    913 } g_aHdaRegMap[HDA_NREGS] =
     974} g_aHdaRegMap[HDA_NUM_REGS] =
    914975
    915976{
     
    919980    { 0x00002, 0x00001, 0x000000FF, 0x00000000, hdaRegReadU8           , hdaRegWriteUnimpl     , HDA_REG_IDX(VMIN)         }, /* Minor Version */
    920981    { 0x00003, 0x00001, 0x000000FF, 0x00000000, hdaRegReadU8           , hdaRegWriteUnimpl     , HDA_REG_IDX(VMAJ)         }, /* Major Version */
    921     { 0x00004, 0x00002, 0x0000FFFF, 0x00000000, hdaRegReadU16          , hdaRegWriteUnimpl     , HDA_REG_IDX(OUTPAY)       }, /* Output Payload Capabilities */
     982    { 0x00004, 0x00002, 0x0000FFFF, 0x00000000, hdaRegReadOUTPAY       , hdaRegWriteOUTPAY     , HDA_REG_IDX(OUTPAY)       }, /* Output Payload Capabilities */
    922983    { 0x00006, 0x00002, 0x0000FFFF, 0x00000000, hdaRegReadU16          , hdaRegWriteUnimpl     , HDA_REG_IDX(INPAY)        }, /* Input Payload Capabilities */
    923984    { 0x00008, 0x00004, 0x00000103, 0x00000103, hdaRegReadU32          , hdaRegWriteGCTL       , HDA_REG_IDX(GCTL)         }, /* Global Control */
     
    925986    { 0x0000e, 0x00002, 0x00000007, 0x00000007, hdaRegReadU8           , hdaRegWriteSTATESTS   , HDA_REG_IDX(STATESTS)     }, /* State Change Status */
    926987    { 0x00010, 0x00002, 0xFFFFFFFF, 0x00000000, hdaRegReadUnimpl       , hdaRegWriteUnimpl     , HDA_REG_IDX(GSTS)         }, /* Global Status */
    927     { 0x00018, 0x00002, 0x0000FFFF, 0x00000000, hdaRegReadU16          , hdaRegWriteUnimpl    , HDA_REG_IDX(OUTSTRMPAY)   }, /* Output Stream Payload Capability */
     988    { 0x00018, 0x00002, 0x0000FFFF, 0x00000000, hdaRegReadOUTSTRMPAY   , hdaRegWriteOUTSTRMPAY , HDA_REG_IDX(OUTSTRMPAY)   }, /* Output Stream Payload Capability */
    928989    { 0x0001A, 0x00002, 0x0000FFFF, 0x00000000, hdaRegReadU16          , hdaRegWriteUnimpl     , HDA_REG_IDX(INSTRMPAY)    }, /* Input Stream Payload Capability */
    929990    { 0x00020, 0x00004, 0xC00000FF, 0xC00000FF, hdaRegReadU32          , hdaRegWriteU32        , HDA_REG_IDX(INTCTL)       }, /* Interrupt Control */
    930991    { 0x00024, 0x00004, 0xC00000FF, 0x00000000, hdaRegReadINTSTS       , hdaRegWriteUnimpl     , HDA_REG_IDX(INTSTS)       }, /* Interrupt Status */
    931992    { 0x00030, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadWALCLK       , hdaRegWriteUnimpl     , HDA_REG_IDX_LOCAL(WALCLK) }, /* Wall Clock Counter */
    932     { 0x00034, 0x00004, 0x000000FF, 0x000000FF, hdaRegReadU32          , hdaRegWriteU32        , HDA_REG_IDX(SSYNC)        }, /* Stream Synchronization */
     993    { 0x00034, 0x00004, 0x000000FF, 0x000000FF, hdaRegReadSSYNC        , hdaRegWriteSSYNC      , HDA_REG_IDX(SSYNC)        }, /* Stream Synchronization */
    933994    { 0x00040, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32          , hdaRegWriteBase       , HDA_REG_IDX(CORBLBASE)    }, /* CORB Lower Base Address */
    934995    { 0x00044, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteBase       , HDA_REG_IDX(CORBUBASE)    }, /* CORB Upper Base Address */
     
    10331094
    10341095    LogFlowFunc(("[SD%RU8]: LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n",
    1035                  pStrmSt->u8Strm, u32LPIB, pThis->fDMAPosition));
     1096                 pStrmSt->u8SD, u32LPIB, pThis->fDMAPosition));
    10361097
    10371098    /* Update LPIB in any case. */
    1038     HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm) = u32LPIB;
     1099    HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD) = u32LPIB;
    10391100
    10401101    /* Do we need to tell the current DMA position? */
     
    10421103    {
    10431104        int rc2 = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns),
    1044                                         (pThis->u64DPBase & DPBASE_ADDR_MASK) + (pStrmSt->u8Strm * 2 * sizeof(uint32_t)),
     1105                                        (pThis->u64DPBase & DPBASE_ADDR_MASK) + (pStrmSt->u8SD * 2 * sizeof(uint32_t)),
    10451106                                        (void *)&u32LPIB, sizeof(uint32_t));
    10461107        AssertRC(rc2);
    1047 #ifdef DEBUG
    1048         hdaBDLEDumpAll(pThis, pStrmSt->u64BDLBase, pStrmSt->State.uCurBDLE);
    1049 #endif
    10501108    }
    10511109}
     
    11411199
    11421200#ifdef DEBUG
    1143     LogFlowFunc(("[SD%RU8]: uOldBDLE=%RU16, uCurBDLE=%RU16, LVI=%RU32, %R[bdle]\n",
    1144                  pStrmSt->u8Strm, uOldBDLE, pStrmSt->State.uCurBDLE, pStrmSt->u16LVI, &pStrmSt->State.BDLE));
     1201    LogFlowFunc(("[SD%RU8]: uOldBDLE=%RU16, uCurBDLE=%RU16, LVI=%RU32, rc=%Rrc, %R[bdle]\n",
     1202                 pStrmSt->u8SD, uOldBDLE, pStrmSt->State.uCurBDLE, pStrmSt->u16LVI, rc, &pStrmSt->State.BDLE));
    11451203#endif
    11461204    return rc;
    11471205}
    1148 #endif
    1149 
    1150 DECLINLINE(PHDASTREAM) hdaStreamFromID(PHDASTATE pThis, uint8_t uStreamID)
    1151 {
    1152     PHDASTREAM pStrmSt;
    1153 
    1154     switch (uStreamID)
    1155     {
    1156         case 0: /** @todo Use dynamic indices, based on stream assignment. */
    1157         {
    1158             pStrmSt = &pThis->StrmStLineIn;
    1159             break;
    1160         }
    1161 # ifdef VBOX_WITH_HDA_MIC_IN
    1162         case 2: /** @todo Use dynamic indices, based on stream assignment. */
    1163         {
    1164             pStrmSt = &pThis->StrmStMicIn;
    1165             break;
    1166         }
    1167 # endif
    1168         case 4: /** @todo Use dynamic indices, based on stream assignment. */
    1169         {
    1170             pStrmSt = &pThis->StrmStOut;
    1171             break;
    1172         }
    1173 
    1174         default:
    1175         {
    1176             pStrmSt = NULL;
    1177             LogFunc(("Warning: Stream with ID=%RU8 not handled\n", uStreamID));
    1178             break;
    1179         }
    1180     }
    1181 
    1182     return pStrmSt;
     1206#endif /* IN_RING3 */
     1207
     1208DECLINLINE(PHDASTREAM) hdaStreamFromSD(PHDASTATE pThis, uint8_t uSD)
     1209{
     1210    AssertPtrReturn(pThis, NULL);
     1211    AssertReturn(uSD <= HDA_MAX_STREAMS, NULL);
     1212    return &pThis->aStreams[uSD];
    11831213}
    11841214
     
    11971227
    11981228#ifdef VBOX_HDA_WITH_FIFO
    1199     return hdaSDFIFOWToBytes(HDA_STREAM_REG(pThis, FIFOW, pStrmSt->u8Strm));
     1229    return hdaSDFIFOWToBytes(HDA_STREAM_REG(pThis, FIFOW, pStrmSt->u8SD));
    12001230#else
    12011231    return 0;
     
    12101240
    12111241    bool fIrq = false;
     1242
     1243    /** @todo Optimize IRQ handling. */
    12121244
    12131245    if (/* Controller Interrupt Enable (CIE). */
     
    12181250        fIrq = true;
    12191251
    1220     /** @todo Don't hardcode stream numbers here. */
    12211252    if (   IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 0)
    1222         || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 4))
    1223     {
    1224 #ifdef IN_RING3
    1225         LogFunc(("BCIS\n"));
    1226 #endif
     1253        || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 1)
     1254        || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 2)
     1255        || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 3)
     1256        || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 4)
     1257        || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 5)
     1258        || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 6)
     1259        || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 7))
     1260    {
    12271261        fIrq = true;
    12281262    }
     
    12301264    if (HDA_REG_FLAG_VALUE(pThis, INTCTL, GIE))
    12311265    {
    1232         LogFunc(("%s\n", fIrq ? "Asserted" : "Deasserted"));
     1266        Log3Func(("%s\n", fIrq ? "Asserted" : "Deasserted"));
    12331267        PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , fIrq);
    12341268    }
     
    14721506}
    14731507
    1474 static int hdaStreamCreate(PHDASTREAM pStrmSt)
     1508static int hdaStreamCreate(PHDASTREAM pStrmSt, uint8_t uSD)
    14751509{
    14761510    AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER);
     1511    AssertReturn(uSD <= HDA_MAX_STREAMS, VERR_INVALID_PARAMETER);
    14771512
    14781513    int rc = RTSemEventCreate(&pStrmSt->State.hStateChangedEvent);
    1479     AssertRC(rc);
    1480 
    1481     pStrmSt->u8Strm         = UINT8_MAX;
    1482 
    1483     pStrmSt->State.fActive  = false;
    1484     pStrmSt->State.fInReset = false;
    1485     pStrmSt->State.fDoStop  = false;
    1486 
    1487     LogFlowFuncLeaveRC(rc);
     1514    if (RT_SUCCESS(rc))
     1515        rc = RTSemMutexCreate(&pStrmSt->State.hMtx);
     1516
     1517    if (RT_SUCCESS(rc))
     1518    {
     1519        pStrmSt->u8SD           = uSD;
     1520        pStrmSt->pSink          = NULL;
     1521
     1522        pStrmSt->State.fActive  = false;
     1523        pStrmSt->State.fInReset = false;
     1524        pStrmSt->State.fDoStop  = false;
     1525    }
     1526
     1527    LogFlowFunc(("uSD=%RU8\n", uSD));
    14881528    return rc;
    14891529}
     
    14931533    AssertPtrReturnVoid(pStrmSt);
    14941534
    1495     LogFlowFunc(("[SD%RU8]: Destroy\n", pStrmSt->u8Strm));
     1535    LogFlowFunc(("[SD%RU8]: Destroy\n", pStrmSt->u8SD));
    14961536
    14971537    int rc2 = hdaStreamStop(pStrmSt);
    14981538    AssertRC(rc2);
    14991539
     1540    if (pStrmSt->State.hMtx != NIL_RTSEMMUTEX)
     1541    {
     1542        rc2 = RTSemMutexDestroy(pStrmSt->State.hMtx);
     1543        AssertRC(rc2);
     1544        pStrmSt->State.hMtx = NIL_RTSEMMUTEX;
     1545    }
     1546
    15001547    if (pStrmSt->State.hStateChangedEvent != NIL_RTSEMEVENT)
    15011548    {
    15021549        rc2 = RTSemEventDestroy(pStrmSt->State.hStateChangedEvent);
    15031550        AssertRC(rc2);
     1551        pStrmSt->State.hStateChangedEvent = NIL_RTSEMEVENT;
    15041552    }
    15051553
     
    15071555}
    15081556
    1509 static int hdaStreamInit(PHDASTATE pThis, PHDASTREAM pStrmSt, uint8_t u8Strm)
     1557static int hdaStreamInit(PHDASTATE pThis, PHDASTREAM pStrmSt, uint8_t u8SD)
    15101558{
    15111559    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    15121560    AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER);
    15131561
    1514     pStrmSt->u8Strm     = u8Strm;
    1515     pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrmSt->u8Strm),
    1516                                       HDA_STREAM_REG(pThis, BDPU, pStrmSt->u8Strm));
    1517     pStrmSt->u16LVI     = HDA_STREAM_REG(pThis, LVI, pStrmSt->u8Strm);
    1518     pStrmSt->u32CBL     = HDA_STREAM_REG(pThis, CBL, pStrmSt->u8Strm);
    1519     pStrmSt->u16FIFOS   = hdaSDFIFOSToBytes(HDA_STREAM_REG(pThis, FIFOS, pStrmSt->u8Strm));
     1562    pStrmSt->u8SD       = u8SD;
     1563    pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrmSt->u8SD),
     1564                                      HDA_STREAM_REG(pThis, BDPU, pStrmSt->u8SD));
     1565    pStrmSt->u16LVI     = HDA_STREAM_REG(pThis, LVI, pStrmSt->u8SD);
     1566    pStrmSt->u32CBL     = HDA_STREAM_REG(pThis, CBL, pStrmSt->u8SD);
     1567    pStrmSt->u16FIFOS   = hdaSDFIFOSToBytes(HDA_STREAM_REG(pThis, FIFOS, pStrmSt->u8SD));
    15201568
    15211569    RT_ZERO(pStrmSt->State.BDLE);
     
    15231571
    15241572    LogFlowFunc(("[SD%RU8]: DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16\n",
    1525                  pStrmSt->u8Strm, pStrmSt->u64BDLBase, pStrmSt->u32CBL, pStrmSt->u16LVI, pStrmSt->u16FIFOS));
     1573                 pStrmSt->u8SD, pStrmSt->u64BDLBase, pStrmSt->u32CBL, pStrmSt->u16LVI, pStrmSt->u16FIFOS));
    15261574
    15271575#ifdef DEBUG
    1528     uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm),
    1529                                       HDA_STREAM_REG(pThis, BDPU, u8Strm));
    1530     uint16_t u16LVI     = HDA_STREAM_REG(pThis, LVI, u8Strm);
    1531     uint32_t u32CBL     = HDA_STREAM_REG(pThis, CBL, u8Strm);
     1576    uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrmSt->u8SD),
     1577                                      HDA_STREAM_REG(pThis, BDPU, pStrmSt->u8SD));
     1578    uint16_t u16LVI     = HDA_STREAM_REG(pThis, LVI, pStrmSt->u8SD);
     1579    uint32_t u32CBL     = HDA_STREAM_REG(pThis, CBL, pStrmSt->u8SD);
    15321580
    15331581    LogFlowFunc(("\t-> DMA @ 0x%x, LVI=%RU16, CBL=%RU32\n", u64BaseDMA, u16LVI, u32CBL));
     
    15431591    AssertPtrReturnVoid(pThis);
    15441592    AssertPtrReturnVoid(pStrmSt);
    1545     AssertReturnVoid(u8Strm <= 7); /** @todo Use a define for MAX_STREAMS! */
     1593    AssertReturnVoid(u8Strm <= HDA_MAX_STREAMS);
    15461594
    15471595#ifdef VBOX_STRICT
    15481596    AssertReleaseMsg(!RT_BOOL(HDA_STREAM_REG(pThis, CTL, u8Strm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)),
    1549                      ("Cannot reset stream %RU8 while in running state\n", u8Strm));
     1597                     ("[SD%RU8] Cannot reset stream while in running state\n", u8Strm));
    15501598#endif
    15511599
     
    15591607     * First, reset the internal stream state.
    15601608     */
    1561     RT_BZERO(pStrmSt, sizeof(HDASTREAM));
     1609    RT_ZERO(pStrmSt->State.BDLE);
     1610    pStrmSt->State.uCurBDLE = 0;
    15621611
    15631612    /*
     
    15751624    HDA_STREAM_REG(pThis, CBL,   u8Strm) = 0;
    15761625    HDA_STREAM_REG(pThis, LVI,   u8Strm) = 0;
    1577     HDA_STREAM_REG(pThis, FMT,   u8Strm) = 0;
     1626    HDA_STREAM_REG(pThis, FMT,   u8Strm) = HDA_SDFMT_MAKE(HDA_SDFMT_TYPE_PCM, HDA_SDFMT_BASE_44KHZ,
     1627                                                          HDA_SDFMT_MULT_1X, HDA_SDFMT_DIV_1X, HDA_SDFMT_16_BIT,
     1628                                                          HDA_SDFMT_CHAN_STEREO);
    15781629    HDA_STREAM_REG(pThis, BDPU,  u8Strm) = 0;
    15791630    HDA_STREAM_REG(pThis, BDPL,  u8Strm) = 0;
    15801631
    15811632    /*
    1582      * Third, set the internal state according to the just set registers.
     1633     * Third, match the internal state to the just set registers.
    15831634     */
    1584     pStrmSt->u8Strm   = u8Strm;
    1585     pStrmSt->u16FIFOS = HDA_STREAM_REG(pThis, FIFOS, u8Strm);
    1586 
    1587 
    1588     /* Report that we're done resetting this stream. */
    1589     HDA_STREAM_REG(pThis, CTL,   u8Strm) = 0;
     1635    pStrmSt->u8SD       = u8Strm;
     1636    pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm),
     1637                                      HDA_STREAM_REG(pThis, BDPU, u8Strm));
     1638    pStrmSt->u32CBL     = HDA_STREAM_REG(pThis, CBL,   u8Strm);
     1639    pStrmSt->u16FIFOS   = HDA_STREAM_REG(pThis, FIFOS, u8Strm);
     1640    pStrmSt->u16FMT     = HDA_STREAM_REG(pThis, FMT,   u8Strm);
     1641    pStrmSt->u16LVI     = HDA_STREAM_REG(pThis, LVI,   u8Strm);
    15901642
    15911643    LogFunc(("[SD%RU8]: Reset\n", u8Strm));
    15921644
    1593     /* Exit reset mode. */
     1645    /* Exit reset state. */
    15941646    ASMAtomicXchgBool(&pStrmSt->State.fInReset, false);
    15951647}
     
    16441696    AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER);
    16451697
    1646     LogFlowFunc(("[SD%RU8]: msTimeout=%RU32\n", pStrmSt->u8Strm, msTimeout));
     1698    LogFlowFunc(("[SD%RU8]: msTimeout=%RU32\n", pStrmSt->u8SD, msTimeout));
    16471699    return RTSemEventWait(pStrmSt->State.hStateChangedEvent, msTimeout);
    16481700}
     
    17281780        if (pThis->fInReset)
    17291781        {
    1730             LogFunc(("Leaving reset\n"));
     1782            LogFunc(("Guest leaving HDA reset\n"));
    17311783            pThis->fInReset = false;
    17321784        }
     
    17361788#ifdef IN_RING3
    17371789        /* Enter reset state. */
    1738         if (   HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA)
    1739             || HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA))
    1740         {
    1741             LogFunc(("Entering reset with DMA(RIRB:%s, CORB:%s)\n",
    1742                      HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) ? "on" : "off",
    1743                      HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA) ? "on" : "off"));
    1744         }
    1745 
    1746         /* Clear the CRST bit to indicate that we're in reset mode. */
     1790        LogFunc(("Guest entering HDA reset with DMA(RIRB:%s, CORB:%s)\n",
     1791                 HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) ? "on" : "off",
     1792                 HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA) ? "on" : "off"));
     1793
     1794        /* Clear the CRST bit to indicate that we're in reset state. */
    17471795        HDA_REG(pThis, GCTL) &= ~HDA_REG_FIELD_FLAG_MASK(GCTL, RST);
    17481796        pThis->fInReset = true;
    17491797
    1750         /* As the CRST bit now is set, we now can proceed resetting stuff. */
    17511798        hdaReset(pThis->CTX_SUFF(pDevIns));
    17521799#else
     
    17541801#endif
    17551802    }
     1803
    17561804    if (u32Value & HDA_REG_FIELD_FLAG_MASK(GCTL, FSH))
    17571805    {
     
    17711819    pThis->au32Regs[iRegMem] &= ~(v & nv); /* write of 1 clears corresponding bit */
    17721820    return VINF_SUCCESS;
     1821}
     1822
     1823static int hdaRegReadOUTPAY(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value)
     1824{
     1825    uint16_t u16OUTSTRMPAY = HDA_REG(pThis, OUTPAY);
     1826    LogFlowFunc(("%RU16\n", u16OUTSTRMPAY));
     1827
     1828    if (pu32Value)
     1829        *pu32Value = u16OUTSTRMPAY;
     1830    return VINF_SUCCESS;
     1831}
     1832
     1833static int hdaRegWriteOUTPAY(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
     1834{
     1835    LogFlowFunc(("%RU16\n", (uint16_t)u32Value));
     1836    return hdaRegWriteU16(pThis, iReg, u32Value);
     1837}
     1838
     1839static int hdaRegReadOUTSTRMPAY(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value)
     1840{
     1841    uint16_t u16OUTSTRMPAY = HDA_REG(pThis, OUTSTRMPAY);
     1842    LogFlowFunc(("%RU16\n", u16OUTSTRMPAY));
     1843
     1844    if (pu32Value)
     1845        *pu32Value = u16OUTSTRMPAY;
     1846    return VINF_SUCCESS;
     1847}
     1848
     1849static int hdaRegWriteOUTSTRMPAY(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
     1850{
     1851    LogFlowFunc(("%RU16\n", (uint16_t)u32Value));
     1852    return hdaRegWriteU16(pThis, iReg, u32Value);
    17731853}
    17741854
     
    17841864    }
    17851865
    1786 #define HDA_IS_STREAM_EVENT(pThis, num)                                  \
    1787        (   (SDSTS((pThis), num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, DE))    \
    1788         || (SDSTS((pThis), num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, FE))    \
    1789         || (SDSTS((pThis), num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS)))
    1790 
    1791 #define HDA_MARK_STREAM(pThis, num, v) \
    1792         do { (v) |= HDA_IS_STREAM_EVENT((pThis), num) ? RT_BIT((num)) : 0; } while(0)
    1793 
    1794     HDA_MARK_STREAM(pThis, 0, v);
    1795     HDA_MARK_STREAM(pThis, 1, v);
    1796     HDA_MARK_STREAM(pThis, 2, v);
    1797     HDA_MARK_STREAM(pThis, 3, v);
    1798     HDA_MARK_STREAM(pThis, 4, v);
    1799     HDA_MARK_STREAM(pThis, 5, v);
    1800     HDA_MARK_STREAM(pThis, 6, v);
    1801     HDA_MARK_STREAM(pThis, 7, v);
    1802 
    1803 #undef HDA_IS_STREAM_EVENT
    1804 #undef HDA_MARK_STREAM
     1866    for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
     1867    {
     1868        const uint32_t u32STS = HDA_STREAM_REG(pThis, STS, i);
     1869        bool fReport =    (u32STS & HDA_REG_FIELD_FLAG_MASK(SDSTS, DE))
     1870                       || (u32STS & HDA_REG_FIELD_FLAG_MASK(SDSTS, FE))
     1871                       || (u32STS & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS));
     1872        v |= fReport ? RT_BIT(i) : 0;
     1873    }
    18051874
    18061875    v |= v ? RT_BIT(31) : 0;
    18071876
    1808     *pu32Value = v;
     1877    if (pu32Value)
     1878        *pu32Value = v;
     1879
    18091880    return VINF_SUCCESS;
    18101881}
     
    18291900    LogFlowFunc(("%RU32\n", *pu32Value));
    18301901    return VINF_SUCCESS;
     1902}
     1903
     1904static int hdaRegReadSSYNC(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value)
     1905{
     1906    /* HDA spec (1a): 3.3.16 WALCLK counter ticks with 24Mhz bitclock rate. */
     1907    *pu32Value = HDA_REG(pThis, SSYNC);
     1908    LogFlowFunc(("%RU32\n", *pu32Value));
     1909    return VINF_SUCCESS;
     1910}
     1911
     1912static int hdaRegWriteSSYNC(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
     1913{
     1914    LogFlowFunc(("%RU32\n", u32Value));
     1915    return hdaRegWriteU32(pThis, iReg, u32Value);
    18311916}
    18321917
     
    18801965    rc = hdaCORBCmdProcess(pThis);
    18811966    return rc;
    1882 #else
     1967#else  /* !IN_RING3 */
    18831968    return VINF_IOM_R3_MMIO_WRITE;
    1884 #endif
     1969#endif /* IN_RING3 */
    18851970}
    18861971
    18871972static int hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    18881973{
    1889     int rc = hdaRegWriteU32(pThis, iReg, u32Value);
    1890     if (RT_SUCCESS(rc))
    1891     {
    1892         uint8_t u8Strm  = HDA_SD_NUM_FROM_REG(pThis, CBL, iReg);
    1893 
    1894         PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm);
    1895         if (pStrmSt)
    1896         {
    1897             pStrmSt->u32CBL = u32Value;
    1898 
    1899             /* Reset BDLE state. */
    1900             RT_ZERO(pStrmSt->State.BDLE);
    1901             pStrmSt->State.uCurBDLE = 0;
    1902         }
    1903 
    1904         LogFlowFunc(("[SD%RU8]: CBL=%RU32\n", u8Strm, u32Value));
    1905     }
    1906     else
    1907         AssertRCReturn(rc, VINF_SUCCESS);
    1908 
    1909     return rc;
     1974#ifdef IN_RING3
     1975    if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */
     1976        return VINF_SUCCESS;
     1977
     1978    PHDASTREAM pStrmSt = hdaStreamFromSD(pThis, HDA_SD_NUM_FROM_REG(pThis, CBL, iReg));
     1979    if (!pStrmSt)
     1980    {
     1981        LogFunc(("[SD%RU8]: Warning: Changing SDCBL on non-attached stream (0x%x)\n", HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), u32Value));
     1982        return hdaRegWriteU32(pThis, iReg, u32Value);
     1983    }
     1984
     1985    int rc2 = hdaRegWriteSDLock(pThis, pStrmSt, iReg, u32Value);
     1986    AssertRC(rc2);
     1987
     1988    pStrmSt->u32CBL = u32Value;
     1989
     1990    /* Reset BDLE state. */
     1991    RT_ZERO(pStrmSt->State.BDLE);
     1992    pStrmSt->State.uCurBDLE = 0;
     1993
     1994    rc2 = hdaRegWriteU32(pThis, iReg, u32Value);
     1995    AssertRC(rc2);
     1996
     1997    LogFlowFunc(("[SD%RU8]: CBL=%RU32\n", pStrmSt->u8SD, u32Value));
     1998    hdaRegWriteSDUnlock(pStrmSt);
     1999
     2000    return VINF_SUCCESS; /* Always return success to the MMIO handler. */
     2001#else  /* !IN_RING3 */
     2002    return VINF_IOM_R3_MMIO_WRITE;
     2003#endif /* IN_RING3 */
    19102004}
    19112005
     
    19172011    bool fInReset  = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST));
    19182012
    1919     uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, CTL, iReg);
    1920 
    1921     PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm);
    1922     if (!pStrmSt)
    1923     {
    1924         LogFunc(("Warning: Changing SDCTL on non-attached stream with ID=%RU8 (iReg=0x%x)\n", u8Strm, iReg));
    1925         return hdaRegWriteU24(pThis, iReg, u32Value); /* Write 3 bytes. */
    1926     }
     2013    if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */
     2014        return VINF_SUCCESS;
     2015
     2016    /* Get the stream descriptor. */
     2017    uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, CTL, iReg);
     2018
     2019    /*
     2020     * Extract the stream tag the guest wants to use for this specific
     2021     * stream descriptor (SDn). This only can happen if the stream is in a non-running
     2022     * state, so we're doing the lookup and assignment here.
     2023     *
     2024     * So depending on the guest OS, SD3 can use stream tag 4, for example.
     2025     */
     2026    uint8_t uTag = (u32Value >> HDA_SDCTL_NUM_SHIFT) & HDA_SDCTL_NUM_MASK;
     2027
     2028    /* Tag 0 is reserved for software / invalid, just skip. */
     2029    if (   !uTag
     2030        || (uTag > HDA_MAX_TAGS))
     2031    {
     2032        LogFunc(("[SD%RU8]: Warning: Invalid stream tag %RU8 specified!\n", uSD, uTag));
     2033        return hdaRegWriteU24(pThis, iReg, u32Value);
     2034    }
     2035
     2036#ifdef IN_RING3
     2037    PHDATAG pTag = &pThis->aTags[uTag];
     2038    AssertPtr(pTag);
     2039
     2040    if (pTag->uTag)
     2041        LogFunc(("[SD%RU8]: Warning: Tag %RU8 already assigned to %RU8 (pStrm=%p)\n", uSD, uTag, pTag->uTag, pTag->pStrm));
     2042
     2043    /* Assign new values. */
     2044    pTag->uTag  = uTag;
     2045    pTag->pStrm = hdaStreamFromSD(pThis, uSD);
     2046
     2047    LogFunc(("[SD%RU8]: Using stream tag=%RU8\n", uSD, uTag));
     2048
     2049    PHDASTREAM pStrmSt = pTag->pStrm;
     2050    AssertPtr(pStrmSt);
     2051
     2052    /* Note: Do not use hdaRegWriteSDLock() here, as SDnCTL might change the RUN bit. */
     2053    int rc2 = RTSemMutexRequest(pStrmSt->State.hMtx, RT_INDEFINITE_WAIT);
     2054    AssertRC(rc2);
     2055#endif /* IN_RING3 */
    19272056
    19282057    LogFunc(("[SD%RU8]: fRun=%RTbool, fInRun=%RTbool, fReset=%RTbool, fInReset=%RTbool, %R[sdctl]\n",
    1929              u8Strm, fRun, fInRun, fReset, fInReset, u32Value));
     2058             uSD, fRun, fInRun, fReset, fInReset, u32Value));
    19302059
    19312060    if (fInReset)
    19322061    {
    1933         /* Guest is resetting HDA's stream, we're expecting guest will mark stream as exit. */
    19342062        Assert(!fReset);
    1935         LogFunc(("Guest initiated exit of stream reset\n"));
     2063        Assert(!fInRun && !fRun);
     2064
     2065        /* Report that we're done resetting this stream by clearing SRST. */
     2066        HDA_STREAM_REG(pThis, CTL, uSD) &= ~HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST);
     2067
     2068        LogFunc(("[SD%RU8]: Guest initiated exit of stream reset\n", uSD));
    19362069    }
    19372070    else if (fReset)
     
    19412074        Assert(!fInRun && !fRun);
    19422075
    1943         LogFunc(("Guest initiated enter to stream reset\n"));
    1944         hdaStreamReset(pThis, pStrmSt, u8Strm);
    1945 #else
    1946         return VINF_IOM_R3_MMIO_WRITE;
     2076        LogFunc(("[SD%RU8]: Guest initiated enter to stream reset\n", pStrmSt->u8SD));
     2077        hdaStreamReset(pThis, pStrmSt, pStrmSt->u8SD);
    19472078#endif
    19482079    }
     
    19562087        {
    19572088            Assert(!fReset && !fInReset);
    1958             LogFunc(("[SD%RU8]: fRun=%RTbool\n", u8Strm, fRun));
    1959 
     2089            LogFunc(("[SD%RU8]: fRun=%RTbool\n", pStrmSt->u8SD, fRun));
     2090
     2091            Assert(pStrmSt->u8SD < HDA_MAX_STREAMS);
     2092
     2093            /*
     2094             * The register layout specifies that input streams (SDI) come first,
     2095             * followed by the output streams (SDO). So every stream ID below HDA_MAX_SDI
     2096             * is an input stream, whereas everything >= HDA_MAX_SDI is an output stream.
     2097             */
    19602098            PHDADRIVER pDrv;
    1961             switch (u8Strm)
     2099            if (pStrmSt->u8SD < HDA_MAX_SDI)
    19622100            {
    1963                 case 0: /** @todo Use a variable here. Later. */
     2101# ifdef VBOX_WITH_HDA_MIC_IN
     2102#  error "Implement mic-in support!"
     2103# else
     2104                RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
     2105                        pDrv->pConnector->pfnEnableIn(pDrv->pConnector,
     2106                                                      pDrv->LineIn.pGstStrm, fRun);
     2107# endif
     2108            }
     2109            else
     2110            {
     2111                RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    19642112                {
    1965                     RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    1966                         pDrv->pConnector->pfnEnableIn(pDrv->pConnector,
    1967                                                       pDrv->LineIn.pStrmIn, fRun);
    1968                     break;
     2113                    pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Front.pGstStrm,     fRun);
     2114# ifdef VBOX_WITH_HDA_51_SURROUND
     2115                    pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->CenterLFE.pGstStrm, fRun);
     2116                    pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Rear.pGstStrm,      fRun);
     2117# endif
    19692118                }
    1970 # ifdef VBOX_WITH_HDA_MIC_IN
    1971                 case 2: /** @todo Use a variable here. Later. */
    1972                 {
    1973                     RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    1974                         pDrv->pConnector->pfnEnableIn(pDrv->pConnector,
    1975                                                       pDrv->MicIn.pStrmIn, fRun);
    1976                     break;
    1977                 }
    1978 # endif
    1979                 case 4: /** @todo Use a variable here. Later. */
    1980                 {
    1981                     RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    1982                         pDrv->pConnector->pfnEnableOut(pDrv->pConnector,
    1983                                                        pDrv->Out.pStrmOut, fRun);
    1984                     break;
    1985                 }
    1986                 default:
    1987                     AssertMsgFailed(("Changing RUN bit on non-attached stream, register %RU32\n", iReg));
    1988                     break;
    19892119            }
    19902120        }
    19912121
    19922122        if (!fInRun && !fRun)
    1993             hdaStreamInit(pThis, pStrmSt, u8Strm);
    1994 
    1995 #else /* !IN_RING3 */
    1996         return VINF_IOM_R3_MMIO_WRITE;
     2123            hdaStreamInit(pThis, pStrmSt, pStrmSt->u8SD);
    19972124#endif /* IN_RING3 */
    19982125    }
    19992126
    2000     return hdaRegWriteU24(pThis, iReg, u32Value);
     2127#ifdef IN_RING3
     2128    rc2 = hdaRegWriteU24(pThis, iReg, u32Value);
     2129    AssertRC(rc2);
     2130
     2131    hdaRegWriteSDUnlock(pStrmSt);
     2132    return VINF_SUCCESS; /* Always return success to the MMIO handler. */
     2133#else
     2134    return VINF_IOM_R3_MMIO_WRITE;
     2135#endif
    20012136}
    20022137
    20032138static int hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    20042139{
    2005     uint32_t v = HDA_REG_IND(pThis, iReg);
    2006     v &= ~(u32Value & v);
     2140    if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */
     2141        return VINF_SUCCESS;
     2142
     2143    uint32_t v  = HDA_REG_IND(pThis, iReg);
     2144             v &= ~(u32Value & v);
    20072145    HDA_REG_IND(pThis, iReg) = v;
     2146
    20082147    hdaProcessInterrupt(pThis);
    20092148    return VINF_SUCCESS;
     
    20122151static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    20132152{
    2014     if (!hdaRegWriteSDIsAllowed(pThis, iReg, u32Value))
     2153#ifdef IN_RING3
     2154    if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */
    20152155        return VINF_SUCCESS;
    20162156
    2017     int rc = hdaRegWriteU16(pThis, iReg, u32Value);
    2018     if (RT_SUCCESS(rc))
    2019     {
    2020         uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg);
    2021 
    2022         PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm);
    2023         if (pStrmSt)
    2024         {
    2025             pStrmSt->u16LVI = u32Value;
    2026 
    2027             /* Reset BDLE state. */
    2028             RT_ZERO(pStrmSt->State.BDLE);
    2029             pStrmSt->State.uCurBDLE = 0;
    2030         }
    2031 
    2032         LogFlowFunc(("[SD%RU8]: CBL=%RU32\n", u8Strm, u32Value));
    2033     }
    2034     else
    2035         AssertRCReturn(rc, VINF_SUCCESS);
    2036 
    2037     return rc;
     2157    PHDASTREAM pStrmSt = hdaStreamFromSD(pThis, HDA_SD_NUM_FROM_REG(pThis, LVI, iReg));
     2158    if (!pStrmSt)
     2159    {
     2160        LogFunc(("[SD%RU8]: Warning: Changing SDLVI on non-attached stream (0x%x)\n", HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), u32Value));
     2161        return hdaRegWriteU16(pThis, iReg, u32Value);
     2162    }
     2163
     2164    int rc2 = hdaRegWriteSDLock(pThis, pStrmSt, iReg, u32Value);
     2165    AssertRC(rc2);
     2166
     2167    /** @todo Validate LVI. */
     2168    pStrmSt->u16LVI = u32Value;
     2169
     2170    /* Reset BDLE state. */
     2171    RT_ZERO(pStrmSt->State.BDLE);
     2172    pStrmSt->State.uCurBDLE = 0;
     2173
     2174    rc2 = hdaRegWriteU16(pThis, iReg, u32Value);
     2175    AssertRC(rc2);
     2176
     2177    LogFlowFunc(("[SD%RU8]: LVI=%RU32\n", pStrmSt->u8SD, u32Value));
     2178    hdaRegWriteSDUnlock(pStrmSt);
     2179
     2180    return VINF_SUCCESS; /* Always return success to the MMIO handler. */
     2181#else  /* !IN_RING3 */
     2182    return VINF_IOM_R3_MMIO_WRITE;
     2183#endif /* IN_RING3 */
    20382184}
    20392185
    20402186static int hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    20412187{
     2188    if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */
     2189        return VINF_SUCCESS;
     2190
    20422191    switch (u32Value)
    20432192    {
     
    20592208static int hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    20602209{
     2210    if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */
     2211        return VINF_SUCCESS;
     2212
    20612213    /** @todo Only allow updating FIFOS if RUN bit is 0? */
    20622214    uint32_t u32FIFOS = 0;
    20632215
    2064     switch (iReg)
    2065     {
    2066         /* SDInFIFOS is RO, n=0-3. */
    2067         case HDA_REG_SD0FIFOS:
    2068         case HDA_REG_SD1FIFOS:
    2069         case HDA_REG_SD2FIFOS:
    2070         case HDA_REG_SD3FIFOS:
    2071         {
    2072             LogFunc(("Guest tries to change R/O value of FIFO size of input stream, ignoring\n"));
     2216    /** @todo Check if this is a SDI and deny writes to this. */
     2217    switch(u32Value)
     2218    {
     2219        case HDA_SDONFIFO_16B:
     2220        case HDA_SDONFIFO_32B:
     2221        case HDA_SDONFIFO_64B:
     2222        case HDA_SDONFIFO_128B:
     2223        case HDA_SDONFIFO_192B:
     2224            u32FIFOS = u32Value;
    20732225            break;
    2074         }
    2075         case HDA_REG_SD4FIFOS:
    2076         case HDA_REG_SD5FIFOS:
    2077         case HDA_REG_SD6FIFOS:
    2078         case HDA_REG_SD7FIFOS:
    2079         {
    2080             switch(u32Value)
    2081             {
    2082                 case HDA_SDONFIFO_16B:
    2083                 case HDA_SDONFIFO_32B:
    2084                 case HDA_SDONFIFO_64B:
    2085                 case HDA_SDONFIFO_128B:
    2086                 case HDA_SDONFIFO_192B:
    2087                     u32FIFOS = u32Value;
    2088                     break;
    2089 
    2090                 case HDA_SDONFIFO_256B: /** @todo r=andy Investigate this. */
    2091                     LogFunc(("256-bit is unsupported, HDA is switched into 192-bit mode\n"));
    2092                     /* Fall through is intentional. */
    2093                 default:
    2094                     u32FIFOS = HDA_SDONFIFO_192B;
    2095                     break;
    2096             }
    2097 
     2226
     2227        case HDA_SDONFIFO_256B: /** @todo r=andy Investigate this. */
     2228            LogFunc(("256-bit is unsupported, HDA is switched into 192-bit mode\n"));
     2229            /* Fall through is intentional. */
     2230        default:
     2231            u32FIFOS = HDA_SDONFIFO_192B;
    20982232            break;
    2099         }
    2100         default:
    2101         {
    2102             AssertMsgFailed(("Something weird happened with register lookup routine\n"));
    2103             break;
    2104         }
    21052233    }
    21062234
    21072235    if (u32FIFOS)
    21082236    {
    2109         LogFunc(("[SD%RU8]: Updating FIFOS to %RU32 bytes\n", 0, hdaSDFIFOSToBytes(u32FIFOS)));
     2237        LogFunc(("[SD%RU8]: Updating FIFOS to %RU32 bytes\n",
     2238                 HDA_SD_NUM_FROM_REG(pThis, FIFOS, iReg), hdaSDFIFOSToBytes(u32FIFOS)));
    21102239        /** @todo Update internal stream state with new FIFOS. */
    21112240
     
    21582287    }
    21592288
    2160     PDMAUDIOFMT enmFmt = AUD_FMT_S16; /* Default to 16-bit signed. */
     2289    PDMAUDIOFMT enmFmt      = AUD_FMT_S16; /* Default to 16-bit signed. */
     2290    uint8_t     cSampleBits = 16;
    21612291    switch (EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))
    21622292    {
    21632293        case 0:
    2164             LogFunc(("Requested 8-bit\n"));
    2165             enmFmt = AUD_FMT_S8;
     2294            enmFmt      = AUD_FMT_S8;
     2295            cSampleBits = 8;
    21662296            break;
    21672297        case 1:
    2168             LogFunc(("Requested 16-bit\n"));
    2169             enmFmt = AUD_FMT_S16;
     2298            enmFmt      = AUD_FMT_S16;
    21702299            break;
    21712300        case 2:
    2172             LogFunc(("Requested 20-bit\n"));
     2301            cSampleBits = 20;
    21732302            break;
    21742303        case 3:
    2175             LogFunc(("Requested 24-bit\n"));
     2304            cSampleBits = 24;
    21762305            break;
    21772306        case 4:
    2178             LogFunc(("Requested 32-bit\n"));
    2179             enmFmt = AUD_FMT_S32;
     2307            enmFmt      = AUD_FMT_S32;
     2308            cSampleBits = 32;
    21802309            break;
    21812310        default:
    2182             AssertMsgFailed(("Unsupported bits shift %x\n",
     2311            AssertMsgFailed(("Unsupported bits per sample %x\n",
    21832312                             EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT)));
    21842313            rc = VERR_NOT_SUPPORTED;
     
    21952324
    21962325# undef EXTRACT_VALUE
    2197 
    2198     LogFlowFuncLeaveRC(rc);
    21992326    return rc;
    22002327}
     
    22042331{
    22052332#ifdef IN_RING3
    2206 # ifdef VBOX_WITH_HDA_CODEC_EMU
    2207     /* No reason to re-open stream with same settings. */
    2208     if (u32Value == HDA_REG_IND(pThis, iReg))
    2209         return VINF_SUCCESS;
    2210 
    22112333    PDMAUDIOSTREAMCFG strmCfg;
    22122334    int rc = hdaSDFMTToStrmCfg(u32Value, &strmCfg);
     
    22142336        return VINF_SUCCESS; /* Always return success to the MMIO handler. */
    22152337
    2216     uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, FMT, iReg);
    2217 
    2218     PHDADRIVER pDrv;
    2219     switch (iReg)
    2220     {
    2221         case HDA_REG_SD0FMT:
    2222             RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    2223                 rc = hdaCodecOpenStream(pThis->pCodec, PI_INDEX, &strmCfg);
    2224             break;
    2225 #  ifdef VBOX_WITH_HDA_MIC_IN
    2226         case HDA_REG_SD2FMT:
    2227             RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    2228                 rc = hdaCodecOpenStream(pThis->pCodec, MC_INDEX, &strmCfg);
    2229             break;
    2230 #  endif
    2231         case HDA_REG_SD4FMT:
    2232             RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    2233                 rc = hdaCodecOpenStream(pThis->pCodec, PO_INDEX, &strmCfg);
    2234             break;
    2235         default:
    2236             LogFunc(("Warning: Changing SDFMT on non-attached stream with ID=%RU8 (iReg=0x%x)\n", u8Strm, iReg));
    2237             break;
    2238     }
    2239 
    2240     /** @todo r=andy rc gets lost; needs fixing. */
    2241     return hdaRegWriteU16(pThis, iReg, u32Value);
    2242 # else /* !VBOX_WITH_HDA_CODEC_EMU */
    2243     return hdaRegWriteU16(pThis, iReg, u32Value);
    2244 # endif
     2338    if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */
     2339        return VINF_SUCCESS;
     2340
     2341    PHDASTREAM pStrmSt = hdaStreamFromSD(pThis, HDA_SD_NUM_FROM_REG(pThis, FMT, iReg));
     2342    if (!pStrmSt)
     2343    {
     2344        LogFunc(("[SD%RU8]: Warning: Changing SDFMT on non-attached stream (0x%x)\n",
     2345                 HDA_SD_NUM_FROM_REG(pThis, FMT, iReg), u32Value));
     2346        return hdaRegWriteU16(pThis, iReg, u32Value);
     2347    }
     2348
     2349    rc = hdaRegWriteSDLock(pThis, pStrmSt, iReg, u32Value);
     2350    AssertRC(rc);
     2351
     2352    LogFlowFunc(("[SD%RU8]: Hz=%RU32, Channels=%RU8, enmFmt=%RU32\n",
     2353                 pStrmSt->u8SD, strmCfg.uHz, strmCfg.cChannels, strmCfg.enmFormat));
     2354
     2355    PDMAUDIOMIXERCTL enmMixerCtl;
     2356#ifdef VBOX_WITH_HDA_51_SURROUND
     2357# error "Implement me!"
     2358#endif
     2359
     2360    enmMixerCtl = PDMAUDIOMIXERCTL_FRONT;
     2361    strmCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
     2362
     2363    if (RT_SUCCESS(rc))
     2364    {
     2365        PHDADRIVER pDrv;
     2366        RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
     2367        {
     2368            int rc2 = hdaCodecRemoveStream(pThis->pCodec, enmMixerCtl);
     2369            if (RT_SUCCESS(rc2))
     2370                rc2 = hdaCodecAddStream(pThis->pCodec, enmMixerCtl, &strmCfg);
     2371
     2372            if (   RT_FAILURE(rc2)
     2373                && (pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY)) /* We only care about primary drivers here, the rest may fail. */
     2374            {
     2375                if (RT_SUCCESS(rc))
     2376                    rc = rc2;
     2377                /* Keep going. */
     2378            }
     2379        }
     2380
     2381        /* If (re-)opening the stream by the codec above failed, don't write the new
     2382         * format to the register so that the guest is aware it didn't work. */
     2383        if (RT_SUCCESS(rc))
     2384        {
     2385            rc = hdaRegWriteU16(pThis, iReg, u32Value);
     2386            AssertRC(rc);
     2387        }
     2388        else
     2389            LogFunc(("[SD%RU8]: (Re-)Opening stream failed with rc=%Rrc\n", pStrmSt->u8SD, rc));
     2390
     2391        hdaRegWriteSDUnlock(pStrmSt);
     2392    }
     2393
     2394    return VINF_SUCCESS; /* Never return failure. */
    22452395#else /* !IN_RING3 */
    22462396    return VINF_IOM_R3_MMIO_WRITE;
     
    22512401DECLINLINE(int) hdaRegWriteSDBDPX(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value, uint8_t u8Strm)
    22522402{
    2253     if (!hdaRegWriteSDIsAllowed(pThis, iReg, u32Value))
     2403#ifdef IN_RING3
     2404    if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */
    22542405        return VINF_SUCCESS;
    22552406
    2256     int rc = hdaRegWriteU32(pThis, iReg, u32Value);
    2257     if (RT_SUCCESS(rc))
    2258     {
    2259         PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm);
    2260         if (pStrmSt)
    2261         {
    2262             pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm),
    2263                                               HDA_STREAM_REG(pThis, BDPU, u8Strm));
    2264             /* Reset BDLE state. */
    2265             RT_ZERO(pStrmSt->State.BDLE);
    2266             pStrmSt->State.uCurBDLE = 0;
    2267         }
    2268     }
    2269     else
    2270         AssertRCReturn(rc, VINF_SUCCESS);
    2271 
    2272     return rc;
     2407    PHDASTREAM pStrmSt = hdaStreamFromSD(pThis, u8Strm);
     2408    if (!pStrmSt)
     2409    {
     2410        LogFunc(("[SD%RU8]: Warning: Changing SDBPL/SDBPU on non-attached stream (0x%x)\n", HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), u32Value));
     2411        return hdaRegWriteU32(pThis, iReg, u32Value);
     2412    }
     2413
     2414    int rc2 = hdaRegWriteSDLock(pThis, pStrmSt, iReg, u32Value);
     2415    AssertRC(rc2);
     2416
     2417    rc2 = hdaRegWriteU32(pThis, iReg, u32Value);
     2418    AssertRC(rc2);
     2419
     2420    /* Update BDL base. */
     2421    pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm),
     2422                                      HDA_STREAM_REG(pThis, BDPU, u8Strm));
     2423    /* Reset BDLE state. */
     2424    RT_ZERO(pStrmSt->State.BDLE);
     2425    pStrmSt->State.uCurBDLE = 0;
     2426
     2427    LogFlowFunc(("[SD%RU8]: BDLBase=0x%x\n", pStrmSt->u8SD, pStrmSt->u64BDLBase));
     2428    hdaRegWriteSDUnlock(pStrmSt);
     2429
     2430    return VINF_SUCCESS; /* Always return success to the MMIO handler. */
     2431#else  /* !IN_RING3 */
     2432    return VINF_IOM_R3_MMIO_WRITE;
     2433#endif /* IN_RING3 */
    22732434}
    22742435
     
    22832444}
    22842445
     2446#ifdef IN_RING3
    22852447/**
    2286  * Checks whether a write to a specific SDnXXX register is allowed or not.
     2448 * XXX
    22872449 *
    22882450 * @return  bool                Returns @true if write is allowed, @false if not.
     
    22912453 * @param   u32Value            Value to write.
    22922454 */
    2293 inline bool hdaRegWriteSDIsAllowed(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    2294 {
     2455DECLINLINE(int) hdaRegWriteSDLock(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t iReg, uint32_t u32Value)
     2456{
     2457    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
     2458    AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER);
     2459
     2460#ifdef VBOX_STRICT
    22952461    /* Check if the SD's RUN bit is set. */
    2296     bool fIsRunning = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
     2462    uint32_t u32SDCTL = HDA_STREAM_REG(pThis, CTL, pStrmSt->u8SD);
     2463    bool fIsRunning   = RT_BOOL(u32SDCTL & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
    22972464    if (fIsRunning)
    22982465    {
    2299 #ifdef VBOX_STRICT
    2300         AssertMsgFailed(("[SD%RU8]: Cannot write to register 0x%x (0x%x) when RUN bit is set\n",
    2301                          HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), iReg, u32Value));
    2302 #endif
    2303         return false;
    2304     }
    2305 
    2306     return true;
    2307 }
     2466        LogFlowFunc(("[SD%RU8]: Warning: Cannot write to register 0x%x (0x%x) when RUN bit is set (%R[sdctl])\n",
     2467                     pStrmSt->u8SD, iReg, u32Value, u32SDCTL));
     2468        return VERR_ACCESS_DENIED;
     2469    }
     2470#endif
     2471
     2472    return RTSemMutexRequest(pStrmSt->State.hMtx, RT_INDEFINITE_WAIT);
     2473}
     2474
     2475DECLINLINE(void) hdaRegWriteSDUnlock(PHDASTREAM pStrmSt)
     2476{
     2477    AssertPtrReturnVoid(pStrmSt);
     2478
     2479    int rc2 = RTSemMutexRelease(pStrmSt->State.hMtx);
     2480    AssertRC(rc2);
     2481}
     2482#endif /* IN_RING3 */
    23082483
    23092484static int hdaRegReadIRS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value)
    23102485{
    2311     int rc = VINF_SUCCESS;
    23122486    /* regarding 3.4.3 we should mark IRS as busy in case CORB is active */
    23132487    if (   HDA_REG(pThis, CORBWP) != HDA_REG(pThis, CORBRP)
    23142488        || HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA))
     2489    {
    23152490        HDA_REG(pThis, IRS) = HDA_REG_FIELD_FLAG_MASK(IRS, ICB);  /* busy */
    2316 
    2317     rc = hdaRegReadU32(pThis, iReg, pu32Value);
    2318     return rc;
     2491    }
     2492
     2493    return hdaRegReadU32(pThis, iReg, pu32Value);
    23192494}
    23202495
     
    23642539        return rc;
    23652540    }
     2541
    23662542    /*
    23672543     * Once the guest read the response, it should clean the IRV bit of the IRS register.
     
    23762552{
    23772553    if (u32Value & HDA_REG_FIELD_FLAG_MASK(RIRBWP, RST))
    2378     {
    23792554        HDA_REG(pThis, RIRBWP) = 0;
    2380     }
    2381     /* The remaining bits are O, see 6.2.22 */
     2555
     2556    /* The remaining bits are O, see 6.2.22. */
    23822557    return VINF_SUCCESS;
    23832558}
     
    25322707    PHDABDLE pBDLE = &pStrmSt->State.BDLE;
    25332708
    2534     uint32_t cbFree = pStrmSt->u32CBL - HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm);
     2709    uint32_t cbFree = pStrmSt->u32CBL - HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD);
    25352710    if (cbFree)
    25362711    {
     
    25572732    }
    25582733
    2559     LogFlowFunc(("[SD%RU8]: CBL=%RU32, LPIB=%RU32, cbFree=%RU32, %R[bdle]\n", pStrmSt->u8Strm,
    2560                  pStrmSt->u32CBL, HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm), cbFree, pBDLE));
     2734    LogFlowFunc(("[SD%RU8]: CBL=%RU32, LPIB=%RU32, cbFree=%RU32, %R[bdle]\n", pStrmSt->u8SD,
     2735                 pStrmSt->u32CBL, HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD), cbFree, pBDLE));
    25612736    return cbFree;
    25622737}
     
    26022777
    26032778    PHDABDLE pBDLE   = &pStrmSt->State.BDLE;
    2604     uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm);
     2779    uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD);
    26052780
    26062781    /* Did we reach the CBL (Cyclic Buffer List) limit? */
     
    26162791
    26172792    LogFlowFunc(("[SD%RU8]: LPIB=%RU32, CBL=%RU32, fCBLLimitReached=%RTbool, fNeedsNextBDLE=%RTbool, %R[bdle]\n",
    2618                  pStrmSt->u8Strm, u32LPIB, pStrmSt->u32CBL, fCBLLimitReached, fNeedsNextBDLE, pBDLE));
     2793                 pStrmSt->u8SD, u32LPIB, pStrmSt->u32CBL, fCBLLimitReached, fNeedsNextBDLE, pBDLE));
    26192794
    26202795    if (fCBLLimitReached)
     
    26332808    AssertPtrReturnVoid(pStrmSt);
    26342809
    2635     LogFlowFunc(("[SD%RU8]: cbInc=%RU32\n", pStrmSt->u8Strm, cbInc));
     2810    LogFlowFunc(("[SD%RU8]: cbInc=%RU32\n", pStrmSt->u8SD, cbInc));
    26362811
    26372812    Assert(cbInc <= pStrmSt->u16FIFOS);
     
    26462821    if (pBDLE->State.cbBelowFIFOW == 0) /* Did we hit (or exceed) the watermark? */
    26472822    {
    2648         const uint32_t u32LPIB = RT_MIN(HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm) + cbInc,
     2823        const uint32_t u32LPIB = RT_MIN(HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD) + cbInc,
    26492824                                        pStrmSt->u32CBL);
    26502825
    26512826        LogFlowFunc(("[SD%RU8]: LPIB: %RU32 -> %RU32, CBL=%RU32\n",
    2652                      pStrmSt->u8Strm,
    2653                      HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm), HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm) + cbInc,
     2827                     pStrmSt->u8SD,
     2828                     HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD), HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD) + cbInc,
    26542829                     pStrmSt->u32CBL));
    26552830
     
    26662841
    26672842    PHDABDLE       pBDLE   = &pStrmSt->State.BDLE;
    2668     const uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm);
     2843    const uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD);
    26692844
    26702845    if (   pBDLE->State.u32BufOff >= pBDLE->u32BufSize
     
    26902865             * but in general sound quality gets worse.
    26912866             */
    2692             HDA_STREAM_REG(pThis, STS, pStrmSt->u8Strm) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS);
     2867            HDA_STREAM_REG(pThis, STS, pStrmSt->u8SD) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS);
    26932868
    26942869            /*
     
    26962871             * we need to generate an interrupt.
    26972872             */
    2698             if (HDA_STREAM_REG(pThis, CTL, pStrmSt->u8Strm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE))
     2873            if (HDA_STREAM_REG(pThis, CTL, pStrmSt->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE))
    26992874                hdaProcessInterrupt(pThis);
    27002875        }
     
    27042879
    27052880    LogFlowFunc(("[SD%RU8]: u32LPIB=%RU32, CBL=%RU32, %R[bdle] => %s\n",
    2706                  pStrmSt->u8Strm, u32LPIB, pStrmSt->u32CBL, pBDLE, fIsComplete ? "COMPLETE" : "INCOMPLETE"));
     2881                 pStrmSt->u8SD, u32LPIB, pStrmSt->u32CBL, pBDLE, fIsComplete ? "COMPLETE" : "INCOMPLETE"));
    27072882
    27082883    return fIsComplete;
     
    27142889 *       but "reports bytes" when all conditions are met (FIFOW).
    27152890 */
    2716 static int hdaReadAudio(PHDASTATE pThis, PHDASTREAM pStrmSt, PAUDMIXSINK pSink, uint32_t cbMax, uint32_t *pcbRead)
     2891static int hdaReadAudio(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t cbMax, uint32_t *pcbRead)
    27172892{
    27182893    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    27192894    AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER);
    2720     AssertPtrReturn(pSink,   VERR_INVALID_POINTER);
    27212895    /* pcbRead is optional. */
    27222896
     
    27362910    else
    27372911    {
    2738         rc = AudioMixerProcessSinkIn(pSink, AUDMIXOP_BLEND, pBDLE->State.au8FIFO, cbBuf, &cbRead);
     2912        rc = AudioMixerProcessSinkIn(pStrmSt->pSink, AUDMIXOP_BLEND, pBDLE->State.au8FIFO, cbBuf, &cbRead);
    27392913        if (RT_SUCCESS(rc))
    27402914        {
     
    28142988        AssertRC(rc);
    28152989
     2990#if 0
     2991        RTFILE fh;
     2992        RTFileOpen(&fh, "c:\\temp\\hdaWriteAudio.pcm",
     2993                   RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     2994        RTFileWrite(fh, pBDLE->State.au8FIFO + pBDLE->State.cbBelowFIFOW, cbData, NULL);
     2995        RTFileClose(fh);
     2996#endif
     2997
    28162998#ifdef VBOX_WITH_STATISTICS
    28172999        STAM_COUNTER_ADD(&pThis->StatBytesRead, cbData);
     
    28293011            RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    28303012            {
    2831                 if (pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv->Out.pStrmOut))
     3013                if (pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv->Front.pGstStrm))
    28323014                {
     3015#ifdef VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT
     3016                    /** @todo Needs more hacking first. */
     3017# if 0
     3018                    static int16_t restBuf = 0;
     3019                    static size_t cbRestOff = 0;
     3020
     3021                    uint8_t temp[HDA_SDONFIFO_256B + 1];
     3022
     3023                    uint8_t *pu8Src = &pBDLE->State.au8FIFO[0];
     3024                    uint8_t *pu8Dst = &temp[0];
     3025
     3026                    size_t cbSample = sizeof(int16_t) * 2;
     3027
     3028                    size_t cbProc     = 0;
     3029                    size_t cbToSkip   = 5 * cbSample;
     3030                    size_t cbSkipSize = cbToSkip;
     3031                    size_t cbDstSize  = 0;
     3032
     3033                    while (cbProc < cbToWrite)
     3034                    {
     3035                        memcpy(pu8Dst, pu8Src, cbSample);
     3036
     3037                        cbSkipSize = RT_MIN(cbToSkip, cbToWrite - cbProc);
     3038
     3039                        pu8Src += 10;
     3040                        cbProc += cbSkipSize;
     3041
     3042                        pu8Dst    += 4;
     3043                        cbDstSize += cbSample;
     3044                    }
     3045
     3046                    /* Sanity. */
     3047                    AssertMsg(((cbDstSize * 8 /* Bit */) % 16) == 0, ("ASDF\n"));
     3048
     3049                    LogFlowFunc(("cbRest=%zu, cbToWrite=%zu, cbProc=%zu, cbDstSize=%zu\n",
     3050                                 0, cbToWrite, cbProc, cbDstSize));
     3051
    28333052                    rc2 = pDrv->pConnector->pfnWrite(pDrv->pConnector, pDrv->Out.pStrmOut,
     3053                                                     temp, cbDstSize, &cbWrittenToStream);
     3054# if 1
     3055                    RTFILE fh;
     3056                    RTFileOpen(&fh, "/tmp/hdaWriteAudio.pcm",
     3057                               RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     3058                    RTFileWrite(fh, temp, cbDstSize, NULL);
     3059                    RTFileClose(fh);
     3060# endif
     3061
     3062# else
     3063                    int16_t *pvStart;
     3064                    size_t cbAcqWrite;
     3065                    RTCircBufAcquireWriteBlock(pThis->pCircBuf, cbToWrite, (void **)&pvStart, &cbAcqWrite);
     3066
     3067                    uint8_t cChannels = 1;
     3068                    size_t cbSample = sizeof(int16_t);
     3069
     3070                    int16_t *pi16Src = (int16_t *)&pBDLE->State.au8FIFO[0];
     3071                    int16_t *pi16Dst = pvStart;
     3072
     3073                    size_t cbProcSrc     = 0;
     3074                    size_t cbProcDst     = 0;
     3075
     3076                    while (cbProcSrc < cbAcqWrite)
     3077                    {
     3078                        memcpy(pi16Dst, pi16Src, cbSample);
     3079
     3080                        pi16Src  += 6 * cChannels;
     3081                        pi16Dst  += cChannels;
     3082
     3083                        cbProcSrc += RT_MIN(cbAcqWrite - cbProcSrc, 6 * cbSample);
     3084                        cbProcDst += cbSample;
     3085
     3086                        Assert(cbProcSrc <= cbAcqWrite);
     3087                        size_t cbLeft = cbAcqWrite - cbProcSrc;
     3088                        LogFlowFunc(("cbProcSrc=%zu, cbProcDst=%zu, cbLeft=%zu\n", cbProcSrc, cbProcDst, cbLeft));
     3089                        if (   cbLeft
     3090                            && cbLeft < cChannels)
     3091                        {
     3092                            LogFlowFunc(("%zu bytes left ...\n", cbAcqWrite - cbProcSrc));
     3093                            break;
     3094                        }
     3095                    }
     3096
     3097                    RTCircBufReleaseWriteBlock(pThis->pCircBuf, cbProcDst);
     3098
     3099                    LogFlowFunc(("cbAcqWrite=%zu, cbToWrite=%zu, cbProcSrc=%zu, cbProcDst=%zu\n",
     3100                                 cbAcqWrite, cbToWrite, cbProcSrc, cbProcDst));
     3101
     3102                    size_t cbAcqRead = 0;
     3103                    RTCircBufAcquireReadBlock(pThis->pCircBuf, _4K, (void **)&pvStart, &cbAcqRead);
     3104# if 1
     3105                    RTFILE fh;
     3106                    RTFileOpen(&fh, "/tmp/hdaWriteAudio.pcm",
     3107                               RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     3108                    RTFileWrite(fh, pvStart, cbAcqRead, NULL);
     3109                    RTFileClose(fh);
     3110# endif
     3111                    rc2 = pDrv->pConnector->pfnWrite(pDrv->pConnector, pDrv->Front.pGstStrm,
     3112                                                     pvStart, cbAcqRead, &cbWrittenToStream);
     3113
     3114                    /** @todo Add support for writing to center/LFE + rear. */
     3115
     3116                    RTCircBufReleaseReadBlock(pThis->pCircBuf, cbAcqRead);
     3117# endif
     3118
     3119#else  /* !VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT */
     3120                    rc2 = pDrv->pConnector->pfnWrite(pDrv->pConnector, pDrv->Front.pGstStrm,
    28343121                                                     pBDLE->State.au8FIFO, cbToWrite, &cbWrittenToStream);
     3122#endif /* VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT */
    28353123                    if (RT_SUCCESS(rc2))
    28363124                    {
     
    28913179}
    28923180
    2893 
    2894 static DECLCALLBACK(void) hdaCloseIn(PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource)
    2895 {
    2896     NOREF(pThis);
    2897     NOREF(enmRecSource);
    2898     LogFlowFuncEnter();
    2899 }
    2900 
    2901 static DECLCALLBACK(void) hdaCloseOut(PHDASTATE pThis)
    2902 {
    2903     NOREF(pThis);
    2904     LogFlowFuncEnter();
    2905 }
    2906 
    2907 static DECLCALLBACK(int) hdaOpenIn(PHDASTATE pThis,
    2908                                    const char *pszName, PDMAUDIORECSOURCE enmRecSource,
    2909                                    PPDMAUDIOSTREAMCFG pCfg)
     3181/**
     3182 * Retrieves a corresponding sink for a given mixer control.
     3183 * Returns NULL if no sink is found.
     3184 *
     3185 * @return  PAUDMIXSINK
     3186 * @param   pThis               HDA state.
     3187 * @param   enmMixerCtl         Mixer control to get the corresponding sink for.
     3188 */
     3189static PAUDMIXSINK hdaMixerControlToSink(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl)
    29103190{
    29113191    PAUDMIXSINK pSink;
    29123192
    2913     switch (enmRecSource)
    2914     {
    2915 # ifdef VBOX_WITH_HDA_MIC_IN
    2916         case PDMAUDIORECSOURCE_MIC:
     3193    switch (enmMixerCtl)
     3194    {
     3195        case PDMAUDIOMIXERCTL_VOLUME:
     3196            /* Fall through is intentional. */
     3197        case PDMAUDIOMIXERCTL_FRONT:
     3198            pSink = pThis->pSinkFront;
     3199            break;
     3200#ifdef VBOX_WITH_HDA_51_SURROUND
     3201        case PDMAUDIOMIXERCTL_CENTER_LFE:
     3202            pSink = pThis->pSinkCenterLFE;
     3203            break;
     3204        case PDMAUDIOMIXERCTL_REAR:
     3205            pSink = pThis->pSinkRear;
     3206            break;
     3207#endif
     3208        case PDMAUDIOMIXERCTL_LINE_IN:
     3209            pSink = pThis->pSinkLineIn;
     3210            break;
     3211#ifdef VBOX_WITH_HDA_MIC_IN
     3212        case PDMAUDIOMIXERCTL_MIC_IN:
    29173213            pSink = pThis->pSinkMicIn;
    29183214            break;
    2919 # endif
    2920         case PDMAUDIORECSOURCE_LINE_IN:
    2921             pSink = pThis->pSinkLineIn;
     3215#endif
     3216        default:
     3217            pSink = NULL;
     3218            AssertMsgFailed(("Unhandled mixer control\n"));
    29223219            break;
    2923         default:
    2924             AssertMsgFailed(("Audio source %ld not supported\n", enmRecSource));
    2925             return VERR_NOT_SUPPORTED;
    2926     }
     3220    }
     3221
     3222    return pSink;
     3223}
     3224
     3225static DECLCALLBACK(int) hdaMixerAddStreamIn(PHDASTATE pThis, PAUDMIXSINK pSink, PPDMAUDIOSTREAMCFG pCfg)
     3226{
     3227    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     3228    AssertPtrReturn(pSink, VERR_INVALID_POINTER);
     3229    AssertPtrReturn(pCfg,  VERR_INVALID_POINTER);
     3230
     3231    AssertReturn(pCfg->enmDir == PDMAUDIODIR_IN, VERR_INVALID_PARAMETER);
     3232
     3233    LogFunc(("Sink=%s, Source=%ld\n", pSink->pszName, pCfg->DestSource.Source));
    29273234
    29283235    int rc = VINF_SUCCESS;
    2929     char *pszDesc;
    29303236
    29313237    PHDADRIVER pDrv;
    29323238    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    29333239    {
    2934         if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] %s", pDrv->uLUN, pszName) <= 0)
     3240        char *pszDesc;
     3241        if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] %s", pDrv->uLUN, pCfg->pszName) <= 0)
    29353242        {
    29363243            rc = VERR_NO_MEMORY;
     
    29383245        }
    29393246
    2940         rc = pDrv->pConnector->pfnCreateIn(pDrv->pConnector, pszDesc, enmRecSource, pCfg, &pDrv->LineIn.pStrmIn);
    2941         LogFlowFunc(("LUN#%RU8: Created input \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc));
    2942         if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */
     3247        int rc2 = VINF_SUCCESS;
     3248        PHDAINPUTSTREAM pStream;
     3249        switch (pCfg->DestSource.Source)
    29433250        {
    2944             AudioMixerRemoveStream(pSink, pDrv->LineIn.phStrmIn);
    2945             rc = AudioMixerAddStreamIn(pSink,
    2946                                        pDrv->pConnector, pDrv->LineIn.pStrmIn,
    2947                                        0 /* uFlags */, &pDrv->LineIn.phStrmIn);
     3251            case PDMAUDIORECSOURCE_LINE:
     3252                pStream = &pDrv->LineIn;
     3253                break;
     3254#ifdef VBOX_WITH_HDA_MIC_IN
     3255            case PDMAUDIORECSOURCE_MIC:
     3256                pStream = &pDrv->MicIn;
     3257                break;
     3258#endif
     3259            default:
     3260                rc2 = VERR_NOT_SUPPORTED;
     3261                break;
    29483262        }
     3263
     3264        if (RT_SUCCESS(rc2))
     3265        {
     3266            PPDMAUDIOGSTSTRMIN pGstStrm;
     3267            PAUDMIXSTREAM      pMixStrm;
     3268
     3269            rc2 = pDrv->pConnector->pfnCreateIn(pDrv->pConnector, pszDesc, pCfg, &pGstStrm);
     3270            LogFlowFunc(("LUN#%RU8: Created input \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc));
     3271            if (RT_SUCCESS(rc2))
     3272                rc2 = AudioMixerAddStreamIn(pSink, pDrv->pConnector, pGstStrm, 0 /* uFlags */, &pMixStrm);
     3273
     3274            if (RT_SUCCESS(rc2))
     3275            {
     3276                pStream->pGstStrm = pGstStrm;
     3277                pStream->pMixStrm = pMixStrm;
     3278            }
     3279        }
     3280
     3281        if (RT_SUCCESS(rc))
     3282            rc = rc2;
    29493283
    29503284        RTStrFree(pszDesc);
     
    29553289}
    29563290
    2957 static DECLCALLBACK(int) hdaOpenOut(PHDASTATE pThis,
    2958                                     const char *pszName, PPDMAUDIOSTREAMCFG pCfg)
    2959 {
     3291static DECLCALLBACK(int) hdaMixerAddStreamOut(PHDASTATE pThis, PAUDMIXSINK pSink, PPDMAUDIOSTREAMCFG pCfg)
     3292{
     3293    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     3294    AssertPtrReturn(pSink, VERR_INVALID_POINTER);
     3295    AssertPtrReturn(pCfg,  VERR_INVALID_POINTER);
     3296
     3297    AssertReturn(pCfg->enmDir == PDMAUDIODIR_OUT, VERR_INVALID_PARAMETER);
     3298
     3299    LogFunc(("Sink=%s, Dest=%ld\n", pSink->pszName, pCfg->DestSource.Dest));
     3300
    29603301    int rc = VINF_SUCCESS;
    2961     char *pszDesc;
    29623302
    29633303    PHDADRIVER pDrv;
    29643304    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    29653305    {
     3306        char *pszDesc;
    29663307        if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] %s (%RU32Hz, %RU8 %s)",
    2967                          pDrv->uLUN, pszName, pCfg->uHz, pCfg->cChannels, pCfg->cChannels > 1 ? "Channels" : "Channel") <= 0)
     3308                         pDrv->uLUN, pCfg->pszName, pCfg->uHz, pCfg->cChannels, pCfg->cChannels > 1 ? "Channels" : "Channel") <= 0)
    29683309        {
    29693310            rc = VERR_NO_MEMORY;
     
    29713312        }
    29723313
    2973         rc = pDrv->pConnector->pfnCreateOut(pDrv->pConnector, pszDesc, pCfg, &pDrv->Out.pStrmOut);
    2974         LogFlowFunc(("LUN#%RU8: Created output \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc));
    2975         if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */
     3314        int rc2 = VINF_SUCCESS;
     3315        PHDAOUTPUTSTREAM pStream;
     3316        switch (pCfg->DestSource.Dest)
    29763317        {
    2977             AudioMixerRemoveStream(pThis->pSinkOutput, pDrv->Out.phStrmOut);
    2978             rc = AudioMixerAddStreamOut(pThis->pSinkOutput,
    2979                                         pDrv->pConnector, pDrv->Out.pStrmOut,
    2980                                         0 /* uFlags */, &pDrv->Out.phStrmOut);
     3318            case PDMAUDIOPLAYBACKDEST_FRONT:
     3319                pStream = &pDrv->Front;
     3320                break;
     3321#ifdef VBOX_WITH_HDA_51_SURROUND
     3322            case PDMAUDIOPLAYBACKDEST_CENTER_LFE:
     3323                pStream = &pDrv->CenterLFE;
     3324                break;
     3325            case PDMAUDIOPLAYBACKDEST_REAR:
     3326                pStream = &pDrv->Rear;
     3327                break;
     3328#endif
     3329            default:
     3330                rc2 = VERR_NOT_SUPPORTED;
     3331                break;
    29813332        }
     3333
     3334        if (RT_SUCCESS(rc2))
     3335        {
     3336            PPDMAUDIOGSTSTRMOUT pGstStrm;
     3337            PAUDMIXSTREAM       pMixStrm;
     3338
     3339            rc2 = pDrv->pConnector->pfnCreateOut(pDrv->pConnector, pszDesc, pCfg, &pGstStrm);
     3340            LogFlowFunc(("LUN#%RU8: Created output \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc2));
     3341            if (RT_SUCCESS(rc2))
     3342                rc2 = AudioMixerAddStreamOut(pSink, pDrv->pConnector, pGstStrm, 0 /* uFlags */, &pMixStrm);
     3343
     3344            if (RT_SUCCESS(rc2))
     3345            {
     3346                pStream->pGstStrm = pGstStrm;
     3347                pStream->pMixStrm = pMixStrm;
     3348            }
     3349        }
     3350
     3351        if (RT_SUCCESS(rc))
     3352            rc = rc2;
    29823353
    29833354        RTStrFree(pszDesc);
     
    29883359}
    29893360
    2990 static DECLCALLBACK(int) hdaSetVolume(PHDASTATE pThis, ENMSOUNDSOURCE enmSource,
    2991                                       bool fMute, uint8_t uVolLeft, uint8_t uVolRight)
    2992 {
    2993     int             rc = VINF_SUCCESS;
    2994     PDMAUDIOVOLUME  vol = { fMute, uVolLeft, uVolRight };
    2995     PAUDMIXSINK     pSink;
    2996 
    2997     /* Convert the audio source to corresponding sink. */
    2998     switch (enmSource)
    2999     {
    3000         case PO_INDEX:
    3001             pSink = pThis->pSinkOutput;
    3002             break;
    3003         case PI_INDEX:
    3004             pSink = pThis->pSinkLineIn;
    3005             break;
    3006         case MC_INDEX:
    3007             pSink = pThis->pSinkMicIn;
    3008             break;
    3009         default:
    3010             AssertFailedReturn(VERR_INVALID_PARAMETER);
    3011             break;
    3012     }
    3013 
    3014     /* Set the volume. Codec already converted it to the correct range. */
    3015     AudioMixerSetSinkVolume(pSink, &vol);
     3361/**
     3362 * Adds a new audio stream to a specific mixer control.
     3363 * Depending on the mixer control the stream then gets assigned to one of the internal
     3364 * mixer sinks, which in turn then handle the mixing of all connected streams to that sink.
     3365 *
     3366 * @return  IPRT status code.
     3367 * @param   pThis               HDA state.
     3368 * @param   enmMixerCtl         Mixer control to assign new stream to.
     3369 * @param   pCfg                Stream configuration for the new stream.
     3370 */
     3371static DECLCALLBACK(int) hdaMixerAddStream(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg)
     3372{
     3373    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     3374    AssertPtrReturn(pCfg,  VERR_INVALID_POINTER);
     3375
     3376    int rc;
     3377
     3378    PAUDMIXSINK pSink = hdaMixerControlToSink(pThis, enmMixerCtl);
     3379    if (pSink)
     3380    {
     3381        if (pSink->enmDir == AUDMIXSINKDIR_INPUT)
     3382        {
     3383            rc = hdaMixerAddStreamIn(pThis, pSink, pCfg);
     3384        }
     3385        else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT)
     3386        {
     3387            rc = hdaMixerAddStreamOut(pThis, pSink, pCfg);
     3388        }
     3389        else
     3390        {
     3391            rc = VERR_INVALID_PARAMETER;
     3392            AssertFailed();
     3393        }
     3394    }
     3395    else
     3396        rc = VERR_NOT_FOUND;
     3397
     3398    LogFlowFuncLeaveRC(rc);
     3399    return rc;
     3400}
     3401
     3402/**
     3403 * Removes a specified mixer control from the HDA's mixer.
     3404 *
     3405 * @return  IPRT status code.
     3406 * @param   pThis               HDA state.
     3407 * @param   enmMixerCtl         Mixer control to remove.
     3408 */
     3409static DECLCALLBACK(int) hdaMixerRemoveStream(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl)
     3410{
     3411    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     3412
     3413    int rc;
     3414
     3415    PAUDMIXSINK pSink = hdaMixerControlToSink(pThis, enmMixerCtl);
     3416    if (pSink)
     3417    {
     3418        if (pSink->enmDir == AUDMIXSINKDIR_INPUT)
     3419        {
     3420            /** @todo Remove streams. */
     3421        }
     3422        else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT)
     3423        {
     3424            /** @todo Remove streams. */
     3425        }
     3426        else
     3427        {
     3428            rc = VERR_INVALID_PARAMETER;
     3429            AssertFailed();
     3430        }
     3431    }
     3432    else
     3433        rc = VERR_NOT_FOUND;
     3434
     3435    LogFlowFuncLeaveRC(rc);
     3436    return rc;
     3437}
     3438
     3439/**
     3440 * Sets the volume of a specified mixer control.
     3441 *
     3442 * @return  IPRT status code.
     3443 * @param   pThis               HDA State.
     3444 * @param   enmMixerCtl         Mixer control to set volume for.
     3445 * @param   pVol                Pointer to volume data to set.
     3446 */
     3447static DECLCALLBACK(int) hdaMixerSetVolume(PHDASTATE pThis,
     3448                                           PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOVOLUME pVol)
     3449{
     3450    int rc;
     3451
     3452    PAUDMIXSINK pSink = hdaMixerControlToSink(pThis, enmMixerCtl);
     3453    if (pSink)
     3454    {
     3455        /* Set the volume.
     3456         * We assume that the codec already converted it to the correct range. */
     3457        rc = AudioMixerSetSinkVolume(pSink, pVol);
     3458    }
     3459    else
     3460        rc = VERR_NOT_FOUND;
    30163461
    30173462    LogFlowFuncLeaveRC(rc);
     
    30323477    uint32_t cbOutMin = UINT32_MAX;
    30333478
     3479    int rc;
    30343480    PHDADRIVER pDrv;
    30353481
     
    30443490     */
    30453491    AssertPtr(pThis->pCodec);
    3046     PDMPCMPROPS codecStrmProps;
    3047 
    3048     int rc = DrvAudioStreamCfgToProps(&pThis->pCodec->strmCfg, &codecStrmProps);
    3049     AssertRC(rc);
    3050 
    3051     uint32_t cCodecSamplesMin  = (int)((2 * cTicksElapsed * pThis->pCodec->strmCfg.uHz + cTicksPerSec) / cTicksPerSec / 2);
    3052     uint32_t cbCodecSamplesMin = cCodecSamplesMin << codecStrmProps.cShift;
     3492
     3493    /* Since the codec always runs at a fixed delivery rate (48 kHz), calculate the sample processing rate based
     3494     * on the clock ticks elapsed (the clock itself runs at 24 Mhz).
     3495     * A stream itself can have a higher or lower delivery rate, which in turn then results in more or less
     3496     * stream samples per frame. */
     3497    uint32_t cCodecSamplesMin  = (int)((2 * cTicksElapsed * 48000 /* Hz */ + cTicksPerSec) / cTicksPerSec / 2);
     3498    /* We always use 32-bit as containers to make sure all data is being pumped if we need to. */
     3499    uint32_t cbCodecSamplesMin = cCodecSamplesMin << 1;
    30533500
    30543501    /*
     
    30733520         * This is not the optimal solution, but as we have to deal with this on a timer-based approach
    30743521         * (until we have the audio callbacks) we need to have device' DMA engines running. */
    3075         if (!pDrv->pConnector->pfnIsValidOut(pDrv->pConnector, pDrv->Out.pStrmOut))
     3522        if (!pDrv->pConnector->pfnIsValidOut(pDrv->pConnector, pDrv->Front.pGstStrm))
    30763523        {
    30773524            /* Use the codec's (fixed) sampling rate. */
     
    30803527        }
    30813528
    3082         const bool fIsActiveOut = pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv->Out.pStrmOut);
     3529        const bool fIsActiveOut = pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv->Front.pGstStrm);
    30833530        if (   RT_FAILURE(rc)
    30843531            || !fIsActiveOut)
    30853532        {
    3086             uint32_t cSamplesMin  = (int)((2 * cTicksElapsed * pDrv->Out.pStrmOut->Props.uHz + cTicksPerSec) / cTicksPerSec / 2);
    3087             uint32_t cbSamplesMin = AUDIOMIXBUF_S2B(&pDrv->Out.pStrmOut->MixBuf, cSamplesMin);
     3533            uint32_t cSamplesMin  = (int)((2 * cTicksElapsed * pDrv->Front.pGstStrm->Props.uHz + cTicksPerSec) / cTicksPerSec / 2);
     3534            uint32_t cbSamplesMin = AUDIOMIXBUF_S2B(&pDrv->Front.pGstStrm->MixBuf, cSamplesMin);
    30883535
    30893536#ifdef DEBUG_TIMER
     
    31043551        cbOutMin = 0;
    31053552
     3553    /** @todo Determine the streams to be handled. */
     3554    PHDASTREAM pStrmStIn  = &pThis->aStreams[0];
     3555    PHDASTREAM pStrmStOut = &pThis->aStreams[4];
     3556
    31063557    /* Do the actual device transfers. */
    3107     hdaTransfer(pThis, PO_INDEX, cbOutMin /* cbToProcess */, NULL /* pcbProcessed */);
    3108     hdaTransfer(pThis, PI_INDEX, cbInMax  /* cbToProcess */, NULL /* pcbProcessed */);
     3558    hdaTransfer(pThis, pStrmStOut, cbOutMin /* cbToProcess */, NULL /* pcbProcessed */);
     3559    hdaTransfer(pThis, pStrmStIn, cbInMax  /* cbToProcess */, NULL /* pcbProcessed */);
    31093560
    31103561    /* Kick the timer again. */
     
    31663617#endif /* VBOX_WITH_AUDIO_CALLBACKS */
    31673618
    3168 static int hdaTransfer(PHDASTATE pThis, ENMSOUNDSOURCE enmSrc, uint32_t cbToProcess, uint32_t *pcbProcessed)
    3169 {
    3170     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     3619static int hdaTransfer(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t cbToProcess, uint32_t *pcbProcessed)
     3620{
     3621    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
     3622    AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER);
    31713623    /* pcbProcessed is optional. */
    31723624
     
    31803632    }
    31813633
    3182     PHDASTREAM pStrmSt;
    3183     switch (enmSrc)
    3184     {
    3185         case PI_INDEX:
    3186         {
    3187             pStrmSt = &pThis->StrmStLineIn;
    3188             break;
    3189         }
    3190 
    3191 #ifdef VBOX_WITH_HDA_MIC_IN
    3192         case MC_INDEX:
    3193         {
    3194             pStrmSt = &pThis->StrmStMicIn;
    3195             break;
    3196         }
    3197 #endif
    3198         case PO_INDEX:
    3199         {
    3200             pStrmSt = &pThis->StrmStOut;
    3201             break;
    3202         }
    3203 
    3204         default:
    3205         {
    3206             AssertMsgFailed(("Unknown source index %ld\n", enmSrc));
    3207             return VERR_NOT_SUPPORTED;
    3208         }
    3209     }
    3210 
    3211     int  rc       = VINF_SUCCESS;
    32123634    bool fProceed = true;
     3635    int rc = RTSemMutexRequest(pStrmSt->State.hMtx, RT_INDEFINITE_WAIT);
     3636    if (RT_FAILURE(rc))
     3637        return rc;
    32133638
    32143639    /* Stop request received? */
    3215     if (ASMAtomicReadBool(&pStrmSt->State.fDoStop))
     3640    if (pStrmSt->State.fDoStop)
    32163641    {
    32173642        pStrmSt->State.fActive = false;
     
    32233648    }
    32243649    /* Is the stream not in a running state currently? */
    3225     else if (!(HDA_STREAM_REG(pThis, CTL, pStrmSt->u8Strm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)))
     3650    else if (!(HDA_STREAM_REG(pThis, CTL, pStrmSt->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)))
    32263651        fProceed = false;
    32273652    /* Nothing to process? */
     
    32313656    if (!fProceed)
    32323657    {
     3658        rc = RTSemMutexRelease(pStrmSt->State.hMtx);
     3659        AssertRC(rc);
     3660
    32333661        if (pcbProcessed)
    32343662            *pcbProcessed = 0;
     
    32363664    }
    32373665
    3238     LogFlowFunc(("enmSrc=%RU32, cbToProcess=%RU32\n", enmSrc, cbToProcess));
    3239 
    32403666    /* Sanity checks. */
    3241     Assert(pStrmSt->u8Strm <= 7); /** @todo Use a define for MAX_STREAMS! */
     3667    Assert(pStrmSt->u8SD <= HDA_MAX_STREAMS);
    32423668    Assert(pStrmSt->u64BDLBase);
    32433669    Assert(pStrmSt->u32CBL);
    32443670
    32453671    /* State sanity checks. */
    3246     Assert(ASMAtomicReadBool(&pStrmSt->State.fInReset) == false);
     3672    Assert(pStrmSt->State.fInReset == false);
    32473673
    32483674    uint32_t cbProcessedTotal = 0;
     
    32533679        /* Do we need to fetch the next Buffer Descriptor Entry (BDLE)? */
    32543680        if (hdaStreamNeedsNextBDLE(pThis, pStrmSt))
    3255             hdaStreamGetNextBDLE(pThis, pStrmSt);
    3256 
    3257         /* Set the FIFORDY bit on the stream while doing the transfer. */
    3258         HDA_STREAM_REG(pThis, STS, pStrmSt->u8Strm) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);
    3259 
    3260         uint32_t cbProcessed;
    3261         switch (enmSrc)
    32623681        {
    3263             case PI_INDEX:
    3264                 rc = hdaReadAudio(pThis, pStrmSt, pThis->pSinkLineIn, cbToProcess, &cbProcessed);
    3265                 break;
    3266             case PO_INDEX:
    3267                 rc = hdaWriteAudio(pThis, pStrmSt, cbToProcess, &cbProcessed);
    3268                 break;
    3269 #ifdef VBOX_WITH_HDA_MIC_IN
    3270             case MC_INDEX:
    3271                 rc = hdaReadAudio(pThis, pStrmSt, pThis->pSinkMicIn, cbToProcess, &cbProcessed);
    3272                 break;
    3273 #endif
    3274             default:
    3275                 AssertMsgFailed(("Unsupported source index %ld\n", enmSrc));
    3276                 rc = VERR_NOT_SUPPORTED;
     3682            rc = hdaStreamGetNextBDLE(pThis, pStrmSt);
     3683            if (RT_FAILURE(rc))
    32773684                break;
    32783685        }
    32793686
     3687        /* Set the FIFORDY bit on the stream while doing the transfer. */
     3688        HDA_STREAM_REG(pThis, STS, pStrmSt->u8SD) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);
     3689
     3690        /*
     3691         * The register layout specifies that input streams (SDI) come first,
     3692         * followed by the output streams (SDO). So every stream ID below HDA_MAX_SDI
     3693         * is an input stream, whereas everything >= HDA_MAX_SDI is an output stream.
     3694         */
     3695        uint32_t cbProcessed;
     3696        if (pStrmSt->u8SD < HDA_MAX_SDI)
     3697            rc = hdaReadAudio (pThis, pStrmSt, cbToProcess, &cbProcessed);
     3698        else
     3699            rc = hdaWriteAudio(pThis, pStrmSt, cbToProcess, &cbProcessed);
     3700
    32803701        /* Remove the FIFORDY bit again. */
    3281         HDA_STREAM_REG(pThis, STS, pStrmSt->u8Strm) &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);
     3702        HDA_STREAM_REG(pThis, STS, pStrmSt->u8SD) &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);
    32823703
    32833704        if (RT_FAILURE(rc))
     
    33073728            *pcbProcessed = cbProcessedTotal;
    33083729    }
    3309 
    3310     LogFlowFuncLeaveRC(rc);
     3730    else
     3731        LogFlowFunc(("Failed with %Rrc\n", rc));
     3732
     3733    int rc2 = RTSemMutexRelease(pStrmSt->State.hMtx);
     3734    if (RT_SUCCESS(rc))
     3735        rc = rc2;
     3736
    33113737    return rc;
    33123738}
     
    33373763#endif
    33383764
    3339     LogFunc(("offReg=%#x cb=%#x\n", offReg, cb));
     3765    Log3Func(("offReg=%#x cb=%#x\n", offReg, cb));
    33403766    Assert(cb == 4); Assert((offReg & 3) == 0);
    33413767
    33423768    if (pThis->fInReset && idxRegDsc != HDA_REG_GCTL)
    3343         LogFunc(("\tAccess to registers except GCTL is blocked while reset\n"));
     3769        LogFunc(("Access to registers except GCTL is blocked while reset\n"));
    33443770
    33453771    if (idxRegDsc == -1)
    3346         LogRel(("HDA: Invalid read access @0x%x (bytes=%d)\n", offReg, cb));
     3772        LogRel(("HDA: Invalid read access @0x%x (bytes=%u)\n", offReg, cb));
    33473773
    33483774    if (idxRegDsc != -1)
     
    33553781             */
    33563782            rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, (uint32_t *)pv);
    3357             LogFunc(("\tRead %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, rc));
     3783            Log3Func(("\tRead %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, rc));
    33583784        }
    33593785        else
     
    33713797
    33723798                rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, &u32Tmp);
    3373                 LogFunc(("\tRead %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, rc));
     3799                Log3Func(("\tRead %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, rc));
    33743800                if (rc != VINF_SUCCESS)
    33753801                    break;
     
    33903816    {
    33913817        rc = VINF_IOM_MMIO_UNUSED_FF;
    3392         LogFunc(("\tHole at %x is accessed for read\n", offReg));
     3818        Log3Func(("\tHole at %x is accessed for read\n", offReg));
    33933819    }
    33943820
     
    33983824#ifdef LOG_ENABLED
    33993825    if (cbLog == 4)
    3400         LogFunc(("\tReturning @%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, rc));
     3826        Log3Func(("\tReturning @%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, rc));
    34013827    else if (cbLog == 2)
    3402         LogFunc(("\tReturning @%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, rc));
     3828        Log3Func(("\tReturning @%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, rc));
    34033829    else if (cbLog == 1)
    3404         LogFunc(("\tReturning @%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, rc));
     3830        Log3Func(("\tReturning @%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, rc));
    34053831#endif
    34063832    return rc;
     
    34213847#endif
    34223848    int rc = g_aHdaRegMap[idxRegDsc].pfnWrite(pThis, idxRegDsc, u32Value);
    3423     LogFunc(("write %#x -> %s[%db]; %x => %x%s\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev,
    3424              g_aHdaRegMap[idxRegDsc].size, u32CurValue, pThis->au32Regs[idxRegMem], pszLog));
     3849    Log3Func(("write %#x -> %s[%db]; %x => %x%s\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev,
     3850              g_aHdaRegMap[idxRegDsc].size, u32CurValue, pThis->au32Regs[idxRegMem], pszLog));
    34253851    return rc;
    34263852}
     
    34643890    uint32_t const u32LogOldValue = idxRegDsc >= 0 ? pThis->au32Regs[idxRegMem] : UINT32_MAX;
    34653891    if (idxRegDsc == -1)
    3466         LogFunc(("@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb));
     3892        Log3Func(("@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb));
    34673893    else if (cb == 4)
    3468         LogFunc(("@%#05x u32=%#010x %s\n", offReg, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
     3894        Log3Func(("@%#05x u32=%#010x %s\n", offReg, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
    34693895    else if (cb == 2)
    3470         LogFunc(("@%#05x u16=%#06x (%#010x) %s\n", offReg, *(uint16_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
     3896        Log3Func(("@%#05x u16=%#06x (%#010x) %s\n", offReg, *(uint16_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
    34713897    else if (cb == 1)
    3472         LogFunc(("@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
     3898        Log3Func(("@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
    34733899
    34743900    if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size != cb)
    3475         LogFunc(("\tsize=%RU32 != cb=%u!!\n", g_aHdaRegMap[idxRegDsc].size, cb));
     3901        Log3Func(("\tsize=%RU32 != cb=%u!!\n", g_aHdaRegMap[idxRegDsc].size, cb));
    34763902#endif
    34773903
     
    34823908    {
    34833909        rc = hdaWriteReg(pThis, idxRegDsc, u64Value, "");
    3484 #ifdef LOG_ENABLED
    3485         LogFunc(("\t%#x -> %#x\n", u32LogOldValue, idxRegMem != UINT32_MAX ? pThis->au32Regs[idxRegMem] : UINT32_MAX));
    3486 #endif
     3910        Log3Func(("\t%#x -> %#x\n", u32LogOldValue, idxRegMem != UINT32_MAX ? pThis->au32Regs[idxRegMem] : UINT32_MAX));
    34873911    }
    34883912    /*
     
    35043928            u64Value <<= cbBefore * 8;
    35053929            u64Value  |= pThis->au32Regs[idxRegMem] & g_afMasks[cbBefore];
    3506             LogFunc(("\tWithin register, supplied %u leading bits: %#llx -> %#llx ...\n",
    3507                      cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value));
     3930            Log3Func(("\tWithin register, supplied %u leading bits: %#llx -> %#llx ...\n",
     3931                      cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value));
    35083932        }
    35093933
     
    35203944                {
    35213945                    u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbReg] & ~g_afMasks[cb];
    3522                     LogFunc(("\tSupplying missing bits (%#x): %#llx -> %#llx ...\n",
    3523                              g_afMasks[cbReg] & ~g_afMasks[cb], u64Value & g_afMasks[cb], u64Value));
     3946                    Log3Func(("\tSupplying missing bits (%#x): %#llx -> %#llx ...\n",
     3947                              g_afMasks[cbReg] & ~g_afMasks[cb], u64Value & g_afMasks[cb], u64Value));
    35243948                }
    35253949                uint32_t u32LogOldVal = pThis->au32Regs[idxRegMem];
    35263950                rc = hdaWriteReg(pThis, idxRegDsc, u64Value, "*");
    3527                 LogFunc(("\t%#x -> %#x\n", u32LogOldVal, pThis->au32Regs[idxRegMem]));
     3951                Log3Func(("\t%#x -> %#x\n", u32LogOldVal, pThis->au32Regs[idxRegMem]));
    35283952            }
    35293953            else
     
    36154039    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    36164040
    3617     LogFlowFunc(("[SD%RU8]\n", pStrm->u8Strm));
     4041    LogFlowFunc(("[SD%RU8]\n", pStrm->u8SD));
    36184042
    36194043    /* Save stream ID. */
    3620     int rc = SSMR3PutU8(pSSM, pStrm->u8Strm);
     4044    int rc = SSMR3PutU8(pSSM, pStrm->u8SD);
    36214045    AssertRCReturn(rc, rc);
    3622     Assert(pStrm->u8Strm <= 7); /** @todo Use a define. */
     4046    Assert(pStrm->u8SD <= HDA_MAX_STREAMS);
    36234047
    36244048    rc = SSMR3PutStructEx(pSSM, &pStrm->State, sizeof(HDASTREAMSTATE), 0 /*fFlags*/, g_aSSMStreamStateFields6, NULL);
     
    36264050
    36274051#ifdef DEBUG /* Sanity checks. */
    3628     uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrm->u8Strm),
    3629                                       HDA_STREAM_REG(pThis, BDPU, pStrm->u8Strm));
    3630     uint16_t u16LVI     = HDA_STREAM_REG(pThis, LVI, pStrm->u8Strm);
    3631     uint32_t u32CBL     = HDA_STREAM_REG(pThis, CBL, pStrm->u8Strm);
     4052    uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrm->u8SD),
     4053                                      HDA_STREAM_REG(pThis, BDPU, pStrm->u8SD));
     4054    uint16_t u16LVI     = HDA_STREAM_REG(pThis, LVI, pStrm->u8SD);
     4055    uint32_t u32CBL     = HDA_STREAM_REG(pThis, CBL, pStrm->u8SD);
    36324056
    36334057    hdaBDLEDumpAll(pThis, u64BaseDMA, u16LVI + 1);
     
    36804104
    36814105    /* Save MMIO registers. */
    3682     AssertCompile(RT_ELEMENTS(pThis->au32Regs) >= HDA_NREGS_SAVED);
    36834106    SSMR3PutU32(pSSM, RT_ELEMENTS(pThis->au32Regs));
    36844107    SSMR3PutMem(pSSM, pThis->au32Regs, sizeof(pThis->au32Regs));
    36854108
    36864109    /* Save number of streams. */
    3687 #ifdef VBOX_WITH_HDA_MIC_IN
    3688     SSMR3PutU32(pSSM, 3);
    3689 #else
    3690     SSMR3PutU32(pSSM, 2);
    3691 #endif
     4110    SSMR3PutU32(pSSM, HDA_MAX_STREAMS);
    36924111
    36934112    /* Save stream states. */
    3694     int rc = hdaSaveStream(pDevIns, pSSM, &pThis->StrmStOut);
    3695     AssertRCReturn(rc, rc);
    3696 #ifdef VBOX_WITH_HDA_MIC_IN
    3697     rc = hdaSaveStream(pDevIns, pSSM, &pThis->StrmStMicIn);
    3698     AssertRCReturn(rc, rc);
    3699 #endif
    3700     rc = hdaSaveStream(pDevIns, pSSM, &pThis->StrmStLineIn);
    3701     AssertRCReturn(rc, rc);
     4113    int rc;
     4114    for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
     4115    {
     4116        rc = hdaSaveStream(pDevIns, pSSM, &pThis->aStreams[i]);
     4117        AssertRCReturn(rc, rc);
     4118    }
    37024119
    37034120    return rc;
     
    37504167        case HDA_SSM_VERSION_3:
    37514168            cRegs = 112;
    3752             AssertCompile(RT_ELEMENTS(pThis->au32Regs) >= HDA_NREGS_SAVED);
     4169            AssertCompile(RT_ELEMENTS(pThis->au32Regs) >= 112);
    37534170            break;
    37544171
     
    38244241
    38254242            /* Output */
    3826             rc = hdaStreamInit(pThis, &pThis->StrmStOut,    4 /* Stream number, hardcoded */);
     4243            PHDASTREAM pStream = &pThis->aStreams[4];
     4244            rc = hdaStreamInit(pThis, pStream, 4 /* Stream descriptor, hardcoded */);
    38274245            if (RT_FAILURE(rc))
    38284246                break;
    3829             HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pThis->StrmStOut.State.BDLE);
    3830             pThis->StrmStOut.State.uCurBDLE = pThis->StrmStOut.State.BDLE.State.u32BDLIndex;
     4247            HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pStream->State.BDLE);
     4248            pStream->State.uCurBDLE = pStream->State.BDLE.State.u32BDLIndex;
    38314249
    38324250            /* Microphone-In */
    3833             rc = hdaStreamInit(pThis, &pThis->StrmStMicIn,  2 /* Stream number, hardcoded */);
     4251            pStream = &pThis->aStreams[2];
     4252            rc = hdaStreamInit(pThis, pStream, 2 /* Stream descriptor, hardcoded */);
    38344253            if (RT_FAILURE(rc))
    38354254                break;
    3836             HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pThis->StrmStMicIn.State.BDLE);
    3837             pThis->StrmStMicIn.State.uCurBDLE = pThis->StrmStMicIn.State.BDLE.State.u32BDLIndex;
     4255            HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pStream->State.BDLE);
     4256            pStream->State.uCurBDLE = pStream->State.BDLE.State.u32BDLIndex;
    38384257
    38394258            /* Line-In */
    3840             rc = hdaStreamInit(pThis, &pThis->StrmStLineIn, 0 /* Stream number, hardcoded */);
     4259            pStream = &pThis->aStreams[0];
     4260            rc = hdaStreamInit(pThis, pStream, 0 /* Stream descriptor, hardcoded */);
    38414261            if (RT_FAILURE(rc))
    38424262                break;
    3843             HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pThis->StrmStLineIn.State.BDLE);
    3844             pThis->StrmStLineIn.State.uCurBDLE = pThis->StrmStLineIn.State.BDLE.State.u32BDLIndex;
     4263            HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pStream->State.BDLE);
     4264            pStream->State.uCurBDLE = pStream->State.BDLE.State.u32BDLIndex;
    38454265            break;
    38464266        }
     
    38604280            for (uint32_t i = 0; i < cStreams; i++)
    38614281            {
    3862                 uint8_t uStreamID;
    3863                 rc = SSMR3GetU8(pSSM, &uStreamID);
     4282                uint8_t uSD;
     4283                rc = SSMR3GetU8(pSSM, &uSD);
    38644284                if (RT_FAILURE(rc))
    38654285                    break;
    38664286
    3867                 PHDASTREAM pStrm = hdaStreamFromID(pThis, uStreamID);
     4287                PHDASTREAM pStrm = hdaStreamFromSD(pThis, uSD);
    38684288                HDASTREAM  StreamDummy;
    38694289
    38704290                if (!pStrm)
    38714291                {
     4292                    RT_ZERO(StreamDummy);
    38724293                    pStrm = &StreamDummy;
    3873                     LogRel2(("HDA: Warning: Stream ID=%RU32 not supported, skipping to load ...\n", uStreamID));
     4294                    LogRel2(("HDA: Warning: Stream ID=%RU32 not supported, skipping to load ...\n", uSD));
    38744295                    break;
    38754296                }
    38764297
    3877                 RT_BZERO(pStrm, sizeof(HDASTREAM));
    3878 
    3879                 rc = hdaStreamInit(pThis, pStrm, uStreamID);
     4298                rc = hdaStreamInit(pThis, pStrm, uSD);
    38804299                if (RT_FAILURE(rc))
    38814300                {
    3882                     LogRel(("HDA: Stream #%RU32: Initialization of stream %RU8 failed, rc=%Rrc\n", i, uStreamID, rc));
     4301                    LogRel(("HDA: Stream #%RU32: Initialization of stream %RU8 failed, rc=%Rrc\n", i, uSD, rc));
    38834302                    break;
    38844303                }
     
    39724391        RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    39734392        {
    3974             rc = pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->LineIn.pStrmIn, fEnableIn);
     4393            PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector;
     4394            rc = pCon->pfnEnableIn(pCon, pDrv->LineIn.pGstStrm, fEnableIn);
    39754395            if (RT_FAILURE(rc))
    39764396                break;
    39774397#ifdef VBOX_WITH_HDA_MIC_IN
    3978             rc = pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->MicIn.pStrmIn, fEnableMicIn);
     4398            rc = pCon->pfnEnableIn(pCon, pDrv->MicIn.pGstStrm, fEnableMicIn);
    39794399            if (RT_FAILURE(rc))
    39804400                break;
    39814401#endif
    3982             rc = pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Out.pStrmOut, fEnableOut);
     4402            rc = pCon->pfnEnableOut(pCon, pDrv->Front.pGstStrm,     fEnableOut);
     4403            if (RT_FAILURE(rc))
     4404                break;
     4405#ifdef VBOX_WITH_HDA_51_SURROUND
     4406            rc = pCon->pfnEnableOut(pCon, pDrv->CenterLFE.pGstStrm, fEnableOut);
     4407            if (RT_FAILURE(rc))
     4408                break;
     4409            rc = pCon->pfnEnableOut(pCon, pDrv->Rear.pGstStrm,      fEnableOut);
     4410            if (RT_FAILURE(rc))
     4411                break;
     4412#endif
    39834413            if (RT_FAILURE(rc))
    39844414                break;
     
    40834513}
    40844514
    4085 static int hdaLookUpRegisterByName(PHDASTATE pThis, const char *pszArgs)
     4515static int hdaDbgLookupRegByName(PHDASTATE pThis, const char *pszArgs)
    40864516{
    40874517    int iReg = 0;
    4088     for (; iReg < HDA_NREGS; ++iReg)
     4518    for (; iReg < HDA_NUM_REGS; ++iReg)
    40894519        if (!RTStrICmp(g_aHdaRegMap[iReg].abbrev, pszArgs))
    40904520            return iReg;
     
    40974527    Assert(   pThis
    40984528           && iHdaIndex >= 0
    4099            && iHdaIndex < HDA_NREGS);
     4529           && iHdaIndex < HDA_NUM_REGS);
    41004530    pHlp->pfnPrintf(pHlp, "%s: 0x%x\n", g_aHdaRegMap[iHdaIndex].abbrev, pThis->au32Regs[g_aHdaRegMap[iHdaIndex].mem_idx]);
    41014531}
     
    41044534 * @callback_method_impl{FNDBGFHANDLERDEV}
    41054535 */
    4106 static DECLCALLBACK(void) hdaInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     4536static DECLCALLBACK(void) hdaDbgInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    41074537{
    41084538    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    4109     int iHdaRegisterIndex = hdaLookUpRegisterByName(pThis, pszArgs);
     4539    int iHdaRegisterIndex = hdaDbgLookupRegByName(pThis, pszArgs);
    41104540    if (iHdaRegisterIndex != -1)
    41114541        hdaDbgPrintRegister(pThis, pHlp, iHdaRegisterIndex);
    41124542    else
    4113         for(iHdaRegisterIndex = 0; (unsigned int)iHdaRegisterIndex < HDA_NREGS; ++iHdaRegisterIndex)
     4543    {
     4544        for(iHdaRegisterIndex = 0; (unsigned int)iHdaRegisterIndex < HDA_NUM_REGS; ++iHdaRegisterIndex)
    41144545            hdaDbgPrintRegister(pThis, pHlp, iHdaRegisterIndex);
    4115 }
    4116 
    4117 static void hdaDbgPrintStream(PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iHdaStrmIndex)
     4546    }
     4547}
     4548
     4549static void hdaDbgPrintStream(PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iIdx)
    41184550{
    41194551    Assert(   pThis
    4120            && iHdaStrmIndex >= 0
    4121            && iHdaStrmIndex < 7);
    4122     pHlp->pfnPrintf(pHlp, "Dump of %d HDA Stream:\n", iHdaStrmIndex);
    4123     pHlp->pfnPrintf(pHlp, "SD%dCTL: %R[sdctl]\n", iHdaStrmIndex, HDA_STREAM_REG(pThis, CTL, iHdaStrmIndex));
    4124     pHlp->pfnPrintf(pHlp, "SD%dCTS: %R[sdsts]\n", iHdaStrmIndex, HDA_STREAM_REG(pThis, STS, iHdaStrmIndex));
    4125     pHlp->pfnPrintf(pHlp, "SD%dFIFOS: %R[sdfifos]\n", iHdaStrmIndex, HDA_STREAM_REG(pThis, FIFOS, iHdaStrmIndex));
    4126     pHlp->pfnPrintf(pHlp, "SD%dFIFOW: %R[sdfifow]\n", iHdaStrmIndex, HDA_STREAM_REG(pThis, FIFOW, iHdaStrmIndex));
    4127 }
    4128 
    4129 static int hdaLookUpStreamIndex(PHDASTATE pThis, const char *pszArgs)
    4130 {
    4131     /* todo: add args parsing */
     4552           && iIdx >= 0
     4553           && iIdx < HDA_MAX_STREAMS);
     4554
     4555    const PHDASTREAM pStrm = &pThis->aStreams[iIdx];
     4556
     4557    pHlp->pfnPrintf(pHlp, "Stream #%d:\n", iIdx);
     4558    pHlp->pfnPrintf(pHlp, "\tSD%dCTL  : %R[sdctl]\n",   iIdx, HDA_STREAM_REG(pThis, CTL,   iIdx));
     4559    pHlp->pfnPrintf(pHlp, "\tSD%dCTS  : %R[sdsts]\n",   iIdx, HDA_STREAM_REG(pThis, STS,   iIdx));
     4560    pHlp->pfnPrintf(pHlp, "\tSD%dFIFOS: %R[sdfifos]\n", iIdx, HDA_STREAM_REG(pThis, FIFOS, iIdx));
     4561    pHlp->pfnPrintf(pHlp, "\tSD%dFIFOW: %R[sdfifow]\n", iIdx, HDA_STREAM_REG(pThis, FIFOW, iIdx));
     4562    pHlp->pfnPrintf(pHlp, "\tBDLE     : %R[bdle]\n",    &pStrm->State.BDLE);
     4563}
     4564
     4565static void hdaDbgPrintBDLE(PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iIdx)
     4566{
     4567    Assert(   pThis
     4568           && iIdx >= 0
     4569           && iIdx < HDA_MAX_STREAMS);
     4570
     4571    const PHDASTREAM pStrm = &pThis->aStreams[iIdx];
     4572    const PHDABDLE   pBDLE = &pStrm->State.BDLE;
     4573
     4574    pHlp->pfnPrintf(pHlp, "Stream #%d BDLE:\n", iIdx);
     4575    pHlp->pfnPrintf(pHlp, "\t%R[bdle]\n",       pBDLE);
     4576
     4577    uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, iIdx),
     4578                                      HDA_STREAM_REG(pThis, BDPU, iIdx));
     4579    uint16_t u16LVI     = HDA_STREAM_REG(pThis, LVI, iIdx);
     4580    uint32_t u32CBL     = HDA_STREAM_REG(pThis, CBL, iIdx);
     4581
     4582    if (!u64BaseDMA)
     4583        return;
     4584
     4585    uint32_t cbBDLE = 0;
     4586    for (uint16_t i = 0; i < u16LVI + 1; i++)
     4587    {
     4588        uint8_t bdle[16]; /** @todo Use a define. */
     4589        PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BaseDMA + i * 16, bdle, 16); /** @todo Use a define. */
     4590
     4591        uint64_t addr = *(uint64_t *)bdle;
     4592        uint32_t len  = *(uint32_t *)&bdle[8];
     4593        uint32_t ioc  = *(uint32_t *)&bdle[12];
     4594
     4595        pHlp->pfnPrintf(pHlp, "\t#%03d BDLE(adr:0x%llx, size:%RU32, ioc:%RTbool)\n",
     4596                        i, addr, len, RT_BOOL(ioc & 0x1));
     4597
     4598        cbBDLE += len;
     4599    }
     4600
     4601    pHlp->pfnPrintf(pHlp, "Total: %RU32 bytes\n", cbBDLE);
     4602
     4603    pHlp->pfnPrintf(pHlp, "DMA counters (base @ 0x%llx):\n", pThis->u64DPBase);
     4604    if (!pThis->u64DPBase) /* No DMA base given? Bail out. */
     4605    {
     4606        pHlp->pfnPrintf(pHlp, "No counters found\n");
     4607        return;
     4608    }
     4609
     4610    for (int i = 0; i < u16LVI + 1; i++)
     4611    {
     4612        uint32_t uDMACnt;
     4613        PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), (pThis->u64DPBase & DPBASE_ADDR_MASK) + (i * 2 * sizeof(uint32_t)),
     4614                          &uDMACnt, sizeof(uDMACnt));
     4615
     4616        pHlp->pfnPrintf(pHlp, "\t#%03d DMA @ 0x%x\n", i , uDMACnt);
     4617    }
     4618}
     4619
     4620static int hdaDbgLookupStrmIdx(PHDASTATE pThis, const char *pszArgs)
     4621{
     4622    /** @todo Add args parsing. */
    41324623    return -1;
    41334624}
     
    41364627 * @callback_method_impl{FNDBGFHANDLERDEV}
    41374628 */
    4138 static DECLCALLBACK(void) hdaInfoStream(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     4629static DECLCALLBACK(void) hdaDbgInfoStream(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    41394630{
    41404631    PHDASTATE   pThis         = PDMINS_2_DATA(pDevIns, PHDASTATE);
    4141     int         iHdaStrmIndex = hdaLookUpStreamIndex(pThis, pszArgs);
     4632    int         iHdaStrmIndex = hdaDbgLookupStrmIdx(pThis, pszArgs);
    41424633    if (iHdaStrmIndex != -1)
    41434634        hdaDbgPrintStream(pThis, pHlp, iHdaStrmIndex);
    41444635    else
    4145         for(iHdaStrmIndex = 0; iHdaStrmIndex < 7; ++iHdaStrmIndex)
     4636        for(iHdaStrmIndex = 0; iHdaStrmIndex < HDA_MAX_STREAMS; ++iHdaStrmIndex)
    41464637            hdaDbgPrintStream(pThis, pHlp, iHdaStrmIndex);
    41474638}
     
    41504641 * @callback_method_impl{FNDBGFHANDLERDEV}
    41514642 */
    4152 static DECLCALLBACK(void) hdaInfoCodecNodes(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     4643static DECLCALLBACK(void) hdaDbgInfoBDLE(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     4644{
     4645    PHDASTATE   pThis         = PDMINS_2_DATA(pDevIns, PHDASTATE);
     4646    int         iHdaStrmIndex = hdaDbgLookupStrmIdx(pThis, pszArgs);
     4647    if (iHdaStrmIndex != -1)
     4648        hdaDbgPrintBDLE(pThis, pHlp, iHdaStrmIndex);
     4649    else
     4650        for(iHdaStrmIndex = 0; iHdaStrmIndex < HDA_MAX_STREAMS; ++iHdaStrmIndex)
     4651            hdaDbgPrintBDLE(pThis, pHlp, iHdaStrmIndex);
     4652}
     4653
     4654/**
     4655 * @callback_method_impl{FNDBGFHANDLERDEV}
     4656 */
     4657static DECLCALLBACK(void) hdaDbgInfoCodecNodes(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    41534658{
    41544659    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     
    41634668 * @callback_method_impl{FNDBGFHANDLERDEV}
    41644669 */
    4165 static DECLCALLBACK(void) hdaInfoCodecSelector(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     4670static DECLCALLBACK(void) hdaDbgInfoCodecSelector(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    41664671{
    41674672    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     
    41764681 * @callback_method_impl{FNDBGFHANDLERDEV}
    41774682 */
    4178 static DECLCALLBACK(void) hdaInfoMixer(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     4683static DECLCALLBACK(void) hdaDbgInfoMixer(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    41794684{
    41804685    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     
    42174722    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    42184723
    4219     HDA_REG(pThis, GCAP)     = HDA_MAKE_GCAP(4,4,0,0,1); /* see 6.2.1 */
    4220     HDA_REG(pThis, VMIN)     = 0x00;                     /* see 6.2.2 */
    4221     HDA_REG(pThis, VMAJ)     = 0x01;                     /* see 6.2.3 */
    4222     HDA_REG(pThis, OUTPAY)   = 0x003C;                   /* see 6.2.4 */
    4223     HDA_REG(pThis, INPAY)    = 0x001D;                   /* see 6.2.5 */
    4224     HDA_REG(pThis, CORBSIZE) = 0x42;                     /* see 6.2.1 */
    4225     HDA_REG(pThis, RIRBSIZE) = 0x42;                     /* see 6.2.1 */
    4226     HDA_REG(pThis, CORBRP)   = 0x0;
    4227     HDA_REG(pThis, RIRBWP)   = 0x0;
    4228 
    4229     LogFunc(("Resetting ...\n"));
     4724    LogFlowFuncEnter();
    42304725
    42314726# ifndef VBOX_WITH_AUDIO_CALLBACKS
     
    42414736# endif
    42424737
     4738    /* See 6.2.1. */
     4739    HDA_REG(pThis, GCAP)     = HDA_MAKE_GCAP(HDA_MAX_SDO /* Ouput streams */,
     4740                                             HDA_MAX_SDI /* Input streams */,
     4741                                             0           /* Bidirectional output streams */,
     4742                                             0           /* Serial data out signals */,
     4743                                             1           /* 64-bit */);
     4744    HDA_REG(pThis, VMIN)     = 0x00;                     /* see 6.2.2 */
     4745    HDA_REG(pThis, VMAJ)     = 0x01;                     /* see 6.2.3 */
     4746    /* Announce the full 60 words output payload. */
     4747    HDA_REG(pThis, OUTPAY)   = 0x003C;                   /* see 6.2.4 */
     4748    /* Announce the full 29 words input payload. */
     4749    HDA_REG(pThis, INPAY)    = 0x001D;                   /* see 6.2.5 */
     4750    HDA_REG(pThis, CORBSIZE) = 0x42;                     /* see 6.2.1 */
     4751    HDA_REG(pThis, RIRBSIZE) = 0x42;                     /* see 6.2.1 */
     4752    HDA_REG(pThis, CORBRP)   = 0x0;
     4753    HDA_REG(pThis, RIRBWP)   = 0x0;
     4754
    42434755    /*
    42444756     * Stop any audio currently playing and/or recording.
     
    42474759    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    42484760    {
    4249         pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->LineIn.pStrmIn, false /* Disable */);
     4761        pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->LineIn.pGstStrm,      false /* Disable */);
    42504762# ifdef VBOX_WITH_HDA_MIC_IN
    4251         /* Ignore rc. */
    4252         pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->MicIn.pStrmIn, false /* Disable */);
     4763        pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->MicIn.pGstStrm,       false /* Disable */);
    42534764# endif
    4254         /* Ditto. */
    4255         pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Out.pStrmOut, false /* Disable */);
    4256         /* Ditto. */
     4765        pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Front.pGstStrm,     false /* Disable */);
     4766# ifdef VBOX_WITH_HDA_51_SURROUND
     4767        pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->CenterLFE.pGstStrm, false /* Disable */);
     4768        pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Rear.pGstStrm,      false /* Disable */);
     4769# endif
    42574770    }
    42584771
     
    42724785    pThis->u64BaseTS = PDMDevHlpTMTimeVirtGetNano(pDevIns);
    42734786
    4274     for (uint8_t u8Strm = 0; u8Strm < 8; u8Strm++) /** @todo Use a define here. */
    4275     {
    4276         PHDASTREAM pStrmSt = NULL;
    4277         if (u8Strm == 0)      /** @todo Implement dynamic stream IDs. */
    4278             pStrmSt = &pThis->StrmStLineIn;
    4279 # ifdef VBOX_WITH_HDA_MIC_IN
    4280         else if (u8Strm == 2) /** @todo Implement dynamic stream IDs. */
    4281             pStrmSt = &pThis->StrmStMicIn;
    4282 # endif
    4283         else if (u8Strm == 4) /** @todo Implement dynamic stream IDs. */
    4284             pStrmSt = &pThis->StrmStOut;
    4285 
    4286         if (pStrmSt)
    4287         {
    4288             /* Remove the RUN bit from SDnCTL in case the stream was in a running state before. */
    4289             HDA_STREAM_REG(pThis, CTL, u8Strm) &= ~HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN);
    4290 
    4291             hdaStreamReset(pThis, pStrmSt, u8Strm);
    4292         }
    4293     }
     4787    for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
     4788    {
     4789        /* Remove the RUN bit from SDnCTL in case the stream was in a running state before. */
     4790        HDA_STREAM_REG(pThis, CTL, i) &= ~HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN);
     4791        hdaStreamReset(pThis, &pThis->aStreams[i], i);
     4792    }
     4793
     4794    /* Clear stream tags <-> objects mapping table. */
     4795    RT_ZERO(pThis->aTags);
    42944796
    42954797    /* Emulation of codec "wake up" (HDA spec 5.5.1 and 6.5). */
     
    43084810# endif
    43094811
     4812    LogFlowFuncLeave();
    43104813    LogRel(("HDA: Reset\n"));
    43114814}
     
    43484851    pThis->pu64RirbBuf = NULL;
    43494852
    4350     hdaStreamDestroy(&pThis->StrmStLineIn);
    4351     hdaStreamDestroy(&pThis->StrmStMicIn);
    4352     hdaStreamDestroy(&pThis->StrmStOut);
     4853    for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
     4854        hdaStreamDestroy(&pThis->aStreams[i]);
    43534855
    43544856    return VINF_SUCCESS;
     
    46645166
    46655167    RTListInit(&pThis->lstDrv);
     5168#ifdef VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT
     5169    rc = RTCircBufCreate(&pThis->pCircBuf, _4K);
     5170    if (RT_FAILURE(rc))
     5171        return rc;
     5172#endif
    46665173
    46675174    uint8_t uLUN;
     
    47045211            AssertRC(rc);
    47055212
    4706             /* Add all required audio sinks. */
     5213            /*
     5214             * Add mixer output sinks.
     5215             */
     5216#ifdef VBOX_WITH_HDA_51_SURROUND
     5217            rc = AudioMixerAddSink(pThis->pMixer, "[Playback] Front",
     5218                                   AUDMIXSINKDIR_OUTPUT, &pThis->pSinkFront);
     5219            AssertRC(rc);
     5220            rc = AudioMixerAddSink(pThis->pMixer, "[Playback] Center / Subwoofer",
     5221                                   AUDMIXSINKDIR_OUTPUT, &pThis->pSinkCenterLFE);
     5222            AssertRC(rc);
     5223            rc = AudioMixerAddSink(pThis->pMixer, "[Playback] Rear",
     5224                                   AUDMIXSINKDIR_OUTPUT, &pThis->pSinkRear);
     5225            AssertRC(rc);
     5226#else
    47075227            rc = AudioMixerAddSink(pThis->pMixer, "[Playback] PCM Output",
    4708                                    AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOutput);
     5228                                   AUDMIXSINKDIR_OUTPUT, &pThis->pSinkFront);
    47095229            AssertRC(rc);
    4710 
     5230#endif
     5231            /*
     5232             * Add mixer input sinks.
     5233             */
    47115234            rc = AudioMixerAddSink(pThis->pMixer, "[Recording] Line In",
    47125235                                   AUDMIXSINKDIR_INPUT, &pThis->pSinkLineIn);
    47135236            AssertRC(rc);
    4714 
     5237#ifdef VBOX_WITH_HDA_MIC_IN
    47155238            rc = AudioMixerAddSink(pThis->pMixer, "[Recording] Microphone In",
    47165239                                   AUDMIXSINKDIR_INPUT, &pThis->pSinkMicIn);
    47175240            AssertRC(rc);
    4718 
     5241#endif
    47195242            /* There is no master volume control. Set the master to max. */
    47205243            PDMAUDIOVOLUME vol = { false, 255, 255 };
     
    47325255
    47335256        /* Audio driver callbacks for multiplexing. */
    4734         pThis->pCodec->pfnCloseIn   = hdaCloseIn;
    4735         pThis->pCodec->pfnCloseOut  = hdaCloseOut;
    4736         pThis->pCodec->pfnOpenIn    = hdaOpenIn;
    4737         pThis->pCodec->pfnOpenOut   = hdaOpenOut;
    4738         pThis->pCodec->pfnReset     = hdaCodecReset;
    4739         pThis->pCodec->pfnSetVolume = hdaSetVolume;
     5257        pThis->pCodec->pfnMixerAddStream    = hdaMixerAddStream;
     5258        pThis->pCodec->pfnMixerRemoveStream = hdaMixerRemoveStream;
     5259        pThis->pCodec->pfnMixerSetVolume    = hdaMixerSetVolume;
     5260        pThis->pCodec->pfnReset             = hdaCodecReset;
    47405261
    47415262        pThis->pCodec->pHDAState = pThis; /* Assign HDA controller state to codec. */
     
    47565277    if (RT_SUCCESS(rc))
    47575278    {
    4758         rc = hdaStreamCreate(&pThis->StrmStLineIn);
    4759         AssertRC(rc);
    4760 #ifdef VBOX_WITH_HDA_MIC_IN
    4761         rc = hdaStreamCreate(&pThis->StrmStMicIn);
    4762         AssertRC(rc);
    4763 #endif
    4764         rc = hdaStreamCreate(&pThis->StrmStOut);
    4765         AssertRC(rc);
    4766 
     5279        /*
     5280         * Create all hardware streams.
     5281         */
     5282        for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
     5283        {
     5284            rc = hdaStreamCreate(&pThis->aStreams[i], i /* uSD */);
     5285            AssertRC(rc);
     5286        }
     5287
     5288        /*
     5289         * As we don't have any dynamic stream <-> mixer sink mapping (yet),
     5290         * hard-wire the associations here.
     5291         */
     5292#ifdef VBOX_WITH_HDA_51_SURROUND
     5293# error "Implement me!" /** @todo */
     5294#else
     5295        /* Same goes for the input sink. */
     5296        for (uint8_t i = 0; i < HDA_MAX_SDI; i++)
     5297            pThis->aStreams[i].pSink = pThis->pSinkLineIn;
     5298# ifdef VBOX_WITH_HDA_MIC_IN
     5299#  error "Implement me!" /** @todo */
     5300# endif
     5301        /* Assign all output streams to the one-and-only output sink. */
     5302        for (uint8_t i = HDA_MAX_SDI; i < HDA_MAX_SDO; i++)
     5303            pThis->aStreams[i].pSink = pThis->pSinkFront;
     5304#endif /* VBOX_WITH_HDA_51_SURROUND */
     5305
     5306        /*
     5307         * Initialize the driver chain.
     5308         */
    47675309        PHDADRIVER pDrv;
    47685310        RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
     
    47785320            AssertPtr(pCon);
    47795321
    4780             bool fValidLineIn = pCon->pfnIsValidIn(pCon, pDrv->LineIn.pStrmIn);
     5322            bool fValidLineIn = pCon->pfnIsValidIn(pCon,  pDrv->LineIn.pGstStrm);
    47815323#ifdef VBOX_WITH_HDA_MIC_IN
    4782             bool fValidMicIn  = pCon->pfnIsValidIn (pCon, pDrv->MicIn.pStrmIn);
    4783 #endif
    4784             bool fValidOut    = pCon->pfnIsValidOut(pCon, pDrv->Out.pStrmOut);
     5324            bool fValidMicIn  = pCon->pfnIsValidIn (pCon, pDrv->MicIn.pGstStrm);
     5325#endif
     5326            bool fValidOut    = pCon->pfnIsValidOut(pCon, pDrv->Front.pGstStrm);
    47855327
    47865328            if (    !fValidLineIn
     
    48855427         * Debug and string formatter types.
    48865428         */
    4887         PDMDevHlpDBGFInfoRegister(pDevIns, "hda",         "HDA info. (hda [register case-insensitive])",    hdaInfo);
    4888         PDMDevHlpDBGFInfoRegister(pDevIns, "hdastrm",     "HDA stream info. (hdastrm [stream number])",     hdaInfoStream);
    4889         PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes",    "HDA codec nodes.",                               hdaInfoCodecNodes);
    4890         PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].",     hdaInfoCodecSelector);
    4891         PDMDevHlpDBGFInfoRegister(pDevIns, "hdamixer",    "HDA mixer state.",                               hdaInfoMixer);
     5429        PDMDevHlpDBGFInfoRegister(pDevIns, "hda",         "HDA info. (hda [register case-insensitive])",     hdaDbgInfo);
     5430        PDMDevHlpDBGFInfoRegister(pDevIns, "hdabdle",     "HDA stream BDLE info. (hdabdle [stream number])", hdaDbgInfoBDLE);
     5431        PDMDevHlpDBGFInfoRegister(pDevIns, "hdastrm",     "HDA stream info. (hdastrm [stream number])",      hdaDbgInfoStream);
     5432        PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes",    "HDA codec nodes.",                                hdaDbgInfoCodecNodes);
     5433        PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].",      hdaDbgInfoCodecSelector);
     5434        PDMDevHlpDBGFInfoRegister(pDevIns, "hdamixer",    "HDA mixer state.",                                hdaDbgInfoMixer);
    48925435
    48935436        rc = RTStrFormatTypeRegister("bdle",    hdaDbgFmtBDLE,    NULL);
  • trunk/src/VBox/Devices/Audio/DevIchHdaCodec.cpp

    r59541 r60353  
    3636#include "VBoxDD.h"
    3737#include "DevIchHdaCodec.h"
     38#include "DevIchHdaCommon.h"
     39#include "AudioMixer.h"
    3840
    3941
     
    103105#define CODEC_F00_00_VENDORID(f00_00)                      (((f00_00) >> 16) & 0xFFFF)
    104106#define CODEC_F00_00_DEVICEID(f00_00)                      ((f00_00) & 0xFFFF)
    105 /* RevisionID (7.3.4.2)*/
    106 #define CODEC_MAKE_F00_02(MajRev, MinRev, RevisionID, SteppingID) (((MajRev) << 20)|((MinRev) << 16)|((RevisionID) << 8)|(SteppingID))
    107 /* Subordinate node count (7.3.4.3)*/
     107
     108/** RevisionID (7.3.4.2). */
     109#define CODEC_MAKE_F00_02(majRev, minRev, venFix, venProg, stepFix, stepProg) \
     110    (  (((majRev)   & 0xF) << 20) \
     111     | (((minRev)   & 0xF) << 16) \
     112     | (((venFix)   & 0xF) << 12) \
     113     | (((venProg)  & 0xF) << 8)  \
     114     | (((stepFix)  & 0xF) << 4)  \
     115     |  ((stepProg) & 0xF))
     116
     117/** Subordinate node count (7.3.4.3). */
    108118#define CODEC_MAKE_F00_04(startNodeNumber, totalNodeNumber) ((((startNodeNumber) & 0xFF) << 16)|((totalNodeNumber) & 0xFF))
    109119#define CODEC_F00_04_TO_START_NODE_NUMBER(f00_04)          (((f00_04) >> 16) & 0xFF)
     
    120130#define CODEC_F00_05_IS_UNSOL(f00_05)                      RT_BOOL((f00_05) & RT_BIT(8))
    121131#define CODEC_F00_05_GROUP(f00_05)                         ((f00_05) & 0xff)
    122 /*  Audio Function Group capabilities (7.3.4.5) */
     132/* Audio Function Group capabilities (7.3.4.5). */
    123133#define CODEC_MAKE_F00_08(BeepGen, InputDelay, OutputDelay) ((((BeepGen) & 0x1) << 16)| (((InputDelay) & 0xF) << 8) | ((OutputDelay) & 0xF))
    124134#define CODEC_F00_08_BEEP_GEN(f00_08)                      ((f00_08) & RT_BIT(16)
    125135
    126 /* Widget Capabilities (7.3.4.6) */
    127 #define CODEC_MAKE_F00_09(type, delay, chanel_count) \
    128     ( (((type) & 0xF) << 20)            \
    129     | (((delay) & 0xF) << 16)           \
    130     | (((chanel_count) & 0xF) << 13))
     136/* Converter Stream, Channel (7.3.3.11). */
     137#define CODEC_F00_06_GET_STREAM_ID(cmd)                    (((cmd) >> 4) & 0x0F)
     138#define CODEC_F00_06_GET_CHANNEL_ID(cmd)                   (((cmd) & 0x0F))
     139
     140/* Widget Capabilities (7.3.4.6). */
     141#define CODEC_MAKE_F00_09(type, delay, chan_ext) \
     142    ( (((type)     & 0xF) << 20)            \
     143    | (((delay)    & 0xF) << 16)           \
     144    | (((chan_ext) & 0xF) << 13))
    131145/* note: types 0x8-0xe are reserved */
    132146#define CODEC_F00_09_TYPE_AUDIO_OUTPUT                     (0x0)
     
    152166#define CODEC_F00_09_CAP_OUT_AMP_PRESENT                   RT_BIT(2)
    153167#define CODEC_F00_09_CAP_IN_AMP_PRESENT                    RT_BIT(1)
    154 #define CODEC_F00_09_CAP_LSB                               RT_BIT(0)
     168#define CODEC_F00_09_CAP_STEREO                            RT_BIT(0)
    155169
    156170#define CODEC_F00_09_TYPE(f00_09)                          (((f00_09) >> 20) & 0xF)
     
    208222#define CODEC_F00_0C_CAP_INPUT                             RT_BIT(5)
    209223#define CODEC_F00_0C_CAP_OUTPUT                            RT_BIT(4)
    210 #define CODEC_F00_0C_CAP_HP                                RT_BIT(3)
     224#define CODEC_F00_0C_CAP_HEADPHONE_AMP                     RT_BIT(3)
    211225#define CODEC_F00_0C_CAP_PRESENSE_DETECT                   RT_BIT(2)
    212226#define CODEC_F00_0C_CAP_TRIGGER_REQUIRED                  RT_BIT(1)
     
    225239#define CODEC_F00_0C_IS_CAP_IMPENDANCE_SENSE(f00_0c)       ((f00_0c) & RT_BIT(0))
    226240
    227 /* Input Amplifier capabilities (7.3.4.10) */
     241/* Input Amplifier capabilities (7.3.4.10). */
    228242#define CODEC_MAKE_F00_0D(mute_cap, step_size, num_steps, offset) \
    229         (  (((mute_cap) & 0x1) << 31)                             \
     243        (  (((mute_cap)  & 0x1)  << 31)                           \
    230244         | (((step_size) & 0xFF) << 16)                           \
    231245         | (((num_steps) & 0xFF) << 8)                            \
    232          | ((offset) & 0xFF))
     246         |  ((offset)    & 0xFF))
    233247
    234248#define CODEC_F00_0D_CAP_MUTE                              RT_BIT(7)
     
    239253#define CODEC_F00_0D_OFFSET(f00_0d)                        (  (f00_0d) & 0x7F)
    240254
     255/** Indicates that the amplifier can be muted. */
     256#define CODEC_AMP_CAP_MUTE                                 0x1
     257/** The amplifier's maximum number of steps. We want
     258 *  a ~90dB dynamic range, so 64 steps with 1.25dB each
     259 *  should do the trick.
     260 *
     261 *  As we want to map our range to [0..128] values we can avoid
     262 *  multiplication and simply doing a shift later.
     263 *
     264 *  Produces -96dB to +0dB.
     265 *  "0" indicates a step of 0.25dB, "127" indicates a step of 32dB.
     266 */
     267#define CODEC_AMP_NUM_STEPS                                0x7F
     268/** The initial gain offset (and when doing a node reset). */
     269#define CODEC_AMP_OFF_INITIAL                              0x40
     270/** The amplifier's gain step size. */
     271#define CODEC_AMP_STEP_SIZE                                0x2
     272
    241273/* Output Amplifier capabilities (7.3.4.10) */
    242274#define CODEC_MAKE_F00_12                                  CODEC_MAKE_F00_0D
     
    247279#define CODEC_F00_12_OFFSET(f00_12)                        CODEC_F00_0D_OFFSET(f00_12)
    248280
    249 /* Connection list lenght (7.3.4.11) */
     281/* Connection list lenght (7.3.4.11). */
    250282#define CODEC_MAKE_F00_0E(long_form, length)    \
    251283    (  (((long_form) & 0x1) << 7)               \
     
    272304#define CODEC_F00_10_BENING(f00_10)                        ((f00_10) & 0x1)
    273305
    274 /* CP/IO Count (7.3.4.14) */
     306/* GPIO count (7.3.4.14). */
    275307#define CODEC_MAKE_F00_11(wake, unsol, numgpi, numgpo, numgpio) \
    276308    (  (((wake) & 0x1) << 31)                                   \
     
    280312     | ((numgpio) & 0xFF))
    281313
    282 /* Processing States (7.3.3.4) */
     314/* Processing States (7.3.3.4). */
    283315#define CODEC_F03_OFF                                      (0)
    284316#define CODEC_F03_ON                                       RT_BIT(0)
    285317#define CODEC_F03_BENING                                   RT_BIT(1)
    286 /* Power States (7.3.3.10) */
    287 #define CODEC_MAKE_F05(reset, stopok, error, act, set)          \
    288     (   (((reset) & 0x1) << 10)                                 \
    289       | (((stopok) & 0x1) << 9)                                 \
    290       | (((error) & 0x1) << 8)                                  \
    291       | (((act) & 0x7) << 4)                                    \
    292       | ((set) & 0x7))
     318/* Power States (7.3.3.10). */
     319#define CODEC_MAKE_F05(reset, stopok, error, act, set) \
     320    (   (((reset)  & 0x1) << 10)                       \
     321     | (((stopok) & 0x1) << 9)                         \
     322     | (((error)  & 0x1) << 8)                         \
     323     | (((act)    & 0xF) << 4)                         \
     324     | ((set)     & 0xF))
    293325#define CODEC_F05_D3COLD                                   (4)
    294326#define CODEC_F05_D3                                       (3)
     
    300332#define CODEC_F05_IS_STOPOK(value)                         (((value) & RT_BIT(9)) != 0)
    301333#define CODEC_F05_IS_ERROR(value)                          (((value) & RT_BIT(8)) != 0)
    302 #define CODEC_F05_ACT(value)                               (((value) & 0x7) >> 4)
    303 #define CODEC_F05_SET(value)                               (((value) & 0x7))
     334#define CODEC_F05_ACT(value)                               (((value) & 0xF0) >> 4)
     335#define CODEC_F05_SET(value)                               (((value) & 0xF))
    304336
    305337#define CODEC_F05_GE(p0, p1)                               ((p0) <= (p1))
    306338#define CODEC_F05_LE(p0, p1)                               ((p0) >= (p1))
    307339
    308 /* Pin Widged Control (7.3.3.13) */
     340/* Converter Stream, Channel (7.3.3.11). */
     341#define CODEC_MAKE_F06(stream, channel) \
     342    (  (((stream)  & 0xF) << 4)         \
     343     |  ((channel) & 0xF))
     344#define CODEC_F06_STREAM(value)                            ((value) & 0xF0)
     345#define CODEC_F06_CHANNEL(value)                           ((value) & 0xF)
     346
     347/* Pin Widged Control (7.3.3.13). */
    309348#define CODEC_F07_VREF_HIZ                                 (0)
    310349#define CODEC_F07_VREF_50                                  (0x1)
     
    316355#define CODEC_F07_OUT_H_ENABLE                             RT_BIT(7)
    317356
    318 /* Unsolicited enabled (7.3.3.14) */
     357/* Volume Knob Control (7.3.3.29). */
     358#define CODEC_F0F_IS_DIRECT                                RT_BIT(7)
     359#define CODEC_F0F_VOLUME                                   (0x7F)
     360
     361/* Unsolicited enabled (7.3.3.14). */
    319362#define CODEC_MAKE_F08(enable, tag) ((((enable) & 1) << 7) | ((tag) & 0x3F))
    320363
    321 /* Converter formats (7.3.3.8) and (3.7.1) */
    322 #define CODEC_MAKE_A(fNonPCM, f44_1BaseRate, mult, div, bits, chan) \
    323     (  (((fNonPCM) & 0x1) << 15)                                    \
    324      | (((f44_1BaseRate) & 0x1) << 14)                              \
    325      | (((mult) & 0x7) << 11)                                       \
    326      | (((div) & 0x7) << 8)                                         \
    327      | (((bits) & 0x7) << 4)                                        \
    328      | ((chan) & 0xF))
    329 
    330 #define CODEC_A_TYPE                                       RT_BIT(15)
    331 #define CODEC_A_TYPE_PCM                                   (0)
    332 #define CODEC_A_TYPE_NON_PCM                               (1)
    333 
    334 #define CODEC_A_BASE                                       RT_BIT(14)
    335 #define CODEC_A_BASE_48KHZ                                 (0)
    336 #define CODEC_A_BASE_44KHZ                                 (1)
    337 
    338 #define CODEC_A_MULT_1X                                    (0)
    339 #define CODEC_A_MULT_2X                                    (1)
    340 #define CODEC_A_MULT_3X                                    (2)
    341 #define CODEC_A_MULT_4X                                    (3)
    342 
    343 #define CODEC_A_DIV_1X                                     (0)
    344 #define CODEC_A_DIV_2X                                     (1)
    345 #define CODEC_A_DIV_3X                                     (2)
    346 #define CODEC_A_DIV_4X                                     (3)
    347 #define CODEC_A_DIV_5X                                     (4)
    348 #define CODEC_A_DIV_6X                                     (5)
    349 #define CODEC_A_DIV_7X                                     (6)
    350 #define CODEC_A_DIV_8X                                     (7)
    351 
    352 #define CODEC_A_8_BIT                                      (0)
    353 #define CODEC_A_16_BIT                                     (1)
    354 #define CODEC_A_20_BIT                                     (2)
    355 #define CODEC_A_24_BIT                                     (3)
    356 #define CODEC_A_32_BIT                                     (4)
    357 
    358 #define CODEC_A_CHAN_MONO                                  (0)
    359 #define CODEC_A_CHAN_STEREO                                (1)
    360 
    361 /* Pin Sense (7.3.3.15) */
     364/* Converter formats (7.3.3.8) and (3.7.1). */
     365/* This is the same format as SDnFMT. */
     366#define CODEC_MAKE_A                                       HDA_SDFMT_MAKE
     367
     368#define CODEC_A_TYPE                                       HDA_SDFMT_TYPE
     369#define CODEC_A_TYPE_PCM                                   HDA_SDFMT_TYPE_PCM
     370#define CODEC_A_TYPE_NON_PCM                               HDA_SDFMT_TYPE_NON_PCM
     371
     372#define CODEC_A_BASE                                       HDA_SDFMT_BASE
     373#define CODEC_A_BASE_48KHZ                                 HDA_SDFMT_BASE_48KHZ
     374#define CODEC_A_BASE_44KHZ                                 HDA_SDFMT_BASE_44KHZ
     375
     376/* Pin Sense (7.3.3.15). */
    362377#define CODEC_MAKE_F09_ANALOG(fPresent, impedance)  \
    363378(  (((fPresent) & 0x1) << 31)                       \
     
    477492#define CODEC_F1C_MISC_MASK                                (0xF)
    478493#define CODEC_F1C_MISC_SHIFT                               (8)
    479 #define CODEC_F1C_MISC_JACK_DETECT                         (0)
    480 #define CODEC_F1C_MISC_RESERVED_0                          (1)
    481 #define CODEC_F1C_MISC_RESERVED_1                          (2)
    482 #define CODEC_F1C_MISC_RESERVED_2                          (3)
     494#define CODEC_F1C_MISC_NONE                                0
     495#define CODEC_F1C_MISC_JACK_NO_PRESENCE_DETECT             RT_BIT(0)
     496#define CODEC_F1C_MISC_RESERVED_0                          RT_BIT(1)
     497#define CODEC_F1C_MISC_RESERVED_1                          RT_BIT(2)
     498#define CODEC_F1C_MISC_RESERVED_2                          RT_BIT(3)
    483499
    484500/* Configuration default: Association */
     
    486502#define CODEC_F1C_ASSOCIATION_SHIFT                        (4)
    487503
    488 /* Reserved; don't use. */
     504/** Reserved; don't use. */
    489505#define CODEC_F1C_ASSOCIATION_INVALID                      0x0
    490506#define CODEC_F1C_ASSOCIATION_GROUP_0                      0x1
     
    498514#define CODEC_F1C_ASSOCIATION_GROUP_15                     0xF
    499515
    500 /* Configuration default: Association Sequence */
     516/* Configuration default: Association Sequence. */
    501517#define CODEC_F1C_SEQ_MASK                                 (0xF)
    502518#define CODEC_F1C_SEQ_SHIFT                                (0)
    503519
    504 /* Implementation identification (7.3.3.30) */
     520/* Implementation identification (7.3.3.30). */
    505521#define CODEC_MAKE_F20(bmid, bsku, aid)     \
    506522    (  (((bmid) & 0xFFFF) << 16)            \
     
    509525    )
    510526
    511 /* macro definition helping in filling the configuration registers. */
     527/* Macro definition helping in filling the configuration registers. */
    512528#define CODEC_MAKE_F1C(port_connectivity, location, device, connection_type, color, misc, association, sequence)    \
    513     (  ((port_connectivity) << CODEC_F1C_PORT_SHIFT)          \
    514      | ((location) << CODEC_F1C_LOCATION_SHIFT)               \
    515      | ((device) << CODEC_F1C_DEVICE_SHIFT)                   \
    516      | ((connection_type) << CODEC_F1C_CONNECTION_TYPE_SHIFT) \
    517      | ((color) << CODEC_F1C_COLOR_SHIFT)                     \
    518      | ((misc) << CODEC_F1C_MISC_SHIFT)                       \
    519      | ((association) << CODEC_F1C_ASSOCIATION_SHIFT)         \
    520      | ((sequence)))
     529    (  (((port_connectivity) & 0xF) << CODEC_F1C_PORT_SHIFT)            \
     530     | (((location)          & 0xF) << CODEC_F1C_LOCATION_SHIFT)        \
     531     | (((device)            & 0xF) << CODEC_F1C_DEVICE_SHIFT)          \
     532     | (((connection_type)   & 0xF) << CODEC_F1C_CONNECTION_TYPE_SHIFT) \
     533     | (((color)             & 0xF) << CODEC_F1C_COLOR_SHIFT)           \
     534     | (((misc)              & 0xF) << CODEC_F1C_MISC_SHIFT)            \
     535     | (((association)       & 0xF) << CODEC_F1C_ASSOCIATION_SHIFT)     \
     536     | (((sequence)          & 0xF)))
    521537
    522538
     
    585601{
    586602    CODECCOMMONNODE node;
     603    uint32_t    u32F01_param;
    587604    uint32_t    u32F03_param;
    588605    uint32_t    u32F05_param;
     
    591608
    592609    uint32_t    u32A_param;
    593     uint32_t    u32F01_param;
    594610    AMPLIFIER   B_params;
    595611} ADCNODE, *PADCNODE;
     
    627643    uint32_t  u32F05_param;
    628644    uint32_t  u32F08_param;
     645    uint32_t  u32F17_param;
    629646    uint32_t  u32F20_param;
    630     uint32_t  u32F17_param;
    631647} AFGCODECNODE, *PAFGCODECNODE;
    632648AssertNodeSize(AFGCODECNODE, 4);
     
    635651{
    636652    CODECCOMMONNODE node;
     653    uint32_t u32F01_param;
    637654    uint32_t u32F07_param;
    638655    uint32_t u32F08_param;
    639656    uint32_t u32F09_param;
    640     uint32_t u32F01_param;
    641657    uint32_t u32F1c_param;
    642658    AMPLIFIER   B_params;
     
    648664    CODECCOMMONNODE node;
    649665    uint32_t u32F01_param;
     666    uint32_t u32F05_param;
     667    uint32_t u32F07_param;
    650668    uint32_t u32F08_param;
    651     uint32_t u32F07_param;
    652669    uint32_t u32F09_param;
    653670    uint32_t u32F1c_param;
    654671} DIGOUTNODE, *PDIGOUTNODE;
    655 AssertNodeSize(DIGOUTNODE, 5);
     672AssertNodeSize(DIGOUTNODE, 6);
    656673
    657674typedef struct DIGINNODE
     
    723740    uint32_t    u32F07_param;
    724741    uint32_t    u32F1c_param;
     742
     743    uint32_t    u32A_param;
    725744} RESNODE, *PRESNODE;
    726 AssertNodeSize(RESNODE, 4);
     745AssertNodeSize(RESNODE, 5);
    727746
    728747/**
     
    773792#define STAC9220_NID_SPDIF_OUT                             0x8  /* Out */
    774793#define STAC9220_NID_SPDIF_IN                              0x9  /* In */
     794/** Also known as PIN_A. */
    775795#define STAC9220_NID_PIN_HEADPHONE0                        0xA  /* In, Out */
    776796#define STAC9220_NID_PIN_B                                 0xB  /* In, Out */
    777797#define STAC9220_NID_PIN_C                                 0xC  /* In, Out */
     798/** Also known as PIN D. */
    778799#define STAC9220_NID_PIN_HEADPHONE1                        0xD  /* In, Out */
    779800#define STAC9220_NID_PIN_E                                 0xE  /* In */
    780801#define STAC9220_NID_PIN_F                                 0xF  /* In, Out */
     802/** Also known as DIGOUT0. */
    781803#define STAC9220_NID_PIN_SPDIF_OUT                         0x10 /* Out */
     804/** Also known as DIGIN. */
    782805#define STAC9220_NID_PIN_SPDIF_IN                          0x11 /* In */
    783806#define STAC9220_NID_ADC0_MUX                              0x12 /* In */
     
    788811#define STAC9220_NID_AMP_ADC0                              0x17 /* In */
    789812#define STAC9220_NID_AMP_ADC1                              0x18 /* In */
    790 /* STAC9221. */
     813/* Only for STAC9221. */
    791814#define STAC9221_NID_ADAT_OUT                              0x19 /* Out */
    792815#define STAC9221_NID_I2S_OUT                               0x1A /* Out */
    793816#define STAC9221_NID_PIN_I2S_OUT                           0x1B /* Out */
    794817
    795 #if 1
    796 /* STAC9220 - Referenced thru STAC9220WIDGET in the constructor below. */
    797 static uint8_t const g_abStac9220Ports[]      = { 0x0A, 0xB, 0xC, 0xD, 0xE, 0xF, 0};
    798 static uint8_t const g_abStac9220Dacs[]       = { 0x02, 0x3, 0x4, 0x5, 0};
    799 static uint8_t const g_abStac9220Adcs[]       = { 0x06, 0x7, 0};
    800 static uint8_t const g_abStac9220SpdifOuts[]  = { 0x08, 0 };
    801 static uint8_t const g_abStac9220SpdifIns[]   = { 0x09, 0 };
    802 static uint8_t const g_abStac9220DigOutPins[] = { 0x10, 0 };
    803 static uint8_t const g_abStac9220DigInPins[]  = { 0x11, 0 };
    804 static uint8_t const g_abStac9220AdcVols[]    = { 0x17, 0x18, 0};
    805 static uint8_t const g_abStac9220AdcMuxs[]    = { 0x12, 0x13, 0};
    806 static uint8_t const g_abStac9220Pcbeeps[]    = { 0x14, 0 };
    807 static uint8_t const g_abStac9220Cds[]        = { 0x15, 0 };
    808 static uint8_t const g_abStac9220VolKnobs[]   = { 0x16, 0 };
    809 static uint8_t const g_abStac9220Reserveds[]  = { 0x09, 0x19, 0x1a, 0x1b, 0 };
    810 #else /** @todo Enable this after 5.0 -- needs more testing first. */
    811 static uint8_t const g_abStac9220Ports[]      = { STAC9220_NID_PIN_HEADPHONE0, STAC9220_NID_PIN_B, STAC9220_NID_PIN_C, STAC9220_NID_PIN_HEADPHONE1, STAC9220_NID_PIN_E, STAC9220_NID_PIN_F, 0};
    812 static uint8_t const g_abStac9220Dacs[]       = { STAC9220_NID_DAC0, STAC9220_NID_DAC1, STAC9220_NID_DAC2, STAC9220_NID_DAC3, 0};
    813 static uint8_t const g_abStac9220Adcs[]       = { STAC9220_NID_ADC0, STAC9220_NID_ADC1, 0};
     818/** Number of total nodes emulated. */
     819#define STAC9221_NUM_NODES                                 0x1C
     820
     821/* STAC9220 - Referenced through STAC9220WIDGET in the constructor below. */
     822static uint8_t const g_abStac9220Ports[]      = { STAC9220_NID_PIN_HEADPHONE0, STAC9220_NID_PIN_B, STAC9220_NID_PIN_C, STAC9220_NID_PIN_HEADPHONE1, STAC9220_NID_PIN_E, STAC9220_NID_PIN_F, 0 };
     823static uint8_t const g_abStac9220Dacs[]       = { STAC9220_NID_DAC0, STAC9220_NID_DAC1, STAC9220_NID_DAC2, STAC9220_NID_DAC3, 0 };
     824static uint8_t const g_abStac9220Adcs[]       = { STAC9220_NID_ADC0, STAC9220_NID_ADC1, 0 };
    814825static uint8_t const g_abStac9220SpdifOuts[]  = { STAC9220_NID_SPDIF_OUT, 0 };
    815826static uint8_t const g_abStac9220SpdifIns[]   = { STAC9220_NID_SPDIF_IN, 0 };
    816827static uint8_t const g_abStac9220DigOutPins[] = { STAC9220_NID_PIN_SPDIF_OUT, 0 };
    817828static uint8_t const g_abStac9220DigInPins[]  = { STAC9220_NID_PIN_SPDIF_IN, 0 };
    818 static uint8_t const g_abStac9220AdcVols[]    = { STAC9220_NID_AMP_ADC0, STAC9220_NID_AMP_ADC1, 0};
    819 static uint8_t const g_abStac9220AdcMuxs[]    = { STAC9220_NID_ADC0_MUX, STAC9220_NID_ADC1_MUX, 0};
     829static uint8_t const g_abStac9220AdcVols[]    = { STAC9220_NID_AMP_ADC0, STAC9220_NID_AMP_ADC1, 0 };
     830static uint8_t const g_abStac9220AdcMuxs[]    = { STAC9220_NID_ADC0_MUX, STAC9220_NID_ADC1_MUX, 0 };
    820831static uint8_t const g_abStac9220Pcbeeps[]    = { STAC9220_NID_PCBEEP, 0 };
    821832static uint8_t const g_abStac9220Cds[]        = { STAC9220_NID_PIN_CD, 0 };
     
    824835/** @todo Is STAC9220_NID_SPDIF_IN really correct for reserved nodes? */
    825836static uint8_t const g_abStac9220Reserveds[]  = { STAC9220_NID_SPDIF_IN, STAC9221_NID_ADAT_OUT, STAC9221_NID_I2S_OUT, STAC9221_NID_PIN_I2S_OUT, 0 };
    826 #endif
    827837
    828838/** SSM description of a CODECNODE. */
     
    854864static DECLCALLBACK(void) stac9220DbgNodes(PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)
    855865{
    856     for (int i = 1; i < 12; i++)
     866    for (int i = 1; i < pThis->cTotalNodes; i++)
    857867    {
    858868        PCODECNODE pNode = &pThis->paNodes[i];
     
    867877
    868878
    869 static DECLCALLBACK(int) stac9220ResetNode(PHDACODEC pThis, uint8_t nodenum, PCODECNODE pNode)
    870 {
    871     pNode->node.id = nodenum;
    872     pNode->node.au32F00_param[0xF] = 0; /* Power statest Supported: are the same as AFG reports */
    873     switch (nodenum)
    874     {
    875         /* Root Node*/
    876         case 0:
    877             pNode->node.au32F00_param[0x02] = CODEC_MAKE_F00_02(0x1, 0x0, 0x34, 0x1); /* rev id */
     879static DECLCALLBACK(int) stac9220ResetNode(PHDACODEC pThis, uint8_t uNID, PCODECNODE pNode)
     880{
     881    LogFlowFunc(("NID=0x%x (%RU8)\n", uNID, uNID));
     882
     883    if (   !pThis->fInReset
     884        && (   uNID != STAC9220_NID_ROOT
     885            && uNID != STAC9220_NID_AFG)
     886       )
     887    {
     888        RT_ZERO(pNode->node);
     889    }
     890
     891    /* Set common parameters across all nodes. */
     892    pNode->node.id = uNID;
     893
     894    switch (uNID)
     895    {
     896        /* Root node. */
     897        case STAC9220_NID_ROOT:
     898        {
     899            /* Set the revision ID. */
     900            pNode->root.node.au32F00_param[0x02] = CODEC_MAKE_F00_02(0x1, 0x0, 0x3, 0x4, 0x0, 0x1);
    878901            break;
    879         case 1:
    880             pNode->node.au32F00_param[0x08] = CODEC_MAKE_F00_08(1, 0xd, 0xd);
    881             pNode->node.au32F00_param[0x0C] = CODEC_MAKE_F00_0C(0x17)
    882                                             | CODEC_F00_0C_CAP_BALANCED_IO
    883                                             | CODEC_F00_0C_CAP_INPUT
    884                                             | CODEC_F00_0C_CAP_PRESENSE_DETECT
    885                                             | CODEC_F00_0C_CAP_TRIGGER_REQUIRED
    886                                             | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//(17 << 8)|RT_BIT(6)|RT_BIT(5)|RT_BIT(2)|RT_BIT(1)|RT_BIT(0);
    887             pNode->node.au32F00_param[0x0B] = CODEC_F00_0B_PCM;
    888             pNode->node.au32F00_param[0x0D] = CODEC_MAKE_F00_0D(1, 0x5, 0xE, 0);//RT_BIT(31)|(0x5 << 16)|(0xE)<<8;
    889             pNode->node.au32F00_param[0x12] = RT_BIT(31)|(0x2 << 16)|(0x7f << 8)|0x7f;
    890             pNode->node.au32F00_param[0x11] = CODEC_MAKE_F00_11(1, 1, 0, 0, 4);//0xc0000004;
    891             pNode->node.au32F00_param[0x0F] = CODEC_F00_0F_D3|CODEC_F00_0F_D2|CODEC_F00_0F_D1|CODEC_F00_0F_D0;
    892             pNode->afg.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D2, CODEC_F05_D2);//0x2 << 4| 0x2; /* PS-Act: D3, PS->Set D3  */
     902        }
     903
     904        /*
     905         * AFG (Audio Function Group).
     906         */
     907        case STAC9220_NID_AFG:
     908        {
     909            pNode->afg.node.au32F00_param[0x08] = CODEC_MAKE_F00_08(1, 0xd, 0xd);
     910            /* We set the AFG's PCM capabitilies fixed to 44.1kHz, 16-bit signed. */
     911            pNode->afg.node.au32F00_param[0x0A] = CODEC_F00_0A_44_1KHZ | CODEC_F00_0A_16_BIT;
     912            pNode->afg.node.au32F00_param[0x0B] = CODEC_F00_0B_PCM;
     913            pNode->afg.node.au32F00_param[0x0C] = CODEC_MAKE_F00_0C(0x17)
     914                                                | CODEC_F00_0C_CAP_BALANCED_IO
     915                                                | CODEC_F00_0C_CAP_INPUT
     916                                                | CODEC_F00_0C_CAP_OUTPUT
     917                                                | CODEC_F00_0C_CAP_PRESENSE_DETECT
     918                                                | CODEC_F00_0C_CAP_TRIGGER_REQUIRED
     919                                                | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;
     920
     921            /* Default input amplifier capabilities. */
     922            pNode->node.au32F00_param[0x0D] = CODEC_MAKE_F00_0D(CODEC_AMP_CAP_MUTE,
     923                                                                0 /* Step size */,
     924                                                                CODEC_AMP_NUM_STEPS,
     925                                                                0 /* Initial offset */);
     926            /* Default output amplifier capabilities. */
     927            pNode->node.au32F00_param[0x12] = CODEC_MAKE_F00_12(CODEC_AMP_CAP_MUTE,
     928                                                                CODEC_AMP_STEP_SIZE,
     929                                                                CODEC_AMP_NUM_STEPS,
     930                                                                CODEC_AMP_OFF_INITIAL);
     931
     932            pNode->afg.node.au32F00_param[0x11] = CODEC_MAKE_F00_11(1, 1, 0, 0, 4);
     933            pNode->afg.node.au32F00_param[0x0F] = CODEC_F00_0F_D3
     934                                                | CODEC_F00_0F_D2
     935                                                | CODEC_F00_0F_D1
     936                                                | CODEC_F00_0F_D0;
     937
     938            pNode->afg.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D2, CODEC_F05_D2); /* PS-Act: D2, PS->Set D2. */
    893939            pNode->afg.u32F08_param = 0;
    894940            pNode->afg.u32F17_param = 0;
    895941            break;
    896         case 2:
    897         case 3:
    898         case 4:
    899         case 5:
    900             memset(pNode->dac.B_params, 0, AMPLIFIER_SIZE);
    901             pNode->dac.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//RT_BIT(14)|(0x1 << 4)|0x1; /* 44100Hz/16bit/2ch */
    902 
    903             AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) = 0x7F | RT_BIT(7);
     942        }
     943
     944        /*
     945         * DACs.
     946         */
     947        case STAC9220_NID_DAC0: /* DAC0: Headphones 0 + 1 */
     948        case STAC9220_NID_DAC1: /* DAC1: PIN C */
     949        case STAC9220_NID_DAC2: /* DAC2: PIN B */
     950        case STAC9220_NID_DAC3: /* DAC3: PIN F */
     951        {
     952            pNode->dac.u32A_param = CODEC_MAKE_A(HDA_SDFMT_TYPE_PCM, HDA_SDFMT_BASE_44KHZ,
     953                                                 HDA_SDFMT_MULT_1X, HDA_SDFMT_DIV_1X, HDA_SDFMT_16_BIT,
     954                                                 HDA_SDFMT_CHAN_STEREO);
     955
     956            /* 7.3.4.6: Audio widget capabilities. */
     957            pNode->dac.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 13, 0)
     958                                               | CODEC_F00_09_CAP_L_R_SWAP
     959                                               | CODEC_F00_09_CAP_POWER_CTRL
     960                                               | CODEC_F00_09_CAP_OUT_AMP_PRESENT
     961                                               | CODEC_F00_09_CAP_STEREO;
     962
     963            /* Connection list; must be 0 if the only connection for the widget is
     964             * to the High Definition Audio Link. */
     965            pNode->dac.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 0 /* Entries */);
     966
     967            pNode->dac.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);
     968
     969            RT_ZERO(pNode->dac.B_params);
     970            AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT,  0) = 0x7F | RT_BIT(7);
    904971            AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_RIGHT, 0) = 0x7F | RT_BIT(7);
    905 
    906             pNode->dac.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0xD, 0)
    907                                              | CODEC_F00_09_CAP_L_R_SWAP
    908                                              | CODEC_F00_09_CAP_POWER_CTRL
    909                                              | CODEC_F00_09_CAP_OUT_AMP_PRESENT
    910                                              | CODEC_F00_09_CAP_LSB;//(0xD << 16) | RT_BIT(11) |  RT_BIT(10) | RT_BIT(2) | RT_BIT(0);
    911             pNode->dac.u32F0c_param = 0;
    912             pNode->dac.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3, Set: D3  */
    913972            break;
    914         case 6:
    915             pNode->node.au32F02_param[0] = 0x17;
     973        }
     974
     975        /*
     976         * ADCs.
     977         */
     978        case STAC9220_NID_ADC0: /* Analog input. */
     979        {
     980            pNode->node.au32F02_param[0] = STAC9220_NID_AMP_ADC0;
    916981            goto adc_init;
    917         case 7:
    918             pNode->node.au32F02_param[0] = 0x18;
     982        }
     983
     984        case STAC9220_NID_ADC1: /* Analog input (CD). */
     985        {
     986            pNode->node.au32F02_param[0] = STAC9220_NID_AMP_ADC1;
     987
     988            /* Fall through is intentional. */
    919989        adc_init:
    920             pNode->adc.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//RT_BIT(14)|(0x1 << 3)|0x1; /* 44100Hz/16bit/2ch */
    921             pNode->adc.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//RT_BIT(0);
     990
     991            pNode->adc.u32A_param   = CODEC_MAKE_A(HDA_SDFMT_TYPE_PCM, HDA_SDFMT_BASE_44KHZ,
     992                                                   HDA_SDFMT_MULT_1X, HDA_SDFMT_DIV_1X, HDA_SDFMT_16_BIT,
     993                                                   HDA_SDFMT_CHAN_STEREO);
     994
    922995            pNode->adc.u32F03_param = RT_BIT(0);
    923             pNode->adc.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3 Set: D3 */
    924             pNode->adc.u32F06_param = 0;
    925             pNode->adc.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 0xD, 0)
    926                                              | CODEC_F00_09_CAP_POWER_CTRL
    927                                              | CODEC_F00_09_CAP_CONNECTION_LIST
    928                                              | CODEC_F00_09_CAP_PROC_WIDGET
    929                                              | CODEC_F00_09_CAP_LSB;//RT_BIT(20)| (0xd << 16) |  RT_BIT(10) | RT_BIT(8) | RT_BIT(6)| RT_BIT(0);
     996            pNode->adc.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3); /* PS-Act: D3 Set: D3 */
     997
     998            pNode->adc.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 13, 0)
     999                                               | CODEC_F00_09_CAP_POWER_CTRL
     1000                                               | CODEC_F00_09_CAP_CONNECTION_LIST
     1001                                               | CODEC_F00_09_CAP_PROC_WIDGET
     1002                                               | CODEC_F00_09_CAP_STEREO;
     1003            /* Connection list entries. */
     1004            pNode->adc.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */);
    9301005            break;
    931         case 8:
    932             pNode->spdifout.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
    933             pNode->spdifout.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0x4, 0)
    934                                                   | CODEC_F00_09_CAP_DIGITAL
    935                                                   | CODEC_F00_09_CAP_FMT_OVERRIDE
    936                                                   | CODEC_F00_09_CAP_LSB;//(4 << 16) | RT_BIT(9)|RT_BIT(4)|0x1;
    937             pNode->node.au32F00_param[0xa] = pThis->paNodes[1].node.au32F00_param[0xA];
    938             pNode->spdifout.node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
     1006        }
     1007
     1008        /*
     1009         * SP/DIF In/Out.
     1010         */
     1011        case STAC9220_NID_SPDIF_OUT:
     1012        {
     1013            pNode->spdifout.u32A_param   = CODEC_MAKE_A(HDA_SDFMT_TYPE_PCM, HDA_SDFMT_BASE_44KHZ,
     1014                                                        HDA_SDFMT_MULT_1X, HDA_SDFMT_DIV_1X, HDA_SDFMT_16_BIT,
     1015                                                        HDA_SDFMT_CHAN_STEREO);
    9391016            pNode->spdifout.u32F06_param = 0;
    9401017            pNode->spdifout.u32F0d_param = 0;
     1018
     1019            pNode->spdifout.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 4, 0)
     1020                                                    | CODEC_F00_09_CAP_DIGITAL
     1021                                                    | CODEC_F00_09_CAP_FMT_OVERRIDE
     1022                                                    | CODEC_F00_09_CAP_STEREO;
     1023
     1024            /* Use a fixed format from AFG. */
     1025            pNode->spdifout.node.au32F00_param[0xA] = pThis->paNodes[STAC9220_NID_AFG].node.au32F00_param[0xA];
     1026            pNode->spdifout.node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
    9411027            break;
    942         case 9:
    943             pNode->spdifin.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(0x1<<4) | 0x1;
    944             pNode->spdifin.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 0x4, 0)
    945                                                  | CODEC_F00_09_CAP_DIGITAL
    946                                                  | CODEC_F00_09_CAP_CONNECTION_LIST
    947                                                  | CODEC_F00_09_CAP_FMT_OVERRIDE
    948                                                  | CODEC_F00_09_CAP_LSB;//(0x1 << 20)|(4 << 16) | RT_BIT(9)| RT_BIT(8)|RT_BIT(4)|0x1;
    949             pNode->node.au32F00_param[0xA] = pThis->paNodes[1].node.au32F00_param[0xA];
    950             pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//RT_BIT(0);
    951             pNode->node.au32F02_param[0] = 0x11;
     1028        }
     1029
     1030        case STAC9220_NID_SPDIF_IN:
     1031        {
     1032            pNode->spdifin.u32A_param = CODEC_MAKE_A(HDA_SDFMT_TYPE_PCM, HDA_SDFMT_BASE_44KHZ,
     1033                                                     HDA_SDFMT_MULT_1X, HDA_SDFMT_DIV_1X, HDA_SDFMT_16_BIT,
     1034                                                     HDA_SDFMT_CHAN_STEREO);
     1035
     1036            pNode->spdifin.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 4, 0)
     1037                                                   | CODEC_F00_09_CAP_DIGITAL
     1038                                                   | CODEC_F00_09_CAP_CONNECTION_LIST
     1039                                                   | CODEC_F00_09_CAP_FMT_OVERRIDE
     1040                                                   | CODEC_F00_09_CAP_STEREO;
     1041
     1042            /* Use a fixed format from AFG. */
     1043            pNode->spdifin.node.au32F00_param[0xA] = pThis->paNodes[STAC9220_NID_AFG].node.au32F00_param[0xA];
    9521044            pNode->spdifin.node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
    953             pNode->spdifin.u32F06_param = 0;
    954             pNode->spdifin.u32F0d_param = 0;
     1045
     1046            /* Connection list entries. */
     1047            pNode->spdifin.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */);
     1048            pNode->spdifin.node.au32F02_param[0]   = 0x11;
    9551049            break;
    956         case 0xA:
    957             pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
    958                                            | CODEC_F00_0C_CAP_INPUT
    959                                            | CODEC_F00_0C_CAP_OUTPUT
    960                                            | CODEC_F00_0C_CAP_HP
    961                                            | CODEC_F00_0C_CAP_PRESENSE_DETECT
    962                                            | CODEC_F00_0C_CAP_TRIGGER_REQUIRED
    963                                            | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x173f;
    964             pNode->node.au32F02_param[0] = 0x2;
    965             pNode->port.u32F07_param = CODEC_F07_IN_ENABLE
    966                                      | CODEC_F07_OUT_ENABLE;
    967             pNode->port.u32F08_param = 0;
     1050        }
     1051
     1052        /*
     1053         * PINs / Ports.
     1054         */
     1055        case STAC9220_NID_PIN_HEADPHONE0: /* Port A: Headphone in/out (front). */
     1056        {
     1057            pNode->port.node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
     1058                                                | CODEC_F00_0C_CAP_INPUT
     1059                                                | CODEC_F00_0C_CAP_OUTPUT
     1060                                                | CODEC_F00_0C_CAP_HEADPHONE_AMP
     1061                                                | CODEC_F00_0C_CAP_PRESENSE_DETECT
     1062                                                | CODEC_F00_0C_CAP_TRIGGER_REQUIRED;
     1063
     1064            /* Connection list entry 0: Goes to DAC0. */
     1065            pNode->port.node.au32F02_param[0]   = STAC9220_NID_DAC0;
     1066
    9681067            if (!pThis->fInReset)
    9691068                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    9721071                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    9731072                                                          CODEC_F1C_COLOR_GREEN,
    974                                                           CODEC_F1C_MISC_JACK_DETECT,
    975                                                           0x2, 0);//RT_MAKE_U32_FROM_U8(0x20, 0x40, 0x21, 0x02);
    976             pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(0, CODEC_F09_ANALOG_NA);//0x7fffffff;
     1073                                                          CODEC_F1C_MISC_NONE,
     1074                                                          CODEC_F1C_ASSOCIATION_GROUP_0, 0xF /* Seq */);
    9771075            goto port_init;
    978         case 0xB:
    979             pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
    980                                            | CODEC_F00_0C_CAP_INPUT
    981                                            | CODEC_F00_0C_CAP_OUTPUT
    982                                            | CODEC_F00_0C_CAP_PRESENSE_DETECT
    983                                            | CODEC_F00_0C_CAP_TRIGGER_REQUIRED
    984                                            | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737;
    985             pNode->node.au32F02_param[0] = 0x4;
    986             pNode->port.u32F07_param = CODEC_F07_IN_ENABLE;
     1076        }
     1077
     1078        case STAC9220_NID_PIN_B: /* Port B: Rear CLFE (Center / Subwoofer). */
     1079        {
     1080            pNode->port.node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
     1081                                                | CODEC_F00_0C_CAP_INPUT
     1082                                                | CODEC_F00_0C_CAP_OUTPUT
     1083                                                | CODEC_F00_0C_CAP_PRESENSE_DETECT
     1084                                                | CODEC_F00_0C_CAP_TRIGGER_REQUIRED;
     1085
     1086            /* Connection list entry 0: Goes to DAC2. */
     1087            pNode->port.node.au32F02_param[0]   = STAC9220_NID_DAC2;
     1088
    9871089            if (!pThis->fInReset)
    9881090                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
    989                                                           CODEC_F1C_LOCATION_INTERNAL|CODEC_F1C_LOCATION_REAR,
     1091                                                          CODEC_F1C_LOCATION_REAR,
    9901092                                                          CODEC_F1C_DEVICE_SPEAKER,
    9911093                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    9921094                                                          CODEC_F1C_COLOR_BLACK,
    993                                                           CODEC_F1C_MISC_JACK_DETECT,
    994                                                           0x1, 0x1);//RT_MAKE_U32_FROM_U8(0x11, 0x60, 0x11, 0x01);
    995             pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA);//RT_BIT(31)|0x7fffffff;
     1095                                                          CODEC_F1C_MISC_NONE,
     1096                                                          CODEC_F1C_ASSOCIATION_GROUP_1, 0xE /* Seq */);
    9961097            goto port_init;
    997         case 0xC:
    998             pNode->node.au32F02_param[0] = 0x3;
    999             pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
    1000                                            | CODEC_F00_0C_CAP_INPUT
    1001                                            | CODEC_F00_0C_CAP_OUTPUT
    1002                                            | CODEC_F00_0C_CAP_PRESENSE_DETECT
    1003                                            | CODEC_F00_0C_CAP_TRIGGER_REQUIRED
    1004                                            | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737;
    1005             pNode->port.u32F07_param = CODEC_F07_IN_ENABLE;
     1098        }
     1099
     1100        case STAC9220_NID_PIN_C: /* Rear Speaker. */
     1101        {
     1102            pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA);
     1103
     1104            pNode->port.node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
     1105                                                | CODEC_F00_0C_CAP_INPUT
     1106                                                | CODEC_F00_0C_CAP_OUTPUT
     1107                                                | CODEC_F00_0C_CAP_PRESENSE_DETECT
     1108                                                | CODEC_F00_0C_CAP_TRIGGER_REQUIRED;
     1109
     1110            /* Connection list entry 0: Goes to DAC1. */
     1111            pNode->port.node.au32F02_param[0x0] = STAC9220_NID_DAC1;
     1112
    10061113            if (!pThis->fInReset)
    10071114                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    10101117                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    10111118                                                          CODEC_F1C_COLOR_GREEN,
    1012                                                           0x0, 0x1, 0x0);//RT_MAKE_U32_FROM_U8(0x10, 0x40, 0x11, 0x01);
    1013             pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA);//RT_BIT(31)|0x7fffffff;
     1119                                                          CODEC_F1C_MISC_NONE,
     1120                                                          CODEC_F1C_ASSOCIATION_GROUP_0, 0x0 /* Seq */);
    10141121            goto port_init;
    1015         case 0xD:
    1016             pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
    1017                                            | CODEC_F00_0C_CAP_INPUT
    1018                                            | CODEC_F00_0C_CAP_OUTPUT
    1019                                            | CODEC_F00_0C_CAP_PRESENSE_DETECT
    1020                                            | CODEC_F00_0C_CAP_TRIGGER_REQUIRED
    1021                                            | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737;
    1022             pNode->port.u32F07_param = CODEC_F07_IN_ENABLE;
    1023             pNode->node.au32F02_param[0] = 0x2;
     1122        }
     1123
     1124        case STAC9220_NID_PIN_HEADPHONE1: /* Also known as PIN_D. */
     1125        {
     1126            pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA);
     1127
     1128            pNode->port.node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
     1129                                                | CODEC_F00_0C_CAP_INPUT
     1130                                                | CODEC_F00_0C_CAP_OUTPUT
     1131                                                | CODEC_F00_0C_CAP_HEADPHONE_AMP
     1132                                                | CODEC_F00_0C_CAP_PRESENSE_DETECT
     1133                                                | CODEC_F00_0C_CAP_TRIGGER_REQUIRED;
     1134
     1135            /* Connection list entry 0: Goes to DAC1. */
     1136            pNode->port.node.au32F02_param[0x0] = STAC9220_NID_DAC0;
     1137
    10241138            if (!pThis->fInReset)
    10251139                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    10281142                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    10291143                                                          CODEC_F1C_COLOR_PINK,
    1030                                                           0x0, 0x5, 0x0);//RT_MAKE_U32_FROM_U8(0x50, 0x90, 0xA1, 0x02); /* Microphone */
    1031             pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA);//RT_BIT(31)|0x7fffffff;
     1144                                                          CODEC_F1C_MISC_NONE,
     1145                                                          CODEC_F1C_ASSOCIATION_GROUP_15, 0xD /* Seq */);
     1146            /* Fall through is intentional. */
    10321147        port_init:
     1148
     1149            pNode->port.u32F07_param = CODEC_F07_IN_ENABLE
     1150                                     | CODEC_F07_OUT_ENABLE;
    10331151            pNode->port.u32F08_param = 0;
    1034             pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0)
    1035                                          | CODEC_F00_09_CAP_CONNECTION_LIST
    1036                                          | CODEC_F00_09_CAP_UNSOL
    1037                                          | CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(8)|RT_BIT(7)|RT_BIT(0);
    1038             pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//0x1;
     1152            pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(true /* fPresent */, CODEC_F09_ANALOG_NA);
     1153
     1154            pNode->port.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
     1155                                                | CODEC_F00_09_CAP_CONNECTION_LIST
     1156                                                | CODEC_F00_09_CAP_UNSOL
     1157                                                | CODEC_F00_09_CAP_STEREO;
     1158            /* Connection list entries. */
     1159            pNode->port.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */);
    10391160            break;
    1040         case 0xE:
    1041             pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0)
    1042                                          | CODEC_F00_09_CAP_UNSOL
    1043                                          | CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(7)|RT_BIT(0);
     1161        }
     1162
     1163        case STAC9220_NID_PIN_E:
     1164        {
     1165            pNode->port.u32F07_param = CODEC_F07_IN_ENABLE;
    10441166            pNode->port.u32F08_param = 0;
    1045             pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT
    1046                                            | CODEC_F00_0C_CAP_OUTPUT
    1047                                            | CODEC_F00_0C_CAP_PRESENSE_DETECT;//0x34;
    1048             pNode->port.u32F07_param = CODEC_F07_IN_ENABLE;
    1049             pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(0, CODEC_F09_ANALOG_NA);//0x7fffffff;
     1167            pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(true /* fPresent */, CODEC_F09_ANALOG_NA);
     1168
     1169            pNode->port.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
     1170                                                | CODEC_F00_09_CAP_UNSOL
     1171                                                | CODEC_F00_09_CAP_STEREO;
     1172            pNode->port.node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT
     1173                                                | CODEC_F00_0C_CAP_PRESENSE_DETECT;
     1174
    10501175            if (!pThis->fInReset)
    10511176                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
    10521177                                                          CODEC_F1C_LOCATION_REAR,
    1053                                                           CODEC_F1C_DEVICE_LINE_OUT,
     1178                                                          CODEC_F1C_DEVICE_LINE_IN,
    10541179                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    10551180                                                          CODEC_F1C_COLOR_BLUE,
    1056                                                           0x0, 0x4, 0x0);//0x01013040;  /* Line Out */
     1181                                                          CODEC_F1C_MISC_NONE,
     1182                                                          CODEC_F1C_ASSOCIATION_GROUP_15, 0xE /* Seq */);
    10571183            break;
    1058         case 0xF:
    1059             pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0x0)
    1060                                          | CODEC_F00_09_CAP_CONNECTION_LIST
    1061                                          | CODEC_F00_09_CAP_UNSOL
    1062                                          | CODEC_F00_09_CAP_OUT_AMP_PRESENT
    1063                                          | CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(8)|RT_BIT(7)|RT_BIT(2)|RT_BIT(0);
    1064             pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT
    1065                                            | CODEC_F00_0C_CAP_OUTPUT
    1066                                            | CODEC_F00_0C_CAP_PRESENSE_DETECT
    1067                                            /* | CODEC_F00_0C_CAP_TRIGGER_REQUIRED
    1068                                            | CODEC_F00_0C_CAP_IMPENDANCE_SENSE */;//0x37;
    1069             pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//0x1;
     1184        }
     1185
     1186        case STAC9220_NID_PIN_F:
     1187        {
     1188            pNode->port.u32F07_param = CODEC_F07_IN_ENABLE | CODEC_F07_OUT_ENABLE;
    10701189            pNode->port.u32F08_param = 0;
    1071             pNode->port.u32F07_param = CODEC_F07_OUT_ENABLE
    1072                                      | CODEC_F07_IN_ENABLE;
     1190            pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(true /* fPresent */, CODEC_F09_ANALOG_NA);
     1191
     1192            pNode->port.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
     1193                                                | CODEC_F00_09_CAP_CONNECTION_LIST
     1194                                                | CODEC_F00_09_CAP_UNSOL
     1195                                                | CODEC_F00_09_CAP_OUT_AMP_PRESENT
     1196                                                | CODEC_F00_09_CAP_STEREO;
     1197            pNode->port.node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT
     1198                                                | CODEC_F00_0C_CAP_OUTPUT;
     1199
     1200            /* Connection list entry 0: Goes to DAC3. */
     1201            pNode->port.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */);
     1202            pNode->port.node.au32F02_param[0x0] = STAC9220_NID_DAC3;
     1203
    10731204            if (!pThis->fInReset)
    10741205                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    10771208                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    10781209                                                          CODEC_F1C_COLOR_ORANGE,
    1079                                                           0x0, 0x1, 0x2);//RT_MAKE_U32_FROM_U8(0x12, 0x60, 0x11, 0x01);
    1080             pNode->node.au32F02_param[0] = 0x5;
    1081             pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(0, CODEC_F09_ANALOG_NA);//0x7fffffff;
     1210                                                          CODEC_F1C_MISC_NONE,
     1211                                                          CODEC_F1C_ASSOCIATION_GROUP_1, 0x0 /* Seq */);
    10821212            break;
    1083         case 0x10:
    1084             pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0x0)
    1085                                          | CODEC_F00_09_CAP_DIGITAL
    1086                                          | CODEC_F00_09_CAP_CONNECTION_LIST
    1087                                          | CODEC_F00_09_CAP_LSB;//(4<<20)|RT_BIT(9)|RT_BIT(8)|RT_BIT(0);
    1088             pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_OUTPUT;//RT_BIT(4);
    1089             pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 0x3);
    1090             pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x08, 0x17, 0x19, 0);
     1213        }
     1214
     1215        case STAC9220_NID_PIN_SPDIF_OUT: /* Rear SPDIF Out. */
     1216        {
     1217            pNode->digout.u32F07_param = CODEC_F07_OUT_ENABLE;
     1218            pNode->digout.u32F09_param = 0;
     1219
     1220            pNode->digout.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
     1221                                                  | CODEC_F00_09_CAP_DIGITAL
     1222                                                  | CODEC_F00_09_CAP_CONNECTION_LIST
     1223                                                  | CODEC_F00_09_CAP_STEREO;
     1224            pNode->digout.node.au32F00_param[0xC] = CODEC_F00_0C_CAP_OUTPUT
     1225                                                  | CODEC_F00_0C_CAP_PRESENSE_DETECT;
     1226
     1227            /* Connection list entries. */
     1228            pNode->digout.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 3 /* Entries */);
     1229            pNode->digout.node.au32F02_param[0x0] = RT_MAKE_U32_FROM_U8(STAC9220_NID_SPDIF_OUT,
     1230                                                                        STAC9220_NID_AMP_ADC0, STAC9221_NID_ADAT_OUT, 0);
    10911231            if (!pThis->fInReset)
    10921232                pNode->digout.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    10951235                                                            CODEC_F1C_CONNECTION_TYPE_DIN,
    10961236                                                            CODEC_F1C_COLOR_BLACK,
    1097                                                             0x0, 0x3, 0x0);//RT_MAKE_U32_FROM_U8(0x30, 0x10, 0x45, 0x01);
     1237                                                            CODEC_F1C_MISC_NONE,
     1238                                                            CODEC_F1C_ASSOCIATION_GROUP_2, 0x0 /* Seq */);
    10981239            break;
    1099         case 0x11:
    1100             pNode->node.au32F00_param[9] = (4 << 20) | (3 << 16) | RT_BIT(10) | RT_BIT(9) | RT_BIT(7) | RT_BIT(0);
    1101             pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_EAPD
    1102                                            | CODEC_F00_0C_CAP_INPUT
    1103                                            | CODEC_F00_0C_CAP_PRESENSE_DETECT;//RT_BIT(16)| RT_BIT(5)|RT_BIT(2);
    1104             pNode->digin.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3 -> D3 */
    1105             pNode->digin.u32F07_param = 0;
     1240        }
     1241
     1242        case STAC9220_NID_PIN_SPDIF_IN:
     1243        {
     1244            pNode->digin.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3); /* PS-Act: D3 -> D3 */
     1245            pNode->digin.u32F07_param = CODEC_F07_IN_ENABLE;
    11061246            pNode->digin.u32F08_param = 0;
    11071247            pNode->digin.u32F09_param = CODEC_MAKE_F09_DIGITAL(0, 0);
    11081248            pNode->digin.u32F0c_param = 0;
     1249
     1250            pNode->digin.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 3, 0)
     1251                                                 | CODEC_F00_09_CAP_POWER_CTRL
     1252                                                 | CODEC_F00_09_CAP_DIGITAL
     1253                                                 | CODEC_F00_09_CAP_UNSOL
     1254                                                 | CODEC_F00_09_CAP_STEREO;
     1255
     1256            pNode->digin.node.au32F00_param[0xC] = CODEC_F00_0C_CAP_EAPD
     1257                                                 | CODEC_F00_0C_CAP_INPUT
     1258                                                 | CODEC_F00_0C_CAP_PRESENSE_DETECT;
    11091259            if (!pThis->fInReset)
    11101260                pNode->digin.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    11131263                                                           CODEC_F1C_CONNECTION_TYPE_OTHER_DIGITAL,
    11141264                                                           CODEC_F1C_COLOR_BLACK,
    1115                                                            0x0, 0x6, 0x0);//(0x1 << 24) | (0xc5 << 16) | (0x10 << 8) | 0x60;
     1265                                                           CODEC_F1C_MISC_NONE,
     1266                                                           CODEC_F1C_ASSOCIATION_GROUP_3, 0x0 /* Seq */);
    11161267            break;
    1117         case 0x12:
    1118             pNode->adcmux.u32F01_param = 0;
     1268        }
     1269
     1270        case STAC9220_NID_ADC0_MUX:
     1271        {
     1272            pNode->adcmux.u32F01_param = 0; /* Connection select control index (STAC9220_NID_PIN_E). */
    11191273            goto adcmux_init;
    1120         case 0x13:
    1121             pNode->adcmux.u32F01_param = 1;
    1122             adcmux_init:
    1123             pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0x0, 0)
    1124                                          | CODEC_F00_09_CAP_CONNECTION_LIST
    1125                                          | CODEC_F00_09_CAP_AMP_FMT_OVERRIDE
    1126                                          | CODEC_F00_09_CAP_OUT_AMP_PRESENT
    1127                                          | CODEC_F00_09_CAP_LSB;//(3<<20)|RT_BIT(8)|RT_BIT(3)|RT_BIT(2)|RT_BIT(0);
    1128             pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x7);
    1129             pNode->node.au32F00_param[0x12] = (0x27 << 16)|(0x4 << 8);
    1130             /* STAC 9220 v10 6.21-22.{4,5} both(left and right) out amplefiers inited with 0*/
    1131             memset(pNode->adcmux.B_params, 0, AMPLIFIER_SIZE);
    1132             pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0xe, 0x15, 0xf, 0xb);
    1133             pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0xc, 0xd, 0xa, 0x0);
     1274        }
     1275
     1276        case STAC9220_NID_ADC1_MUX:
     1277        {
     1278            pNode->adcmux.u32F01_param = 1; /* Connection select control index (STAC9220_NID_PIN_CD). */
     1279
     1280            /* Fall through is intentional. */
     1281        adcmux_init:
     1282
     1283            pNode->adcmux.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0, 0)
     1284                                                  | CODEC_F00_09_CAP_CONNECTION_LIST
     1285                                                  | CODEC_F00_09_CAP_AMP_FMT_OVERRIDE
     1286                                                  | CODEC_F00_09_CAP_OUT_AMP_PRESENT
     1287                                                  | CODEC_F00_09_CAP_STEREO;
     1288
     1289            pNode->adcmux.node.au32F00_param[0xD] = CODEC_MAKE_F00_0D(0, 27, 4, 0);
     1290
     1291            /* Connection list entries. */
     1292            pNode->adcmux.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 7 /* Entries */);
     1293            pNode->adcmux.node.au32F02_param[0x0] = RT_MAKE_U32_FROM_U8(STAC9220_NID_PIN_E,
     1294                                                                        STAC9220_NID_PIN_CD,
     1295                                                                        STAC9220_NID_PIN_F,
     1296                                                                        STAC9220_NID_PIN_B);
     1297            pNode->adcmux.node.au32F02_param[0x4] = RT_MAKE_U32_FROM_U8(STAC9220_NID_PIN_C,
     1298                                                                        STAC9220_NID_PIN_HEADPHONE1,
     1299                                                                        STAC9220_NID_PIN_HEADPHONE0,
     1300                                                                        0x0 /* Unused */);
     1301
     1302            /* STAC 9220 v10 6.21-22.{4,5} both(left and right) out amplifiers initialized with 0. */
     1303            RT_BZERO(pNode->adcmux.B_params, AMPLIFIER_SIZE);
    11341304            break;
    1135         case 0x14:
    1136             pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_BEEP_GEN, 0, 0)
    1137                                          | CODEC_F00_09_CAP_AMP_FMT_OVERRIDE
    1138                                          | CODEC_F00_09_CAP_OUT_AMP_PRESENT;//(7 << 20) | RT_BIT(3) | RT_BIT(2);
    1139             pNode->node.au32F00_param[0x12] = (0x17 << 16)|(0x3 << 8)| 0x3;
     1305        }
     1306
     1307        case STAC9220_NID_PCBEEP:
     1308        {
    11401309            pNode->pcbeep.u32F0a_param = 0;
    1141             memset(pNode->pcbeep.B_params, 0, AMPLIFIER_SIZE);
     1310
     1311            pNode->pcbeep.node.au32F00_param[0x9]  = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_BEEP_GEN, 0, 0)
     1312                                                   | CODEC_F00_09_CAP_AMP_FMT_OVERRIDE
     1313                                                   | CODEC_F00_09_CAP_OUT_AMP_PRESENT;
     1314            pNode->pcbeep.node.au32F00_param[0xD]  = CODEC_MAKE_F00_0D(0, 17, 3, 3);
     1315
     1316            RT_BZERO(pNode->pcbeep.B_params, AMPLIFIER_SIZE);
    11421317            break;
    1143         case 0x15:
    1144             pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
    1145                                            | CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(0);
    1146             pNode->node.au32F00_param[0xc] = CODEC_F00_0C_CAP_INPUT;//RT_BIT(5);
     1318        }
     1319
     1320        case STAC9220_NID_PIN_CD:
     1321        {
     1322            pNode->cdnode.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
     1323                                                  | CODEC_F00_09_CAP_STEREO;
     1324            pNode->cdnode.node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT;
     1325
    11471326            if (!pThis->fInReset)
    11481327                pNode->cdnode.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_FIXED,
     
    11511330                                                            CODEC_F1C_CONNECTION_TYPE_ATAPI,
    11521331                                                            CODEC_F1C_COLOR_UNKNOWN,
    1153                                                             0x0, 0x7, 0x0);//RT_MAKE_U32_FROM_U8(0x70, 0x0, 0x33, 0x90);
     1332                                                            CODEC_F1C_MISC_NONE,
     1333                                                            CODEC_F1C_ASSOCIATION_GROUP_15, 0xF /* Seq */);
    11541334            break;
    1155         case 0x16:
    1156             pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VOLUME_KNOB, 0x0, 0x0);//(0x6 << 20);
    1157             pNode->node.au32F00_param[0x13] = RT_BIT(7)| 0x7F;
    1158             pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x4);
    1159             pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x2, 0x3, 0x4, 0x5);
     1335        }
     1336
     1337        case STAC9220_NID_VOL_KNOB:
     1338        {
    11601339            pNode->volumeKnob.u32F08_param = 0;
    11611340            pNode->volumeKnob.u32F0f_param = 0x7f;
     1341
     1342            pNode->volumeKnob.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VOLUME_KNOB, 0, 0);
     1343            pNode->volumeKnob.node.au32F00_param[0xD] = RT_BIT(7) | 0x7F;
     1344
     1345            /* Connection list entries. */
     1346            pNode->volumeKnob.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 4 /* Entries */);
     1347            pNode->volumeKnob.node.au32F02_param[0x0] = RT_MAKE_U32_FROM_U8(STAC9220_NID_DAC0,
     1348                                                                            STAC9220_NID_DAC1,
     1349                                                                            STAC9220_NID_DAC2,
     1350                                                                            STAC9220_NID_DAC3);
    11621351            break;
    1163         case 0x17:
    1164             pNode->node.au32F02_param[0] = 0x12;
     1352        }
     1353
     1354        case STAC9220_NID_AMP_ADC0:
     1355        {
     1356            pNode->adcvol.node.au32F02_param[0] = STAC9220_NID_ADC0_MUX;
    11651357            goto adcvol_init;
    1166         case 0x18:
    1167             pNode->node.au32F02_param[0] = 0x13;
     1358        }
     1359
     1360        case STAC9220_NID_AMP_ADC1:
     1361        {
     1362            pNode->adcvol.node.au32F02_param[0] = STAC9220_NID_ADC1_MUX;
     1363
     1364            /* Fall through is intentional. */
    11681365        adcvol_init:
    1169             memset(pNode->adcvol.B_params, 0, AMPLIFIER_SIZE);
    1170 
    1171             pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0, 0)
    1172                                            | CODEC_F00_09_CAP_L_R_SWAP
    1173                                            | CODEC_F00_09_CAP_CONNECTION_LIST
    1174                                            | CODEC_F00_09_CAP_IN_AMP_PRESENT
    1175                                            | CODEC_F00_09_CAP_LSB;//(0x3 << 20)|RT_BIT(11)|RT_BIT(8)|RT_BIT(1)|RT_BIT(0);
    1176             pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x1);
    1177             AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_LEFT, 0) = RT_BIT(7);
     1366
     1367            pNode->adcvol.u32F0c_param = 0;
     1368
     1369            pNode->adcvol.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0, 0)
     1370                                                  | CODEC_F00_09_CAP_L_R_SWAP
     1371                                                  | CODEC_F00_09_CAP_CONNECTION_LIST
     1372                                                  | CODEC_F00_09_CAP_IN_AMP_PRESENT
     1373                                                  | CODEC_F00_09_CAP_STEREO;
     1374
     1375
     1376            pNode->adcvol.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */);
     1377
     1378            RT_BZERO(pNode->adcvol.B_params, AMPLIFIER_SIZE);
     1379            AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_LEFT,  0) = RT_BIT(7);
    11781380            AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_RIGHT, 0) = RT_BIT(7);
    1179             pNode->adcvol.u32F0c_param = 0;
    11801381            break;
    1181         case 0x19:
    1182             pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VENDOR_DEFINED, 0x3, 0)
     1382        }
     1383
     1384        /*
     1385         * STAC9221 nodes.
     1386         */
     1387
     1388        case STAC9221_NID_ADAT_OUT:
     1389        {
     1390            pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VENDOR_DEFINED, 3, 0)
    11831391                                           | CODEC_F00_09_CAP_DIGITAL
    1184                                            | CODEC_F00_09_CAP_LSB;//(0xF << 20)|(0x3 << 16)|RT_BIT(9)|RT_BIT(0);
     1392                                           | CODEC_F00_09_CAP_STEREO;
    11851393            break;
    1186         case 0x1A:
    1187             pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0x3, 0)
     1394        }
     1395
     1396        case STAC9221_NID_I2S_OUT:
     1397        {
     1398            pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 3, 0)
    11881399                                           | CODEC_F00_09_CAP_DIGITAL
    1189                                            | CODEC_F00_09_CAP_LSB;//(0x3 << 16)|RT_BIT(9)|RT_BIT(0);
     1400                                           | CODEC_F00_09_CAP_STEREO;
    11901401            break;
    1191         case 0x1B:
     1402        }
     1403
     1404        case STAC9221_NID_PIN_I2S_OUT:
     1405        {
    11921406            pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
    11931407                                           | CODEC_F00_09_CAP_DIGITAL
    11941408                                           | CODEC_F00_09_CAP_CONNECTION_LIST
    1195                                            | CODEC_F00_09_CAP_LSB;//(0x4 << 20)|RT_BIT(9)|RT_BIT(8)|RT_BIT(0);
    1196             pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 0x1);
    1197             pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_OUTPUT;//0x10;
    1198             pNode->node.au32F02_param[0] = 0x1a;
    1199             pNode->reserved.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_NO_PHYS,
    1200                                                           CODEC_F1C_LOCATION_NA,
    1201                                                           CODEC_F1C_DEVICE_LINE_OUT,
    1202                                                           CODEC_F1C_CONNECTION_TYPE_UNKNOWN,
    1203                                                           CODEC_F1C_COLOR_UNKNOWN,
    1204                                                           0x0, 0x0, 0xf);//0x4000000f;
     1409                                           | CODEC_F00_09_CAP_STEREO;
     1410            pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_OUTPUT;
     1411
     1412            /* Connection list entries. */
     1413            pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */);
     1414            pNode->node.au32F02_param[0]   = STAC9221_NID_I2S_OUT;
     1415
     1416            if (!pThis->fInReset)
     1417                pNode->reserved.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_NO_PHYS,
     1418                                                              CODEC_F1C_LOCATION_NA,
     1419                                                              CODEC_F1C_DEVICE_LINE_OUT,
     1420                                                              CODEC_F1C_CONNECTION_TYPE_UNKNOWN,
     1421                                                              CODEC_F1C_COLOR_UNKNOWN,
     1422                                                              CODEC_F1C_MISC_NONE,
     1423                                                              CODEC_F1C_ASSOCIATION_GROUP_15, 0xB /* Seq */);
    12051424            break;
     1425        }
     1426
    12061427        default:
    1207         break;
    1208     }
     1428            AssertMsgFailed(("Node %RU8 not implemented\n", uNID));
     1429            break;
     1430    }
     1431
    12091432    return VINF_SUCCESS;
    12101433}
     
    12131436static int stac9220Construct(PHDACODEC pThis)
    12141437{
    1215     unconst(pThis->cTotalNodes) = 0x1C;
     1438    unconst(pThis->cTotalNodes) = STAC9221_NUM_NODES;
     1439
    12161440    pThis->pfnCodecNodeReset = stac9220ResetNode;
    1217     pThis->pfnDbgListNodes   = stac9220DbgNodes;
    1218     pThis->u16VendorId = 0x8384;
    1219     pThis->u16DeviceId = 0x7680;
    1220     pThis->u8BSKU = 0x76;
     1441
     1442    pThis->u16VendorId  = 0x8384; /* SigmaTel */
     1443    /*
     1444     * Note: The Linux kernel uses "patch_stac922x" for the fixups,
     1445     *       which in turn uses "ref922x_pin_configs" for the configuration
     1446     *       defaults tweaking in sound/pci/hda/patch_sigmatel.c.
     1447     */
     1448    pThis->u16DeviceId  = 0x7680; /* STAC9221 A1 */
     1449    pThis->u8BSKU       = 0x76;
    12211450    pThis->u8AssemblyId = 0x80;
     1451
    12221452    pThis->paNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pThis->cTotalNodes);
    12231453    if (!pThis->paNodes)
    12241454        return VERR_NO_MEMORY;
     1455
    12251456    pThis->fInReset = false;
     1457
    12261458#define STAC9220WIDGET(type) pThis->au8##type##s = g_abStac9220##type##s
    12271459    STAC9220WIDGET(Port);
     
    12391471    STAC9220WIDGET(Reserved);
    12401472#undef STAC9220WIDGET
    1241     unconst(pThis->u8AdcVolsLineIn) = 0x17;
    1242     unconst(pThis->u8DacLineOut) = 0x3;
     1473
     1474    unconst(pThis->u8AdcVolsLineIn) = STAC9220_NID_AMP_ADC0;
     1475    unconst(pThis->u8DacLineOut)    = STAC9220_NID_DAC1;
    12431476
    12441477    return VINF_SUCCESS;
     
    12901523 * Misc helpers.
    12911524 */
    1292 static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL mt)
    1293 {
    1294     uint32_t dir = AMPLIFIER_OUT;
    1295     ENMSOUNDSOURCE enmSrc;
    1296     switch (mt)
    1297     {
    1298         case PDMAUDIOMIXERCTL_PCM:
    1299             enmSrc = PO_INDEX;
    1300             dir = AMPLIFIER_OUT;
     1525static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL enmMixerCtl)
     1526{
     1527    uint8_t iDir;
     1528    switch (enmMixerCtl)
     1529    {
     1530        case PDMAUDIOMIXERCTL_VOLUME:
     1531        case PDMAUDIOMIXERCTL_FRONT:
     1532            iDir = AMPLIFIER_OUT;
    13011533            break;
    13021534        case PDMAUDIOMIXERCTL_LINE_IN:
    1303             enmSrc = PI_INDEX;
    1304             dir = AMPLIFIER_IN;
     1535        case PDMAUDIOMIXERCTL_MIC_IN:
     1536            iDir = AMPLIFIER_IN;
    13051537            break;
    13061538        default:
    1307             AssertMsgFailedReturn(("Invalid mixer control %ld\n", mt), VERR_INVALID_PARAMETER);
     1539            AssertMsgFailedReturn(("Invalid mixer control %ld\n", enmMixerCtl), VERR_INVALID_PARAMETER);
    13081540            break;
    13091541    }
    13101542
    1311     int mute = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & RT_BIT(7);
    1312     mute |= AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & RT_BIT(7);
    1313     mute >>=7;
    1314     mute &= 0x1;
    1315     uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & 0x7f;
    1316     uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & 0x7f;
    1317 
    1318     /* The STAC9220 volume controls have 0 to -96dB attenuation range in 128 steps.
     1543    int iMute;
     1544    iMute  = AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_LEFT,  0) & RT_BIT(7);
     1545    iMute |= AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_RIGHT, 0) & RT_BIT(7);
     1546    iMute >>=7;
     1547    iMute &= 0x1;
     1548
     1549    uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_LEFT,  0) & 0x7f;
     1550    uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_RIGHT, 0) & 0x7f;
     1551
     1552    /*
     1553     * The STAC9220 volume controls have 0 to -96dB attenuation range in 128 steps.
    13191554     * We have 0 to -96dB range in 256 steps. HDA volume setting of 127 must map
    13201555     * to 255 internally (0dB), while HDA volume setting of 0 (-96dB) should map
     
    13241559    rVol = (rVol + 1) * (2 * 255) / 256;
    13251560
    1326     return pThis->pfnSetVolume(pThis->pHDAState, enmSrc, RT_BOOL(mute), lVol, rVol);
     1561    PDMAUDIOVOLUME Vol = { RT_BOOL(iMute), lVol, rVol };
     1562    return pThis->pfnMixerSetVolume(pThis->pHDAState, enmMixerCtl, &Vol);
    13271563}
    13281564
     
    14261662                            u8Index);
    14271663    else
    1428         LogRel2(("HDA: Unhandled get amplifier command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
     1664        LogRel2(("HDA: Warning: Unhandled get amplifier command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
    14291665
    14301666    return VINF_SUCCESS;
     
    14541690        pAmplifier = &pNode->adc.B_params;
    14551691    else
    1456         LogRel2(("HDA: Unhandled set amplifier command: 0x%x (Payload=%RU16, NID=0x%x [%RU8])\n",
     1692        LogRel2(("HDA: Warning: Unhandled set amplifier command: 0x%x (Payload=%RU16, NID=0x%x [%RU8])\n",
    14571693                 cmd, CODEC_VERB_PAYLOAD16(cmd), CODEC_NID(cmd)));
    14581694
     
    14881724
    14891725        if (CODEC_NID(cmd) == pThis->u8DacLineOut)
    1490             hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_PCM);
     1726            hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_FRONT);
    14911727    }
    14921728
     
    15311767        *pResp = pThis->paNodes[CODEC_NID(cmd)].adcvol.u32F01_param;
    15321768    else
    1533         LogRel2(("HDA: Unhandled get pin control command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
     1769        LogRel2(("HDA: Warning: Unhandled get connection select control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    15341770
    15351771    return VINF_SUCCESS;
     
    15561792        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adcvol.u32F01_param;
    15571793    else
    1558         LogRel2(("HDA: Unhandled set connection select control command: 0x%x (Payload=0x%x, NID=0x%x [%RU8])\n",
    1559                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     1794        LogRel2(("HDA: Warning: Unhandled set connection select control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    15601795
    15611796    if (pu32Reg)
     
    15861821        *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F07_param;
    15871822    else
    1588         LogRel2(("HDA: Unhandled get pin control command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
     1823        LogRel2(("HDA: Warning: Unhandled get pin control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    15891824
    15901825    return VINF_SUCCESS;
     
    16141849        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F07_param;
    16151850    else
    1616         LogRel2(("HDA: Unhandled set pin control command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n",
    1617                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     1851        LogRel2(("HDA: Warning: Unhandled set pin control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    16181852
    16191853    if (pu32Reg)
     
    16351869    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    16361870        *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param;
    1637     else if ((cmd) == 1 /* AFG */)
     1871    else if ((cmd) == STAC9220_NID_AFG)
    16381872        *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F08_param;
    16391873    else if (hdaCodecIsVolKnobNode(pThis, CODEC_NID(cmd)))
     
    16441878        *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param;
    16451879    else
    1646         LogRel2(("HDA: Unhandled get unsolicited enabled command: 0x%x (NID=0x%x [%RU8])\n",
    1647                  cmd, CODEC_NID(cmd)));
     1880        LogRel2(("HDA: Warning: Unhandled get unsolicited enabled command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    16481881
    16491882    return VINF_SUCCESS;
     
    16631896    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    16641897        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param;
    1665     else if (CODEC_NID(cmd) == 1 /* AFG */)
     1898    else if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    16661899        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F08_param;
    16671900    else if (hdaCodecIsVolKnobNode(pThis, CODEC_NID(cmd)))
     
    16721905        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digout.u32F08_param;
    16731906    else
    1674         LogRel2(("HDA: Unhandled set unsolicited enabled command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n",
    1675                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     1907        LogRel2(("HDA: Warning: Unhandled set unsolicited enabled command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    16761908
    16771909    if (pu32Reg)
     
    16941926        *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F09_param;
    16951927    else
    1696         LogRel2(("HDA: Unhandled get pin sense command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
     1928        LogRel2(("HDA: Warning: Unhandled get pin sense command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    16971929
    16981930    return VINF_SUCCESS;
     
    17131945        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F09_param;
    17141946    else
    1715         LogRel2(("HDA: Unhandled set pin sense command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n",
    1716                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     1947        LogRel2(("HDA: Warning: Unhandled set pin sense command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    17171948
    17181949    if (pu32Reg)
     
    18182049        return VINF_SUCCESS;
    18192050    }
    1820     if (CODEC_NID(cmd) == 1 /* AFG */)
     2051    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    18212052        *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F20_param;
    18222053    else
     
    18352066    }
    18362067    uint32_t *pu32Reg;
    1837     if (CODEC_NID(cmd) == 0x1 /* AFG */)
     2068    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    18382069        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F20_param;
    18392070    else
     
    18742105{
    18752106    Assert(CODEC_CAD(cmd) == pThis->id);
    1876     Assert(CODEC_NID(cmd) == 1 /* AFG */);
    1877     if (   CODEC_NID(cmd) == 1 /* AFG */
     2107    Assert(CODEC_NID(cmd) == STAC9220_NID_AFG);
     2108    if (   CODEC_NID(cmd) == STAC9220_NID_AFG
    18782109        && pThis->pfnCodecNodeReset)
    18792110    {
     
    19002131    *pResp = 0;
    19012132
    1902     if (CODEC_NID(cmd) == 1 /* AFG */)
     2133    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    19032134        *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F05_param;
    19042135    else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
     
    19062137    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    19072138        *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F05_param;
     2139    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
     2140        *pResp = pThis->paNodes[CODEC_NID(cmd)].digout.u32F05_param;
    19082141    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    19092142        *pResp = pThis->paNodes[CODEC_NID(cmd)].adc.u32F05_param;
     
    19152148        *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F05_param;
    19162149    else
    1917         LogRel2(("HDA: Unhandled get power state command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
    1918 
    1919     return VINF_SUCCESS;
    1920 }
    1921 
    1922 DECLINLINE(void) codecPropogatePowerState(uint32_t *pu32F05_param)
    1923 {
    1924     AssertPtr(pu32F05_param);
    1925     if (!pu32F05_param)
    1926         return;
    1927 
    1928     bool fReset  = CODEC_F05_IS_RESET(*pu32F05_param);
    1929     bool fStopOk = CODEC_F05_IS_STOPOK(*pu32F05_param);
    1930     uint8_t u8SetPowerState = CODEC_F05_SET(*pu32F05_param);
    1931 
    1932     *pu32F05_param = CODEC_MAKE_F05(fReset, fStopOk, 0, u8SetPowerState, u8SetPowerState);
     2150        LogRel2(("HDA: Warning: Unhandled get power state command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
     2151
     2152    LogFunc(("NID=0x%x, fReset=%RTbool, fStopOk=%RTbool, Set=%RU8, Act=%RU8\n",
     2153             CODEC_NID(cmd), CODEC_F05_IS_RESET(*pResp), CODEC_F05_IS_STOPOK(*pResp), CODEC_F05_SET(*pResp), CODEC_F05_ACT(*pResp)));
     2154    return VINF_SUCCESS;
    19332155}
    19342156
     
    19422164
    19432165    uint32_t *pu32Reg = NULL;
    1944     if (CODEC_NID(cmd) == 1 /* AFG */)
     2166    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    19452167        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F05_param;
    19462168    else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
     
    19482170    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    19492171        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F05_param;
     2172    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
     2173        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digout.u32F05_param;
    19502174    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    19512175        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adc.u32F05_param;
     
    19572181        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F05_param;
    19582182    else
    1959         LogRel2(("HDA: Unhandled set power state command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n",
    1960                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     2183        LogRel2(("HDA: Warning: Unhandled set power state command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    19612184
    19622185    if (!pu32Reg)
    19632186        return VINF_SUCCESS;
    19642187
    1965     bool fReset = CODEC_F05_IS_RESET(*pu32Reg);
    1966     bool fStopOk = CODEC_F05_IS_STOPOK(*pu32Reg);
    1967 
    1968     if (CODEC_NID(cmd) != 1 /* AFG */)
    1969     {
    1970         /*
    1971          * We shouldn't propogate actual power state, which actual for AFG
    1972          */
     2188    bool    fReset  = CODEC_F05_IS_RESET (*pu32Reg);
     2189    bool    fStopOk = CODEC_F05_IS_STOPOK(*pu32Reg);
     2190    uint8_t uPwrAct = CODEC_F05_ACT      (*pu32Reg);
     2191    uint8_t uPwrSet = CODEC_F05_SET      (*pu32Reg);
     2192    uint8_t uPwrCmd = CODEC_F05_SET      (cmd);
     2193
     2194    LogFunc(("[NID=0x%x] Cmd=D%RU8, Act=D%RU8, Set=D%RU8 (AFG Act=D%RU8, Set=D%RU8)\n",
     2195            CODEC_NID(cmd), uPwrCmd, uPwrAct, uPwrSet,
     2196            CODEC_F05_ACT(pThis->paNodes[STAC9220_NID_AFG].afg.u32F05_param),
     2197            CODEC_F05_SET(pThis->paNodes[STAC9220_NID_AFG].afg.u32F05_param)));
     2198
     2199    const uint8_t uAFGPwrSet = CODEC_F05_SET(pThis->paNodes[STAC9220_NID_AFG].afg.u32F05_param);
     2200
     2201    /* If this is the AFG node, PS-Act always matches the PS-Set power state.*/
     2202    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
     2203    {
     2204        *pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0, uPwrCmd /* PS-Act */, uPwrCmd /* PS-Set */);
     2205
     2206        /* Propagate to all other nodes under this AFG. */
     2207        LogFunc(("Propagating Set=D%RU8 to all nodes ...\n", uPwrCmd));
     2208
     2209#define PROPAGATE_PWR_STATE(_aList, _aMember) \
     2210        { \
     2211            const uint8_t *pu8NodeIndex = &_aList[0]; \
     2212            while (*(pu8NodeIndex++)) \
     2213            { \
     2214                pThis->paNodes[*pu8NodeIndex]._aMember.u32F05_param = \
     2215                    CODEC_MAKE_F05(fReset, fStopOk, 0, RT_MIN((uAFGPwrSet + 1), CODEC_F05_D3), \
     2216                                   uPwrCmd /* Always update PS-Set with command power state just received. */); \
     2217                LogFunc(("\t[NID=0x%x]: Act=D%RU8, Set=D%RU8\n", *pu8NodeIndex, \
     2218                         CODEC_F05_ACT(pThis->paNodes[*pu8NodeIndex]._aMember.u32F05_param), \
     2219                         CODEC_F05_SET(pThis->paNodes[*pu8NodeIndex]._aMember.u32F05_param))); \
     2220            } \
     2221        }
     2222
     2223        PROPAGATE_PWR_STATE(pThis->au8Dacs,       dac);
     2224        PROPAGATE_PWR_STATE(pThis->au8Adcs,       adc);
     2225        PROPAGATE_PWR_STATE(pThis->au8DigInPins,  digin);
     2226        PROPAGATE_PWR_STATE(pThis->au8DigOutPins, digout);
     2227        PROPAGATE_PWR_STATE(pThis->au8SpdifIns,   spdifin);
     2228        PROPAGATE_PWR_STATE(pThis->au8SpdifOuts,  spdifout);
     2229        PROPAGATE_PWR_STATE(pThis->au8Reserveds,  reserved);
     2230
     2231#undef PROPAGATE_PWR_STATE
     2232    }
     2233    /*
     2234     * If this node is a reqular node (not the AFG one), adpopt PS-Set of the AFG node
     2235     * as PS-Set of this node. PS-Act always is one level under PS-Set here.
     2236     */
     2237    else
     2238    {
    19732239        *pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0,
    1974                                   CODEC_F05_ACT(pThis->paNodes[1].afg.u32F05_param),
    1975                                   CODEC_F05_SET(cmd));
    1976     }
    1977 
    1978     /* Propagate next power state only if AFG is on or verb modifies AFG power state */
    1979     if (   CODEC_NID(cmd) == 1 /* AFG */
    1980         || !CODEC_F05_ACT(pThis->paNodes[1].afg.u32F05_param))
    1981     {
    1982         *pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0, CODEC_F05_SET(cmd), CODEC_F05_SET(cmd));
    1983         if (   CODEC_NID(cmd) == 1 /* AFG */
    1984             && (CODEC_F05_SET(cmd)) == CODEC_F05_D0)
    1985         {
    1986             /* now we're powered on AFG and may propogate power states on nodes */
    1987             const uint8_t *pu8NodeIndex = &pThis->au8Dacs[0];
    1988             while (*(++pu8NodeIndex))
    1989                 codecPropogatePowerState(&pThis->paNodes[*pu8NodeIndex].dac.u32F05_param);
    1990 
    1991             pu8NodeIndex = &pThis->au8Adcs[0];
    1992             while (*(++pu8NodeIndex))
    1993                 codecPropogatePowerState(&pThis->paNodes[*pu8NodeIndex].adc.u32F05_param);
    1994 
    1995             pu8NodeIndex = &pThis->au8DigInPins[0];
    1996             while (*(++pu8NodeIndex))
    1997                 codecPropogatePowerState(&pThis->paNodes[*pu8NodeIndex].digin.u32F05_param);
    1998         }
    1999     }
     2240                                  RT_MIN((uAFGPwrSet + 1), CODEC_F05_D3),
     2241                                  uPwrCmd /* Always update PS-Set with command power state just received. */);
     2242    }
     2243
     2244    if (pu32Reg)
     2245        hdaCodecSetRegisterU8(pu32Reg, cmd, 0);
     2246
     2247    LogFunc(("[NID=0x%x] fReset=%RTbool, fStopOk=%RTbool, Act=D%RU8, Set=D%RU8\n",
     2248             CODEC_NID(cmd), fReset, fStopOk, CODEC_F05_ACT(*pu32Reg), CODEC_F05_SET(*pu32Reg)));
     2249
    20002250    return VINF_SUCCESS;
    20012251}
     
    20162266    else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    20172267        *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
    2018     else if (CODEC_NID(cmd) == 0x1A)
     2268    else if (CODEC_NID(cmd) == STAC9221_NID_I2S_OUT)
    20192269        *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F06_param;
    20202270    else
    2021         LogRel2(("HDA: Unhandled get stream ID command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
     2271        LogRel2(("HDA: Warning: Unhandled get stream ID command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
     2272
     2273    LogFlowFunc(("[NID0x%x] Stream ID is 0x%x\n",
     2274                 CODEC_NID(cmd), CODEC_F00_06_GET_STREAM_ID(*pResp)));
    20222275
    20232276    return VINF_SUCCESS;
     
    20442297        pu32Addr = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F06_param;
    20452298    else
    2046         LogRel2(("HDA: Unhandled set stream ID command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n",
    2047                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     2299        LogRel2(("HDA: Warning: Unhandled set stream ID command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
     2300
     2301    LogFlowFunc(("[NID0x%x] Setting new stream ID to 0x%x\n",
     2302                 CODEC_NID(cmd), CODEC_F00_06_GET_STREAM_ID(cmd)));
    20482303
    20492304    if (pu32Addr)
     
    20532308}
    20542309
    2055 /* F06 */
     2310/* A0 */
    20562311static DECLCALLBACK(int) vrbProcGetConverterFormat(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    20572312{
     
    20692324    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    20702325        *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifin.u32A_param;
     2326    else if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
     2327        *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32A_param;
    20712328    else
    2072         LogRel2(("HDA: Unhandled get power state command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
    2073 
    2074     return VINF_SUCCESS;
    2075 }
    2076 
     2329        LogRel2(("HDA: Warning: Unhandled get converter format command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
     2330
     2331    return VINF_SUCCESS;
     2332}
     2333
     2334/* Also see section 3.7.1. */
    20772335static DECLCALLBACK(int) vrbProcSetConverterFormat(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    20782336{
     
    20912349        hdaCodecSetRegisterU16(&pThis->paNodes[CODEC_NID(cmd)].spdifin.u32A_param, cmd, 0);
    20922350    else
    2093         LogRel2(("HDA: Unhandled set converter format command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n",
    2094                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     2351        LogRel2(("HDA: Warning: Unhandled set converter format command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    20952352
    20962353    return VINF_SUCCESS;
     
    21122369        *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F0c_param;
    21132370    else
    2114         LogRel2(("HDA: Unhandled get EAPD/BTL enable command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
     2371        LogRel2(("HDA: Warning: Unhandled get EAPD/BTL enabled command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    21152372
    21162373    return VINF_SUCCESS;
     
    21332390        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F0c_param;
    21342391    else
    2135         LogRel2(("HDA: Unhandled set EAPD/BTL enable command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n",
    2136                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     2392        LogRel2(("HDA: Warning: Unhandled set EAPD/BTL enabled command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    21372393
    21382394    if (pu32Reg)
     
    21532409        *pResp = pThis->paNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
    21542410    else
    2155         LogRel2(("HDA: Unhandled get volume knob control command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
     2411        LogRel2(("HDA: Warning: Unhandled get volume knob control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    21562412
    21572413    return VINF_SUCCESS;
     
    21702426        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
    21712427    else
    2172         LogRel2(("HDA: Unhandled set volume control command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n",
    2173                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     2428        LogRel2(("HDA: Warning: Unhandled set volume knob control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    21742429
    21752430    if (pu32Reg)
     
    21792434}
    21802435
     2436/* F15 */
     2437static DECLCALLBACK(int) vrbProcGetGPIOData(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     2438{
     2439    if (!vrbIsValidNode(pThis, cmd, pResp))
     2440        return VINF_SUCCESS;
     2441
     2442    *pResp = 0;
     2443
     2444    return VINF_SUCCESS;
     2445}
     2446
     2447/* 715 */
     2448static DECLCALLBACK(int) vrbProcSetGPIOData(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     2449{
     2450    if (!vrbIsValidNode(pThis, cmd, pResp))
     2451        return VINF_SUCCESS;
     2452
     2453    *pResp = 0;
     2454
     2455    return VINF_SUCCESS;
     2456}
     2457
     2458/* F16 */
     2459static DECLCALLBACK(int) vrbProcGetGPIOEnableMask(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     2460{
     2461    if (!vrbIsValidNode(pThis, cmd, pResp))
     2462        return VINF_SUCCESS;
     2463
     2464    *pResp = 0;
     2465
     2466    return VINF_SUCCESS;
     2467}
     2468
     2469/* 716 */
     2470static DECLCALLBACK(int) vrbProcSetGPIOEnableMask(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     2471{
     2472    if (!vrbIsValidNode(pThis, cmd, pResp))
     2473        return VINF_SUCCESS;
     2474
     2475    *pResp = 0;
     2476
     2477    return VINF_SUCCESS;
     2478}
     2479
    21812480/* F17 */
    21822481static DECLCALLBACK(int) vrbProcGetGPIOUnsolisted(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     
    21882487
    21892488    /* Note: this is true for ALC885. */
    2190     if (CODEC_NID(cmd) == 0x1 /* AFG */)
     2489    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    21912490        *pResp = pThis->paNodes[1].afg.u32F17_param;
    21922491    else
    2193         LogRel2(("HDA: Unhandled get GPIO unsolisted command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
     2492        LogRel2(("HDA: Warning: Unhandled get GPIO unsolisted command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    21942493
    21952494    return VINF_SUCCESS;
     
    22052504
    22062505    uint32_t *pu32Reg = NULL;
    2207     if (CODEC_NID(cmd) == 1 /* AFG */)
     2506    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    22082507        pu32Reg = &pThis->paNodes[1].afg.u32F17_param;
    22092508    else
    2210         LogRel2(("HDA: Unhandled set GPIO unsolisted command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n",
    2211                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     2509        LogRel2(("HDA: Warning: Unhandled set GPIO unsolisted command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    22122510
    22132511    if (pu32Reg)
     
    22382536        *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
    22392537    else
    2240         LogRel2(("HDA: Unhandled get config command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));
     2538        LogRel2(("HDA: Warning: Unhandled get config command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd));
    22412539
    22422540    return VINF_SUCCESS;
     
    22592557        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
    22602558    else
    2261         LogRel2(("HDA: Unhandled set config command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n",
    2262                  cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd)));
     2559        LogRel2(("HDA: Warning: Unhandled set config command (%RU8) for NID0x%x: 0x%x\n", u8Offset, CODEC_NID(cmd), cmd));
    22632560
    22642561    if (pu32Reg)
     
    23462643    { 0x000F0F00, CODEC_VERB_8BIT_CMD , vrbProcGetVolumeKnobCtrl      },
    23472644    { 0x00070F00, CODEC_VERB_8BIT_CMD , vrbProcSetVolumeKnobCtrl      },
     2645    { 0x000F1500, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOData            },
     2646    { 0x00071500, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOData            },
     2647    { 0x000F1600, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOEnableMask      },
     2648    { 0x00071600, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOEnableMask      },
    23482649    { 0x000F1700, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOUnsolisted      },
    23492650    { 0x00071700, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOUnsolisted      },
     
    23572658    { 0x000B0000, CODEC_VERB_16BIT_CMD, vrbProcGetAmplifier           },
    23582659    { 0x00030000, CODEC_VERB_16BIT_CMD, vrbProcSetAmplifier           },
     2660    /** @todo Implement 0x7e7: IDT Set GPIO (STAC922x only). */
    23592661};
    23602662
     
    25812883{
    25822884    Assert(CODEC_CAD(cmd) == pThis->id);
    2583     if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
    2584         LogFlowFunc(("cmd %x was addressed to reserved node\n", cmd));
    25852885
    25862886    if (   CODEC_VERBDATA(cmd) == 0
     
    25882888    {
    25892889        *pfn = vrbProcUnimplemented;
    2590         /// @todo r=michaln: There needs to be a counter to avoid log flooding (see e.g. DevRTC.cpp)
    2591         LogFlowFunc(("cmd %x was ignored\n", cmd));
    2592         return VINF_SUCCESS;
    2593     }
    2594 
    2595     for (int i = 0; i < pThis->cVerbs; ++i)
     2890        AssertMsgFailed(("Unknown / invalid node 0x%x\n", CODEC_NID(cmd)));
     2891        return VINF_SUCCESS;
     2892    }
     2893
     2894    for (int i = 0; i < pThis->cVerbs; i++)
    25962895    {
    25972896        if ((CODEC_VERBDATA(cmd) & pThis->paVerbs[i].mask) == pThis->paVerbs[i].verb)
     
    26032902
    26042903    *pfn = vrbProcUnimplemented;
    2605     LogFlowFunc(("callback for %x wasn't found\n", CODEC_VERBDATA(cmd)));
     2904
     2905    LogFlowFunc(("[NID0x%x] Callback for %x not found\n", CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
    26062906    return VINF_SUCCESS;
    26072907}
     
    26112911 */
    26122912
    2613 /**
    2614  *
    2615  * routines open one of the voices (IN, OUT) with corresponding parameters.
    2616  * this routine could be called from HDA on setting/resseting sound format.
    2617  *
    2618  * @todo Probably passed settings should be verified (if AFG's declared proposed
    2619  *       format) before enabling.
    2620  */
    2621 int hdaCodecOpenStream(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, PPDMAUDIOSTREAMCFG pCfg)
     2913int hdaCodecAddStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg)
    26222914{
    26232915    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    2624 
    2625     int rc;
    2626     switch (enmSoundSource)
    2627     {
    2628         case PI_INDEX:
    2629             rc = pThis->pfnOpenIn(pThis->pHDAState,  "hda.in", PDMAUDIORECSOURCE_LINE_IN, pCfg);
     2916    AssertPtrReturn(pCfg,  VERR_INVALID_POINTER);
     2917
     2918    int rc = VINF_SUCCESS;
     2919
     2920    switch (enmMixerCtl)
     2921    {
     2922        case PDMAUDIOMIXERCTL_LINE_IN:
     2923#ifdef VBOX_WITH_HDA_MIC_IN
     2924        case PDMAUDIOMIXERCTL_MIC_IN:
     2925#endif
     2926        {
     2927            pCfg->enmDir = PDMAUDIODIR_IN;
    26302928            break;
    2631 #ifdef VBOX_WITH_HDA_MIC_IN
    2632         case MC_INDEX:
    2633             rc = pThis->pfnOpenIn(pThis->pHDAState,  "hda.mc", PDMAUDIORECSOURCE_MIC, pCfg);
     2929        }
     2930
     2931        case PDMAUDIOMIXERCTL_VOLUME:
     2932        case PDMAUDIOMIXERCTL_FRONT:
     2933        {
     2934            pCfg->enmDir = PDMAUDIODIR_OUT;
    26342935            break;
    2635 #endif
    2636         case PO_INDEX:
    2637             rc = pThis->pfnOpenOut(pThis->pHDAState, "hda.out", pCfg);
     2936        }
     2937
     2938        default:
     2939            AssertMsgFailed(("Mixer control %ld not implemented\n", enmMixerCtl));
     2940            rc = VERR_NOT_IMPLEMENTED;
    26382941            break;
    2639 
    2640         default:
    2641             AssertMsgFailed(("Index %ld not implemented\n", enmSoundSource));
    2642             rc = VERR_NOT_IMPLEMENTED;
    2643     }
     2942    }
     2943
     2944    if (RT_SUCCESS(rc))
     2945        rc = pThis->pfnMixerAddStream(pThis->pHDAState, enmMixerCtl, pCfg);
    26442946
    26452947    LogFlowFuncLeaveRC(rc);
     
    26472949}
    26482950
     2951int hdaCodecRemoveStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl)
     2952{
     2953    return VINF_SUCCESS;
     2954}
     2955
    26492956int hdaCodecSaveState(PHDACODEC pThis, PSSMHANDLE pSSM)
    26502957{
    2651     AssertLogRelMsgReturn(pThis->cTotalNodes == 0x1c, ("cTotalNodes=%#x, should be 0x1c", pThis->cTotalNodes),
     2958    AssertLogRelMsgReturn(pThis->cTotalNodes == STAC9221_NUM_NODES, ("cTotalNodes=%#x, should be 0x1c", pThis->cTotalNodes),
    26522959                          VERR_INTERNAL_ERROR);
    26532960    SSMR3PutU32(pSSM, pThis->cTotalNodes);
     
    27153022     */
    27163023    if (hdaCodecIsDacNode(pThis, pThis->u8DacLineOut))
    2717         hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_PCM);
     3024        hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_FRONT);
    27183025    else if (hdaCodecIsSpdifOutNode(pThis, pThis->u8DacLineOut))
    2719         hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, PDMAUDIOMIXERCTL_PCM);
     3026        hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, PDMAUDIOMIXERCTL_FRONT);
    27203027    hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
    27213028
     
    27403047{
    27413048    AssertPtrReturn(pDevIns, VERR_INVALID_POINTER);
    2742     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    2743     AssertPtrReturn(pCfg, VERR_INVALID_POINTER);
    2744 
    2745     pThis->id        = uLUN;
    2746     pThis->paVerbs   = &g_aCodecVerbs[0];
    2747     pThis->cVerbs    = RT_ELEMENTS(g_aCodecVerbs);
    2748 
    2749     pThis->pfnLookup       = codecLookup;
     3049    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
     3050    AssertPtrReturn(pCfg,    VERR_INVALID_POINTER);
     3051
     3052    pThis->id      = uLUN;
     3053    pThis->paVerbs = &g_aCodecVerbs[0];
     3054    pThis->cVerbs  = RT_ELEMENTS(g_aCodecVerbs);
     3055
    27503056#ifdef DEBUG
    27513057    pThis->pfnDbgSelector  = codecDbgSelector;
    27523058    pThis->pfnDbgListNodes = codecDbgListNodes;
    27533059#endif
     3060    pThis->pfnLookup       = codecLookup;
     3061
    27543062    int rc = stac9220Construct(pThis);
    27553063    AssertRC(rc);
    27563064
    2757     /* common root node initializers */
    2758     pThis->paNodes[0].node.au32F00_param[0] = CODEC_MAKE_F00_00(pThis->u16VendorId, pThis->u16DeviceId);
    2759     pThis->paNodes[0].node.au32F00_param[4] = CODEC_MAKE_F00_04(0x1, 0x1);
    2760     /* common AFG node initializers */
    2761     pThis->paNodes[1].node.au32F00_param[4] = CODEC_MAKE_F00_04(0x2, pThis->cTotalNodes - 2);
    2762     pThis->paNodes[1].node.au32F00_param[5] = CODEC_MAKE_F00_05(1, CODEC_F00_05_AFG);
    2763     pThis->paNodes[1].afg.u32F20_param = CODEC_MAKE_F20(pThis->u16VendorId, pThis->u8BSKU, pThis->u8AssemblyId);
    2764 
    2765     /* This codec uses a fixed setting (44.1 kHz, 16-bit signed, 2 channels). */
    2766     pThis->strmCfg.uHz           = 44100;
    2767     pThis->strmCfg.cChannels     = 2;
    2768     pThis->strmCfg.enmFormat     = AUD_FMT_S16;
    2769     pThis->strmCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS;
    2770 
    2771     hdaCodecOpenStream(pThis, PI_INDEX, &pThis->strmCfg);
     3065    /* Common root node initializers. */
     3066    pThis->paNodes[STAC9220_NID_ROOT].root.node.au32F00_param[0] = CODEC_MAKE_F00_00(pThis->u16VendorId, pThis->u16DeviceId);
     3067    pThis->paNodes[STAC9220_NID_ROOT].root.node.au32F00_param[4] = CODEC_MAKE_F00_04(0x1, 0x1);
     3068
     3069    /* Common AFG node initializers. */
     3070    pThis->paNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0x4] = CODEC_MAKE_F00_04(0x2, pThis->cTotalNodes - 2);
     3071    pThis->paNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0x5] = CODEC_MAKE_F00_05(1, CODEC_F00_05_AFG);
     3072    pThis->paNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0xA] = CODEC_F00_0A_44_1KHZ | CODEC_F00_0A_16_BIT;
     3073    pThis->paNodes[STAC9220_NID_AFG].afg.u32F20_param = CODEC_MAKE_F20(pThis->u16VendorId, pThis->u8BSKU, pThis->u8AssemblyId);
     3074
     3075    /* Initialize the streams to some default values (44.1 kHz, 16-bit signed, 2 channels).
     3076     * The codec's (fixed) delivery rate is 48kHz, so a frame will be delivered every 20.83us. */
     3077    PDMAUDIOSTREAMCFG strmCfg;
     3078    strmCfg.uHz           = 44100;
     3079    strmCfg.cChannels     = 2;
     3080    strmCfg.enmFormat     = AUD_FMT_S16;
     3081    strmCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS;
     3082
     3083    /*
     3084     * Output streams.
     3085     */
     3086    strmCfg.enmDir = PDMAUDIODIR_OUT;
     3087
     3088    /* Front. */
     3089    strmCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
     3090    rc = hdaCodecAddStream(pThis, PDMAUDIOMIXERCTL_FRONT, &strmCfg);
     3091    AssertRC(rc);
     3092
     3093#ifdef VBOX_WITH_HDA_51_SURROUND
     3094    /* Center / LFE. */
     3095    strmCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_CENTER_LFE;
     3096    rc = hdaCodecAddStream(pThis, PDMAUDIOMIXERCTL_CENTER_LFE, &strmCfg);
     3097    AssertRC(rc);
     3098
     3099    /* Rear. */
     3100    strmCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_REAR;
     3101    rc = hdaCodecAddStream(pThis, PDMAUDIOMIXERCTL_REAR, &strmCfg);
     3102    AssertRC(rc);
     3103#endif
     3104
     3105    /*
     3106     * Input streams.
     3107     */
     3108    strmCfg.enmDir = PDMAUDIODIR_IN;
     3109
    27723110#ifdef VBOX_WITH_HDA_MIC_IN
    2773     hdaCodecOpenStream(pThis, MC_INDEX, &pThis->strmCfg);
     3111    strmCfg.DestSource.Source = PDMAUDIORECSOURCE_MIC;
     3112    rc = hdaCodecAddStream(pThis, PDMAUDIOMIXERCTL_MIC_IN, &strmCfg);
     3113    AssertRC(rc);
    27743114#endif
    2775     hdaCodecOpenStream(pThis, PO_INDEX, &pThis->strmCfg);
    2776 
    2777     /* Initialize the AFG node with the fixed setting. */
    2778     pThis->paNodes[1].node.au32F00_param[0xA] = CODEC_F00_0A_44_1KHZ | CODEC_F00_0A_16_BIT;
    2779 
     3115    strmCfg.DestSource.Source = PDMAUDIORECSOURCE_LINE;
     3116    rc = hdaCodecAddStream(pThis, PDMAUDIOMIXERCTL_LINE_IN, &strmCfg);
     3117    AssertRC(rc);
     3118
     3119    /*
     3120     * Reset nodes.
     3121     */
    27803122    AssertPtr(pThis->paNodes);
    27813123    AssertPtr(pThis->pfnCodecNodeReset);
     
    27843126        pThis->pfnCodecNodeReset(pThis, i, &pThis->paNodes[i]);
    27853127
    2786     hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params,       PDMAUDIOMIXERCTL_PCM);
     3128    /*
     3129     * Set initial volume.
     3130     */
     3131    hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params,       PDMAUDIOMIXERCTL_FRONT);
    27873132    hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
    2788 
    2789     return VINF_SUCCESS;
    2790 }
    2791 
     3133#ifdef VBOX_WITH_HDA_MIC_IN
     3134    #error "Implement mic-in support!"
     3135#endif
     3136
     3137    return VINF_SUCCESS;
     3138}
     3139
  • trunk/src/VBox/Devices/Audio/DevIchHdaCodec.h

    r59439 r60353  
    1616 */
    1717
    18 #ifndef DEV_CODEC_H
    19 #define DEV_CODEC_H
     18#ifndef DEV_HDA_CODEC_H
     19#define DEV_HDA_CODEC_H
    2020
    2121/** The ICH HDA (Intel) controller. */
     
    3939#define CODEC_RESPONSE_UNSOLICITED RT_BIT_64(34)
    4040
    41 
    42 #ifndef VBOX_WITH_HDA_CODEC_EMU
    4341typedef struct CODECVERB
    4442{
     
    4846    PFNHDACODECVERBPROCESSOR pfn;
    4947} CODECVERB;
    50 #endif
    5148
    52 #ifndef VBOX_WITH_HDA_CODEC_EMU
    53 # define TYPE union
    54 #else
    55 # define TYPE struct
    56 typedef struct CODECEMU CODECEMU;
    57 typedef CODECEMU *PCODECEMU;
    58 #endif
    59 TYPE CODECNODE;
    60 typedef TYPE CODECNODE CODECNODE;
    61 typedef TYPE CODECNODE *PCODECNODE;
     49union CODECNODE;
     50typedef union CODECNODE CODECNODE, *PCODECNODE;
    6251
    63 typedef enum
    64 {
    65     PI_INDEX = 0,    /**< PCM in */
    66     PO_INDEX,        /**< PCM out */
    67     MC_INDEX,        /**< Mic in */
    68     LAST_INDEX
    69 } ENMSOUNDSOURCE;
    70 
     52/**
     53 * Structure for keeping a HDA codec state.
     54 */
    7155typedef struct HDACODEC
    7256{
     
    7963     * A driver only can be assigned to one codec at a time. */
    8064    RTLISTANCHOR            lstDrv;
    81     /** The codec's current audio stream configuration. */
    82     PDMAUDIOSTREAMCFG       strmCfg;
    8365
    84 #ifndef VBOX_WITH_HDA_CODEC_EMU
    8566    CODECVERB const        *paVerbs;
    8667    int                     cVerbs;
    87 #else
    88     PCODECEMU               pCodecBackend;
    89 #endif
     68
    9069    PCODECNODE              paNodes;
    9170    /** Pointer to HDA state (controller) this
     
    9372    PHDASTATE               pHDAState;
    9473    bool                    fInReset;
    95 #ifndef VBOX_WITH_HDA_CODEC_EMU
     74
    9675    const uint8_t           cTotalNodes;
    9776    const uint8_t          *au8Ports;
     
    11089    const uint8_t           u8AdcVolsLineIn;
    11190    const uint8_t           u8DacLineOut;
    112 #endif
     91
    11392    /** Callbacks to the HDA controller, mostly used for multiplexing to the various host backends. */
    114     DECLR3CALLBACKMEMBER(void, pfnCloseIn, (PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource));
    115     DECLR3CALLBACKMEMBER(void, pfnCloseOut, (PHDASTATE pThis));
    116     DECLR3CALLBACKMEMBER(int, pfnOpenIn, (PHDASTATE pThis, const char *pszName, PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg));
    117     DECLR3CALLBACKMEMBER(int, pfnOpenOut, (PHDASTATE pThis, const char *pszName, PPDMAUDIOSTREAMCFG pCfg));
    118     DECLR3CALLBACKMEMBER(int, pfnSetVolume, (PHDASTATE pThis, ENMSOUNDSOURCE enmSource, bool fMute, uint8_t uVolLeft, uint8_t uVolRight));
     93    DECLR3CALLBACKMEMBER(int, pfnMixerAddStream, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg));
     94    DECLR3CALLBACKMEMBER(int, pfnMixerRemoveStream, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl));
     95    DECLR3CALLBACKMEMBER(int, pfnMixerSetVolume, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOVOLUME pVol));
    11996    /** Callbacks by codec implementation. */
    12097    DECLR3CALLBACKMEMBER(int, pfnLookup, (PHDACODEC pThis, uint32_t verb, PPFNHDACODECVERBPROCESSOR));
     
    130107int hdaCodecSaveState(PHDACODEC pThis, PSSMHANDLE pSSM);
    131108int hdaCodecLoadState(PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion);
    132 int hdaCodecOpenStream(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, PPDMAUDIOSTREAMCFG pCfg);
     109int hdaCodecAddStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg);
     110int hdaCodecRemoveStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl);
    133111
    134112#define HDA_SSM_VERSION   6
     
    143121#define HDA_SSM_VERSION_1 1
    144122
    145 # ifdef VBOX_WITH_HDA_CODEC_EMU
    146 /* */
    147 struct CODECEMU
    148 {
    149     DECLR3CALLBACKMEMBER(int, pfnCodecEmuConstruct,(PHDACODEC pThis));
    150     DECLR3CALLBACKMEMBER(int, pfnCodecEmuDestruct,(PHDACODEC pThis));
    151     DECLR3CALLBACKMEMBER(int, pfnCodecEmuReset,(PHDACODEC pThis, bool fInit));
    152 };
    153 # endif
    154 #endif
     123#endif /* DEV_HDA_CODEC_H */
    155124
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r59994 r60353  
    7272int drvAudioAddHstOut(PDRVAUDIO pThis, const char *pszName, PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOHSTSTRMOUT *ppHstStrmOut)
    7373{
    74     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     74    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    7575    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
    76     AssertPtrReturn(pCfg, VERR_INVALID_POINTER);
    77 
    78     PPDMAUDIOHSTSTRMOUT pHstStrmOut;
     76    AssertPtrReturn(pCfg,    VERR_INVALID_POINTER);
    7977
    8078    int rc;
    81     if (   conf.fixed_out.enabled /** @todo Get rid of these settings! */
    82         && conf.fixed_out.greedy)
     79
     80    PPDMAUDIOHSTSTRMOUT pHstStrmOut = drvAudioFindSpecificOut(pThis, NULL, pCfg);
     81    if (!pHstStrmOut)
    8382    {
    8483        rc = drvAudioAllocHstOut(pThis, pszName, pCfg, &pHstStrmOut);
    85     }
    86     else
    87         rc = VERR_NOT_FOUND;
    88 
    89     if (RT_FAILURE(rc))
    90     {
    91         pHstStrmOut = drvAudioFindSpecificOut(pThis, NULL, pCfg);
    92         if (!pHstStrmOut)
    93         {
    94             rc = drvAudioAllocHstOut(pThis, pszName, pCfg, &pHstStrmOut);
    95             if (RT_FAILURE(rc))
    96                 pHstStrmOut = drvAudioFindAnyHstOut(pThis, NULL /* pHstStrmOut */);
    97         }
    98 
    99         rc = pHstStrmOut ? VINF_SUCCESS : rc;
    100     }
     84        if (RT_FAILURE(rc))
     85            pHstStrmOut = drvAudioFindAnyHstOut(pThis, NULL /* pHstStrmOut */);
     86    }
     87
     88    rc = pHstStrmOut ? VINF_SUCCESS : rc;
    10189
    10290    if (RT_SUCCESS(rc))
     
    10694}
    10795
     96#ifndef VBOX_AUDIO_TESTCASE
    10897static PDMAUDIOFMT drvAudioGetConfFormat(PCFGMNODE pCfgHandle, const char *pszKey,
    10998                                         PDMAUDIOFMT enmDefault, bool *pfDefault)
     
    272261    return VINF_SUCCESS;
    273262}
     263#endif /* !VBOX_AUDIO_TESTCASE */
    274264
    275265static bool drvAudioStreamCfgIsValid(PPDMAUDIOSTREAMCFG pCfg)
     
    301291    fValid |= pCfg->uHz > 0;
    302292
    303 #ifdef DEBUG
    304     drvAudioStreamCfgPrint(pCfg);
    305 #endif
    306 
    307     LogFlowFunc(("pCfg=%p, fValid=%RTbool\n", pCfg, fValid));
    308293    return fValid;
    309294}
     
    828813                                PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOGSTSTRMOUT *ppGstStrmOut)
    829814{
    830     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     815    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    831816    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
    832     AssertPtrReturn(pCfg, VERR_INVALID_POINTER);
    833 
    834     /*
    835      * Try figuring out which audio stream configuration this backend
    836      * should use. If fixed output is enabled the backend will be tied
    837      * to a fixed rate (in Hz, among other parameters), regardless of
    838      * what the backend could do else.
    839      */
    840     PPDMAUDIOSTREAMCFG pBackendCfg;
    841     if (conf.fixed_out.enabled)
    842         pBackendCfg = &conf.fixed_out.settings;
    843     else
    844         pBackendCfg = pCfg;
    845 
    846     AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
    847 
    848     LogFlowFunc(("Using fixed audio output settings: %RTbool\n",
    849                  RT_BOOL(conf.fixed_out.enabled)));
     817    AssertPtrReturn(pCfg,    VERR_INVALID_POINTER);
    850818
    851819    PPDMAUDIOGSTSTRMOUT pGstStrmOut =
     
    861829     */
    862830    PPDMAUDIOHSTSTRMOUT pHstStrmOut;
    863     int rc = drvAudioAddHstOut(pThis, pszName, pBackendCfg, &pHstStrmOut);
     831    int rc = drvAudioAddHstOut(pThis, pszName, pCfg, &pHstStrmOut);
    864832    if (RT_FAILURE(rc))
    865833    {
     
    893861                                      PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOGSTSTRMIN *ppGstStrmIn)
    894862{
    895     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     863    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    896864    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
    897 
    898 /*
    899      * Try figuring out which audio stream configuration this backend
    900      * should use for the audio input data. If fixed input is enabled
    901      * the backend will be tied to a fixed rate (in Hz, among other parameters),
    902      * regardless of what the backend initially wanted to use.
    903      */
    904     PPDMAUDIOSTREAMCFG pBackendCfg;
    905     if (conf.fixed_in.enabled)
    906         pBackendCfg = &conf.fixed_in.settings;
    907     else
    908         pBackendCfg = pCfg;
    909 
    910     AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
    911 
    912     LogFlowFunc(("Using fixed audio input settings: %RTbool\n",
    913                  RT_BOOL(conf.fixed_in.enabled)));
     865    AssertPtrReturn(pCfg,    VERR_INVALID_POINTER);
    914866
    915867    PPDMAUDIOGSTSTRMIN pGstStrmIn = (PPDMAUDIOGSTSTRMIN)RTMemAllocZ(sizeof(PDMAUDIOGSTSTRMIN));
     
    921873     */
    922874    PPDMAUDIOHSTSTRMIN pHstStrmIn;
    923     int rc = drvAudioHstInAdd(pThis, pszName, pBackendCfg, enmRecSource, &pHstStrmIn);
     875    int rc = drvAudioHstInAdd(pThis, pszName, pCfg, enmRecSource, &pHstStrmIn);
    924876    if (RT_FAILURE(rc))
    925877    {
     
    17161668}
    17171669
    1718 static struct audio_option audio_options[] =
    1719 {
    1720     /* DAC */
    1721     {"DACFixedSettings", AUD_OPT_BOOL, &conf.fixed_out.enabled,
    1722      "Use fixed settings for host DAC", NULL, 0},
    1723 
    1724     {"DACFixedFreq", AUD_OPT_INT, &conf.fixed_out.settings.uHz,
    1725      "Frequency for fixed host DAC", NULL, 0},
    1726 
    1727     {"DACFixedFmt", AUD_OPT_FMT, &conf.fixed_out.settings.enmFormat,
    1728      "Format for fixed host DAC", NULL, 0},
    1729 
    1730     {"DACFixedChannels", AUD_OPT_INT, &conf.fixed_out.settings.cChannels,
    1731      "Number of channels for fixed DAC (1 - mono, 2 - stereo)", NULL, 0},
    1732 
    1733     {"DACVoices", AUD_OPT_INT, &conf.fixed_out.cStreams, /** @todo Rename! */
    1734      "Number of streams for DAC", NULL, 0},
    1735 
    1736     /* ADC */
    1737     {"ADCFixedSettings", AUD_OPT_BOOL, &conf.fixed_in.enabled,
    1738      "Use fixed settings for host ADC", NULL, 0},
    1739 
    1740     {"ADCFixedFreq", AUD_OPT_INT, &conf.fixed_in.settings.uHz,
    1741      "Frequency for fixed host ADC", NULL, 0},
    1742 
    1743     {"ADCFixedFmt", AUD_OPT_FMT, &conf.fixed_in.settings.enmFormat,
    1744      "Format for fixed host ADC", NULL, 0},
    1745 
    1746     {"ADCFixedChannels", AUD_OPT_INT, &conf.fixed_in.settings.cChannels,
    1747      "Number of channels for fixed ADC (1 - mono, 2 - stereo)", NULL, 0},
    1748 
    1749     {"ADCVoices", AUD_OPT_INT, &conf.fixed_in.cStreams, /** @todo Rename! */
    1750      "Number of streams for ADC", NULL, 0},
    1751 
    1752     /* Misc */
    1753     {"TimerFreq", AUD_OPT_INT, &conf.period.hz,
    1754      "Timer frequency in Hz (0 - use lowest possible)", NULL, 0},
    1755 
    1756     {"PLIVE", AUD_OPT_BOOL, &conf.plive,
    1757      "(undocumented)", NULL, 0} /** @todo What is this? */
    1758 };
    1759 
    17601670static DECLCALLBACK(int) drvAudioInit(PCFGMNODE pCfgHandle, PPDMDRVINS pDrvIns)
    17611671{
     
    17741684
    17751685    int rc = RTCritSectInit(&pThis->CritSect);
    1776     if (RT_SUCCESS(rc))
    1777     {
    1778         rc = drvAudioProcessOptions(pCfgHandle, "AUDIO", audio_options, RT_ELEMENTS(audio_options));
    1779         /** @todo Check for invalid options? */
    1780 
    1781         pThis->cStreamsFreeOut = conf.fixed_out.cStreams;
    1782         pThis->cStreamsFreeIn  = conf.fixed_in.cStreams;
    1783 
    1784         if (!pThis->cStreamsFreeOut)
    1785             pThis->cStreamsFreeOut = 1;
    1786 
    1787         if (!pThis->cStreamsFreeIn)
    1788             pThis->cStreamsFreeIn = 1;
    1789     }
     1686
     1687    /** @todo Add audio driver options. */
    17901688
    17911689    /*
     
    19641862
    19651863static DECLCALLBACK(int) drvAudioCreateIn(PPDMIAUDIOCONNECTOR pInterface, const char *pszName,
    1966                                           PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg,
    1967                                           PPDMAUDIOGSTSTRMIN *ppGstStrmIn)
     1864                                          PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOGSTSTRMIN *ppGstStrmIn)
    19681865{
    19691866    AssertPtrReturn(pInterface,  VERR_INVALID_POINTER);
     
    19731870    AssertPtrReturn(ppGstStrmIn, VERR_INVALID_POINTER);
    19741871
     1872    Assert(pCfg->enmDir == PDMAUDIODIR_IN);
     1873
    19751874    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
    19761875
     
    19871886    }
    19881887
    1989     PPDMAUDIOGSTSTRMIN pGstStrmIn = *ppGstStrmIn;
    1990     if (   RT_SUCCESS(rc)
    1991         && pGstStrmIn
    1992         && drvAudioPCMPropsAreEqual(&pGstStrmIn->Props, pCfg))
    1993     {
    1994         LogFunc(("[%s] Exists and matches required configuration, skipping creation\n",
    1995                  pGstStrmIn->MixBuf.pszName));
    1996         rc = VWRN_ALREADY_EXISTS;
    1997     }
    1998 
    1999     if (rc != VINF_SUCCESS) /* Note: Can be VWRN_ALREADY_EXISTS, so don't use VINF_SUCCESS here. */
    2000     {
    2001         int rc2 = RTCritSectLeave(&pThis->CritSect);
    2002         AssertRC(rc2);
    2003 
    2004         return rc;
    2005     }
    2006 
    2007     if (   !conf.fixed_in.enabled
    2008         && pGstStrmIn)
    2009     {
    2010         drvAudioDestroyGstIn(pThis, pGstStrmIn);
    2011         pGstStrmIn = NULL;
    2012     }
    2013 
    2014     if (pGstStrmIn)
    2015     {
    2016         PPDMAUDIOHSTSTRMIN pHstStrmIn = pGstStrmIn->pHstStrmIn;
    2017         AssertPtr(pHstStrmIn);
    2018 
    2019         drvAudioGstInFreeRes(pGstStrmIn);
    2020 
    2021         char *pszTemp;
    2022         if (RTStrAPrintf(&pszTemp, "%s (Guest)", pszName) <= 0)
    2023         {
    2024             RTMemFree(pGstStrmIn);
    2025 
    2026             int rc2 = RTCritSectLeave(&pThis->CritSect);
    2027             AssertRC(rc2);
    2028 
    2029             return VERR_NO_MEMORY;
    2030         }
    2031 
    2032         rc = drvAudioGstInInit(pGstStrmIn, pHstStrmIn, pszName, pCfg);
    2033 
    2034         RTStrFree(pszTemp);
    2035     }
    2036     else
    2037         rc = drvAudioCreateStreamPairIn(pThis, pszName, enmRecSource, pCfg, &pGstStrmIn);
    2038 
    2039     if (RT_SUCCESS(rc))
    2040     {
    2041         if (pGstStrmIn)
     1888    if (RT_SUCCESS(rc))
     1889    {
     1890        PPDMAUDIOGSTSTRMIN pGstStrmIn;
     1891        rc = drvAudioCreateStreamPairIn(pThis, pszName, pCfg->DestSource.Source, pCfg, &pGstStrmIn);
     1892        if (RT_SUCCESS(rc))
    20421893            *ppGstStrmIn = pGstStrmIn;
    20431894    }
     
    20591910    AssertPtrReturn(ppGstStrmOut, VERR_INVALID_POINTER);
    20601911
     1912    Assert(pCfg->enmDir == PDMAUDIODIR_OUT);
     1913
    20611914    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
    20621915
     
    20731926    }
    20741927
    2075     PPDMAUDIOGSTSTRMOUT pGstStrmOut = *ppGstStrmOut;
    2076     if (   RT_SUCCESS(rc)
    2077         && pGstStrmOut
    2078         && drvAudioPCMPropsAreEqual(&pGstStrmOut->Props, pCfg))
    2079     {
    2080         LogFunc(("[%s] Exists and matches required configuration, skipping creation\n",
    2081                  pGstStrmOut->MixBuf.pszName));
    2082 
    2083         rc = VWRN_ALREADY_EXISTS;
    2084     }
    2085 
    2086     if (rc != VINF_SUCCESS) /* Note: Can be VWRN_ALREADY_EXISTS, so don't use VINF_SUCCESS here. */
    2087     {
    2088         int rc2 = RTCritSectLeave(&pThis->CritSect);
    2089         AssertRC(rc2);
    2090 
    2091         return rc;
    2092     }
    2093 
    2094 #if 0
    2095     /* Any live samples that need to be updated after
    2096      * we set the new parameters? */
    2097     PPDMAUDIOGSTSTRMOUT pOldGstStrmOut = NULL;
    2098     uint32_t cLiveSamples = 0;
    2099 
    2100     if (   conf.plive
    2101         && pGstStrmOut
    2102         && (   !pGstStrmOut->State.fActive
    2103             && !pGstStrmOut->State.fEmpty))
    2104     {
    2105         cLiveSamples = pGstStrmOut->cTotalSamplesWritten;
    2106         if (cLiveSamples)
    2107         {
    2108             pOldGstStrmOut = pGstStrmOut;
    2109             pGstStrmOut = NULL;
    2110         }
    2111     }
    2112 #endif
    2113 
    2114     if (   pGstStrmOut
    2115         && !conf.fixed_out.enabled)
    2116     {
    2117         drvAudioDestroyGstOut(pThis, pGstStrmOut);
    2118         pGstStrmOut = NULL;
    2119     }
    2120 
    2121     if (pGstStrmOut)
    2122     {
    2123         PPDMAUDIOHSTSTRMOUT pHstStrmOut = pGstStrmOut->pHstStrmOut;
    2124         AssertPtr(pHstStrmOut);
    2125 
    2126         drvAudioGstOutFreeRes(pGstStrmOut);
    2127 
    2128         rc = drvAudioGstOutInit(pGstStrmOut, pHstStrmOut, pszName, pCfg);
    2129     }
    2130     else
    2131     {
     1928    if (RT_SUCCESS(rc))
     1929    {
     1930        PPDMAUDIOGSTSTRMOUT pGstStrmOut;
    21321931        rc = drvAudioCreateStreamPairOut(pThis, pszName, pCfg, &pGstStrmOut);
    2133         if (RT_FAILURE(rc))
    2134             LogFunc(("Failed to create output stream \"%s\", rc=%Rrc\n", pszName, rc));
    2135     }
    2136 
    2137     if (RT_SUCCESS(rc))
    2138     {
    2139         if (pGstStrmOut)
     1932        if (RT_SUCCESS(rc))
    21401933            *ppGstStrmOut = pGstStrmOut;
    2141 #if 0
    2142         /* Update remaining live samples with new rate. */
    2143         if (cLiveSamples)
    2144         {
    2145             AssertPtr(pOldGstStrmOut);
    2146 
    2147             uint32_t cSamplesMixed =
    2148                 (cLiveSamples << pOldGstStrmOut->Props.cShift)
    2149                 * pOldGstStrmOut->Props.cbPerSec
    2150                 / (*ppGstStrmOut)->Props.cbPerSec;
    2151 
    2152             pGstStrmOut->cTotalSamplesWritten += cSamplesMixed;
    2153         }
    2154 #endif
    21551934    }
    21561935
     
    23772156    }
    23782157
    2379 #ifdef DEBUG_andy
     2158#ifndef VBOX_AUDIO_TESTCASE
    23802159    CFGMR3Dump(pCfgHandle);
    23812160#endif
  • trunk/src/VBox/Devices/Audio/DrvAudio.h

    r59987 r60353  
    154154int DrvAudioStreamCfgToProps(PPDMAUDIOSTREAMCFG pCfg, PPDMPCMPROPS pProps);
    155155
    156 typedef struct fixed_settings
    157 {
    158     int enabled;
    159     int cStreams;
    160     int greedy;
    161     PDMAUDIOSTREAMCFG settings;
    162 } fixed_settings;
    163 
    164 static struct {
    165     struct fixed_settings fixed_out;
    166     struct fixed_settings fixed_in;
    167     union {
    168         int hz;
    169         int64_t ticks;
    170     } period;
    171     int plive;
    172 } conf = {
    173 
    174     /* Fixed output settings. */
    175     {                           /* DAC fixed settings */
    176         1,                      /* enabled */
    177         1,                      /* cStreams */
    178         1,                      /* greedy */
    179         {
    180             44100,              /* freq */
    181             2,                  /* nchannels */
    182             AUD_FMT_S16,        /* fmt */
    183             PDMAUDIOHOSTENDIANNESS
    184         }
    185     },
    186 
    187     /* Fixed input settings. */
    188     {                           /* ADC fixed settings */
    189         1,                      /* enabled */
    190         2,                      /* cStreams */
    191         1,                      /* greedy */
    192         {
    193             44100,              /* freq */
    194             2,                  /* nchannels */
    195             AUD_FMT_S16,        /* fmt */
    196             PDMAUDIOHOSTENDIANNESS
    197         }
    198     },
    199 
    200     { 200 },                    /* frequency (in Hz) */
    201     0,                          /* plive */ /** @todo Disable pending live? */
    202 };
    203156#endif /* DRV_AUDIO_H */
    204157
  • trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp

    r59890 r60353  
    7171        case PDMAUDIORECSOURCE_VIDEO:   return "Video";
    7272        case PDMAUDIORECSOURCE_AUX:     return "AUX";
    73         case PDMAUDIORECSOURCE_LINE_IN: return "Line In";
     73        case PDMAUDIORECSOURCE_LINE: return "Line In";
    7474        case PDMAUDIORECSOURCE_PHONE:   return "Phone";
    7575        default:
  • trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp

    r59987 r60353  
    907907            }
    908908
    909             case PDMAUDIORECSOURCE_LINE_IN:
     909            case PDMAUDIORECSOURCE_LINE:
    910910            default:
    911911                /* Try opening the default device (NULL). */
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r60307 r60353  
    19021902
    19031903    GEN_CHECK_SIZE(HDAINPUTSTREAM);
    1904     GEN_CHECK_OFF(HDAINPUTSTREAM, pStrmIn);
    1905     GEN_CHECK_OFF(HDAINPUTSTREAM, phStrmIn);
     1904    GEN_CHECK_OFF(HDAINPUTSTREAM, pGstStrm);
     1905    GEN_CHECK_OFF(HDAINPUTSTREAM, pMixStrm);
    19061906
    19071907    GEN_CHECK_SIZE(HDAOUTPUTSTREAM);
    1908     GEN_CHECK_OFF(HDAOUTPUTSTREAM, pStrmOut);
    1909     GEN_CHECK_OFF(HDAOUTPUTSTREAM, phStrmOut);
     1908    GEN_CHECK_OFF(HDAOUTPUTSTREAM, pGstStrm);
     1909    GEN_CHECK_OFF(HDAOUTPUTSTREAM, pMixStrm);
    19101910
    19111911    GEN_CHECK_SIZE(HDADRIVER);
     
    19171917    GEN_CHECK_OFF(HDADRIVER, pConnector);
    19181918    GEN_CHECK_OFF(HDADRIVER, LineIn);
     1919#ifdef VBOX_WITH_HDA_MIC_IN
    19191920    GEN_CHECK_OFF(HDADRIVER, MicIn);
    1920     GEN_CHECK_OFF(HDADRIVER, Out);
     1921#endif
     1922    GEN_CHECK_OFF(HDADRIVER, Front);
    19211923
    19221924    GEN_CHECK_SIZE(HDABDLESTATE);
     
    19371939
    19381940    GEN_CHECK_SIZE(HDASTREAM);
    1939     GEN_CHECK_OFF(HDASTREAM, u8Strm);
     1941    GEN_CHECK_OFF(HDASTREAM, u8SD);
    19401942    GEN_CHECK_OFF(HDASTREAM, u64BDLBase);
    19411943    GEN_CHECK_OFF(HDASTREAM, u16FMT);
     
    19521954    GEN_CHECK_OFF(HDASTATE, MMIOBaseAddr);
    19531955    GEN_CHECK_OFF(HDASTATE, au32Regs[0]);
    1954     GEN_CHECK_OFF(HDASTATE, au32Regs[HDA_NREGS]);
    1955     GEN_CHECK_OFF(HDASTATE, StrmStLineIn);
    1956     GEN_CHECK_OFF(HDASTATE, StrmStOut);
    1957     GEN_CHECK_OFF(HDASTATE, StrmStMicIn);
     1956    GEN_CHECK_OFF(HDASTATE, au32Regs[HDA_NUM_REGS]);
     1957    GEN_CHECK_OFF(HDASTATE, aStreams);
     1958    GEN_CHECK_OFF(HDASTATE, aTags);
    19581959    GEN_CHECK_OFF(HDASTATE, u64CORBBase);
    19591960    GEN_CHECK_OFF(HDASTATE, u64RIRBBase);
     
    19771978    GEN_CHECK_OFF(HDASTATE, StatBytesRead);
    19781979    GEN_CHECK_OFF(HDASTATE, StatBytesWritten);
    1979 #endif
     1980#endif /* VBOX_WITH_STATISTICS */
    19801981    GEN_CHECK_OFF(HDASTATE, pCodec);
    19811982    GEN_CHECK_OFF(HDASTATE, lstDrv);
    19821983    GEN_CHECK_OFF(HDASTATE, pMixer);
     1984    GEN_CHECK_OFF(HDASTATE, pSinkFront);
     1985#ifdef VBOX_WITH_HDA_51_SURROUND
     1986    GEN_CHECK_OFF(HDASTATE, pSinkCenterLFE);
     1987    GEN_CHECK_OFF(HDASTATE, pSinkRear);
     1988#endif
    19831989    GEN_CHECK_OFF(HDASTATE, pSinkLineIn);
     1990#ifdef VBOX_WITH_HDA_MIC_IN
    19841991    GEN_CHECK_OFF(HDASTATE, pSinkMicIn);
     1992#endif
    19851993    GEN_CHECK_OFF(HDASTATE, u64BaseTS);
    19861994    GEN_CHECK_OFF(HDASTATE, u8RespIntCnt);
     1995#ifdef VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT
     1996    GEN_CHECK_OFF(HDASTATE, pCircBuf);
     1997#endif
    19871998
    19881999#ifdef VBOX_WITH_NVME_IMPL
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette