Index: /trunk/src/VBox/Devices/Audio/DevCodec.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevCodec.cpp	(revision 36690)
+++ /trunk/src/VBox/Devices/Audio/DevCodec.cpp	(revision 36691)
@@ -279,5 +279,5 @@
         case 1:
             pNode->afg.node.name = "AFG";
-            pNode->node.au32F00_param[8] = CODEC_MAKE_F00_08(CODEC_F00_08_BEEP_GEN, 0xd, 0xd);
+            pNode->node.au32F00_param[8] = CODEC_MAKE_F00_08(1, 0xd, 0xd);
             pNode->node.au32F00_param[0xC] =   CODEC_MAKE_F00_0C(0x17)
                                              | CODEC_F00_0C_CAP_BALANCED_IO
@@ -1333,6 +1333,5 @@
         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].pcbeep.u32F07_param;
     else if (   codecIsReservedNode(pState, CODEC_NID(cmd))
-             && CODEC_NID(cmd) == 0x1b
-             && pState->enmCodec == STAC9220_CODEC)
+             && CODEC_NID(cmd) == 0x1b)
         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param;
     Assert((pu32Reg));
@@ -2165,5 +2164,5 @@
 }
 
-int codecConstruct(PPDMDEVINS pDevIns, CODECState *pState, ENMCODEC enmCodec)
+int codecConstruct(PPDMDEVINS pDevIns, CODECState *pState, PCFGMNODE pCfgHandle)
 {
     audsettings_t as;
@@ -2172,18 +2171,6 @@
     pState->cVerbs = sizeof(CODECVERBS)/sizeof(CODECVERB);
     pState->pfnLookup = codecLookup;
-    pState->enmCodec = enmCodec;
-    switch (enmCodec)
-    {
-        case STAC9220_CODEC:
-            rc = stac9220Construct(pState);
-            AssertRC(rc);
-            break;
-        case ALC885_CODEC:
-            rc = alc885Construct(pState);
-            AssertRC(rc);
-            break;
-        default:
-            AssertMsgFailed(("Unsupported Codec"));
-    }
+    rc = stac9220Construct(pState);
+    AssertRC(rc);
     /* common root node initializers */
     pState->pNodes[0].node.au32F00_param[0] = CODEC_MAKE_F00_00(pState->u16VendorId, pState->u16DeviceId);
@@ -2191,5 +2178,5 @@
     /* common AFG node initializers */
     pState->pNodes[1].node.au32F00_param[4] = CODEC_MAKE_F00_04(0x2, pState->cTotalNodes - 2);
-    pState->pNodes[1].node.au32F00_param[5] = CODEC_MAKE_F00_05(CODEC_F00_05_UNSOL, CODEC_F00_05_AFG);
+    pState->pNodes[1].node.au32F00_param[5] = CODEC_MAKE_F00_05(1, CODEC_F00_05_AFG);
     pState->pNodes[1].afg.u32F20_param = CODEC_MAKE_F20(pState->u16VendorId, pState->u8BSKU, pState->u8AssemblyId);
 
Index: /trunk/src/VBox/Devices/Audio/DevCodec.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevCodec.h	(revision 36690)
+++ /trunk/src/VBox/Devices/Audio/DevCodec.h	(revision 36691)
@@ -48,4 +48,7 @@
 #define CODEC_VERB_CMD8(cmd) (CODEC_VERB_CMD((cmd), CODEC_VERB_8BIT_CMD, 8))
 #define CODEC_VERB_CMD16(cmd) (CODEC_VERB_CMD((cmd), CODEC_VERB_16BIT_CMD, 16))
+#define CODEC_VERB_PAYLOAD4(cmd) ((cmd) & CODEC_VERB_4BIT_DATA)
+#define CODEC_VERB_PAYLOAD8(cmd) ((cmd) & CODEC_VERB_8BIT_DATA)
+#define CODEC_VERB_PAYLOAD16(cmd) ((cmd) & CODEC_VERB_16BIT_DATA)
 
 #define CODEC_VERB_GET_AMP_DIRECTION  RT_BIT(15)
@@ -74,8 +77,12 @@
 /* VendorID (7.3.4.1) */
 #define CODEC_MAKE_F00_00(vendorID, deviceID) (((vendorID) << 16) | (deviceID))
+#define CODEC_F00_00_VENDORID(f00_00) (((f00_00) >> 16) & 0xFFFF)
+#define CODEC_F00_00_DEVICEID(f00_00) ((f00_00) & 0xFFFF)
 /* RevisionID (7.3.4.2)*/
 #define CODEC_MAKE_F00_02(MajRev, MinRev, RevisionID, SteppingID) (((MajRev) << 20)|((MinRev) << 16)|((RevisionID) << 8)|(SteppingID))
 /* Subordinate node count (7.3.4.3)*/
 #define CODEC_MAKE_F00_04(startNodeNumber, totalNodeNumber) ((((startNodeNumber) & 0xFF) << 16)|((totalNodeNumber) & 0xFF))
+#define CODEC_F00_04_TO_START_NODE_NUMBER(f00_04) (((f00_04) >> 16) & 0xFF)
+#define CODEC_F00_04_TO_NODE_COUNT(f00_04) ((f00_04) & 0xFF)
 /*
  * Function Group Type  (7.3.4.4)
@@ -83,11 +90,13 @@
  * [0x80 - 0xff] are vendor defined function groups
  */
-#define CODEC_MAKE_F00_05(UnSol, NodeType) ((UnSol)|(NodeType))
+#define CODEC_MAKE_F00_05(UnSol, NodeType) (((UnSol) << 8)|(NodeType))
 #define CODEC_F00_05_UNSOL  RT_BIT(8)
 #define CODEC_F00_05_AFG    (0x1)
 #define CODEC_F00_05_MFG    (0x2)
+#define CODEC_F00_05_IS_UNSOL(f00_05) RT_BOOL((f00_05) & RT_BIT(8))
+#define CODEC_F00_05_GROUP(f00_05) ((f00_05) & 0xff)
 /*  Audio Function Group capabilities (7.3.4.5) */
-#define CODEC_MAKE_F00_08(BeepGen, InputDelay, OutputDelay) ((BeepGen)| (((InputDelay) & 0xF) << 8) | ((OutputDelay) & 0xF))
-#define CODEC_F00_08_BEEP_GEN RT_BIT(16)
+#define CODEC_MAKE_F00_08(BeepGen, InputDelay, OutputDelay) ((((BeepGen) & 0x1) << 16)| (((InputDelay) & 0xF) << 8) | ((OutputDelay) & 0xF))
+#define CODEC_F00_08_BEEP_GEN(f00_08) ((f00_08) & RT_BIT(16)
 
 /* Widget Capabilities (7.3.4.6) */
@@ -120,4 +129,20 @@
 #define CODEC_F00_09_CAP_IN_AMP_PRESENT     RT_BIT(1)
 #define CODEC_F00_09_CAP_LSB                RT_BIT(0)
+
+#define CODEC_F00_09_TYPE(f00_09) (((f00_09) >> 20) & 0xF)
+
+#define CODEC_F00_09_IS_CAP_CP(f00_09)              RT_BOOL((f00_09) & RT_BIT(12))
+#define CODEC_F00_09_IS_CAP_L_R_SWAP(f00_09)        RT_BOOL((f00_09) & RT_BIT(11))
+#define CODEC_F00_09_IS_CAP_POWER_CTRL(f00_09)      RT_BOOL((f00_09) & RT_BIT(10))
+#define CODEC_F00_09_IS_CAP_DIGITAL(f00_09)         RT_BOOL((f00_09) & RT_BIT(9))
+#define CODEC_F00_09_IS_CAP_CONNECTION_LIST(f00_09) RT_BOOL((f00_09) & RT_BIT(8))
+#define CODEC_F00_09_IS_CAP_UNSOL(f00_09)           RT_BOOL((f00_09) & RT_BIT(7))
+#define CODEC_F00_09_IS_CAP_PROC_WIDGET(f00_09)     RT_BOOL((f00_09) & RT_BIT(6))
+#define CODEC_F00_09_IS_CAP_STRIPE(f00_09)          RT_BOOL((f00_09) & RT_BIT(5))
+#define CODEC_F00_09_IS_CAP_FMT_OVERRIDE(f00_09)    RT_BOOL((f00_09) & RT_BIT(4))
+#define CODEC_F00_09_IS_CAP_AMP_OVERRIDE(f00_09)    RT_BOOL((f00_09) & RT_BIT(3))
+#define CODEC_F00_09_IS_CAP_OUT_AMP_PRESENT(f00_09) RT_BOOL((f00_09) & RT_BIT(2))
+#define CODEC_F00_09_IS_CAP_IN_AMP_PRESENT(f00_09)  RT_BOOL((f00_09) & RT_BIT(1))
+#define CODEC_F00_09_IS_CAP_LSB(f00_09)             RT_BOOL((f00_09) & RT_BIT(0))
 
 /* Supported PCM size, rates (7.3.4.7) */
@@ -164,5 +189,17 @@
 #define CODEC_F00_0C_CAP_IMPENDANCE_SENSE       RT_BIT(0)
 
-/* Amplifier capabilities (7.3.4.10) */
+#define CODEC_F00_0C_IS_CAP_HBR(f00_0c)                    ((f00_0c) & RT_BIT(27))
+#define CODEC_F00_0C_IS_CAP_DP(f00_0c)                     ((f00_0c) & RT_BIT(24))
+#define CODEC_F00_0C_IS_CAP_EAPD(f00_0c)                   ((f00_0c) & RT_BIT(16))
+#define CODEC_F00_0C_IS_CAP_HDMI(f00_0c)                   ((f00_0c) & RT_BIT(7))
+#define CODEC_F00_0C_IS_CAP_BALANCED_IO(f00_0c)            ((f00_0c) & RT_BIT(6))
+#define CODEC_F00_0C_IS_CAP_INPUT(f00_0c)                  ((f00_0c) & RT_BIT(5))
+#define CODEC_F00_0C_IS_CAP_OUTPUT(f00_0c)                 ((f00_0c) & RT_BIT(4))
+#define CODEC_F00_0C_IS_CAP_HP(f00_0c)                     ((f00_0c) & RT_BIT(3))
+#define CODEC_F00_0C_IS_CAP_PRESENSE_DETECT(f00_0c)        ((f00_0c) & RT_BIT(2))
+#define CODEC_F00_0C_IS_CAP_TRIGGER_REQUIRED(f00_0c)       ((f00_0c) & RT_BIT(1))
+#define CODEC_F00_0C_IS_CAP_IMPENDANCE_SENSE(f00_0c)       ((f00_0c) & RT_BIT(0))
+
+/* Input Amplifier capabilities (7.3.4.10) */
 #define CODEC_MAKE_F00_0D(mute_cap, step_size, num_steps, offset) \
         (  (((mute_cap) & 0x1) << 31)                             \
@@ -171,8 +208,13 @@
          | ((offset) & 0xFF))
 
+/* Output Amplifier capabilities (7.3.4.10) */
+#define CODEC_MAKE_F00_12 CODEC_MAKE_F00_0D
+
 /* Connection list lenght (7.3.4.11) */
 #define CODEC_MAKE_F00_0E(long_form, length)    \
     (  (((long_form) & 0x1) << 7)               \
      | ((length) & 0x7F))
+#define CODEC_F00_0E_IS_LONG(f00_0e) RT_BOOL((f00_0e) & RT_BIT(7))
+#define CODEC_F00_0E_COUNT(f00_0e) ((f00_0e) & 0x7F)
 /* Supported Power States (7.3.4.12) */
 #define CODEC_F00_0F_EPSS       RT_BIT(31)
@@ -185,4 +227,9 @@
 #define CODEC_F00_0F_D0         RT_BIT(0)
 
+/* Processing capabilities 7.3.4.13 */
+#define CODEC_MAKE_F00_10(num, benign) ((((num) & 0xFF) << 8) | ((benign) & 0x1))
+#define CODEC_F00_10_NUM(f00_10) (((f00_10) & (0xFF << 8)) >> 8)
+#define CODEC_F00_10_BENING(f00_10) ((f00_10) & 0x1)
+
 /* CP/IO Count (7.3.4.14) */
 #define CODEC_MAKE_F00_11(wake, unsol, numgpi, numgpo, numgpio) \
@@ -193,4 +240,8 @@
      | ((numgpio) & 0xFF))
 
+/* Processing States (7.3.3.4) */
+#define CODEC_F03_OFF    (0)
+#define CODEC_F03_ON     RT_BIT(0)
+#define CODEC_F03_BENING RT_BIT(1)
 /* Power States (7.3.3.10) */
 #define CODEC_MAKE_F05(reset, stopok, error, act, set)          \
@@ -212,4 +263,7 @@
 #define CODEC_F05_SET(value)        (((value) & 0x7))
 
+#define CODEC_F05_GE(p0, p1) ((p0) <= (p1))
+#define CODEC_F05_LE(p0, p1) ((p0) >= (p1))
+
 /* Pin Widged Control (7.3.3.13) */
 #define CODEC_F07_VREF_HIZ      (0)
@@ -222,4 +276,7 @@
 #define CODEC_F07_OUT_H_ENABLE  RT_BIT(7)
 
+/* Unsolicited enabled (7.3.3.14) */
+#define CODEC_MAKE_F08(enable, tag) ((((enable) & 1) << 7) | ((tag) & 0x3F))
+
 /* Converter formats (7.3.3.8) and (3.7.1) */
 #define CODEC_MAKE_A(fNonPCM, f44_1BaseRate, mult, div, bits, chan) \
@@ -260,4 +317,8 @@
   | (((fELDValid) & 0x1) << 30))
 
+#define CODEC_MAKE_F0C(lrswap, eapd, btl) ((((lrswap) & 1) << 2) | (((eapd) & 1) << 1) | ((btl) & 1))
+#define CODEC_FOC_IS_LRSWAP(f0c)    RT_BOOL((f0c) & RT_BIT(2))
+#define CODEC_FOC_IS_EAPD(f0c)      RT_BOOL((f0c) & RT_BIT(1))
+#define CODEC_FOC_IS_BTL(f0c)       RT_BOOL((f0c) & RT_BIT(0))
 /* HDA spec 7.3.3.31 defines layout of configuration registers/verbs (0xF1C) */
 /* Configuration's port connection */
@@ -289,5 +350,5 @@
 #define CODEC_F1C_LOCATION_SPECIAL_0           (0x7)
 #define CODEC_F1C_LOCATION_SPECIAL_1           (0x8)
-#define CODEC_F1C_LOCATION_SPECIAL_3           (0x9)
+#define CODEC_F1C_LOCATION_SPECIAL_2           (0x9)
 
 /* Configuration's devices */
@@ -351,8 +412,8 @@
 #define CODEC_F1C_MISC_MASK                  (0xF)
 #define CODEC_F1C_MISC_SHIFT                 (8)
-#define CODEC_F1C_MISC_JACK_DETECT           RT_BIT(0)
-#define CODEC_F1C_MISC_RESERVED_0            RT_BIT(1)
-#define CODEC_F1C_MISC_RESERVED_1            RT_BIT(2)
-#define CODEC_F1C_MISC_RESERVED_2            RT_BIT(3)
+#define CODEC_F1C_MISC_JACK_DETECT           (0)
+#define CODEC_F1C_MISC_RESERVED_0            (1)
+#define CODEC_F1C_MISC_RESERVED_1            (2)
+#define CODEC_F1C_MISC_RESERVED_2            (3)
 
 /* Configuration's association */
@@ -382,4 +443,5 @@
 
 
+#ifndef VBOX_WITH_HDA_CODEC_EMU
 typedef struct CODECVERB
 {
@@ -389,9 +451,12 @@
     PFNCODECVERBPROCESSOR pfn;
 } CODECVERB;
-
-#ifndef VBOX_HDA_CODEC_EMU
+#endif
+
+#ifndef VBOX_WITH_HDA_CODEC_EMU
 # define TYPE union
 #else
 # define TYPE struct
+typedef struct CODECEMU CODECEMU;
+typedef CODECEMU *PCODECEMU;
 #endif
 TYPE CODECNODE;
@@ -408,9 +473,4 @@
 } ENMSOUNDSOURCE;
 
-typedef enum
-{
-    STAC9220_CODEC,
-    ALC885_CODEC
-} ENMCODEC;
 
 typedef struct CODECState
@@ -421,6 +481,10 @@
     uint8_t                 u8BSKU;
     uint8_t                 u8AssemblyId;
+#ifndef VBOX_WITH_HDA_CODEC_EMU
     CODECVERB               *pVerbs;
     int                     cVerbs;
+#else
+    PCODECEMU               pCodecBackend;
+#endif
     PCODECNODE               pNodes;
     QEMUSoundCard           card;
@@ -429,7 +493,7 @@
     /** PCM out */
     SWVoiceOut              *SwVoiceOut;
-    ENMCODEC                enmCodec;
     void                    *pHDAState;
     bool                    fInReset;
+#ifndef VBOX_WITH_HDA_CODEC_EMU
     const uint8_t           cTotalNodes;
     const uint8_t           *au8Ports;
@@ -448,13 +512,17 @@
     const uint8_t           u8AdcVolsLineIn;
     const uint8_t           u8DacLineOut;
+#endif
     DECLR3CALLBACKMEMBER(int, pfnProcess, (struct CODECState *));
+    DECLR3CALLBACKMEMBER(void, pfnTransfer, (struct CODECState *pState, ENMSOUNDSOURCE, int avail));
+    /* These callbacks are set by Codec implementation */
     DECLR3CALLBACKMEMBER(int, pfnLookup, (struct CODECState *pState, uint32_t verb, PPFNCODECVERBPROCESSOR));
     DECLR3CALLBACKMEMBER(int, pfnReset, (struct CODECState *pState));
-    DECLR3CALLBACKMEMBER(void, pfnTransfer, (struct CODECState *pState, ENMSOUNDSOURCE, int avail));
     DECLR3CALLBACKMEMBER(int, pfnCodecNodeReset, (struct CODECState *pState, uint8_t, PCODECNODE));
-
-} CODECState;
-
-int codecConstruct(PPDMDEVINS pDevIns, CODECState *pCodecState, ENMCODEC enmCodec);
+    /* These callbacks are set by codec implementation to answer debugger requests */
+    DECLR3CALLBACKMEMBER(void, pfnCodecDbgListNodes, (CODECState *pState, PCDBGFINFOHLP pHlp, const char *pszArgs));
+    DECLR3CALLBACKMEMBER(void, pfnCodecDbgSelector, (CODECState *pState, PCDBGFINFOHLP pHlp, const char *pszArgs));
+} CODECState, *PCODECState;
+
+int codecConstruct(PPDMDEVINS pDevIns, CODECState *pCodecState, PCFGMNODE pCfgHandle);
 int codecDestruct(CODECState *pCodecState);
 int codecSaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle);
@@ -462,3 +530,12 @@
 int codecOpenVoice(CODECState *pCodecState, ENMSOUNDSOURCE enmSoundSource, audsettings_t *pAudioSettings);
 
+# ifdef VBOX_WITH_HDA_CODEC_EMU
+/* */
+struct CODECEMU
+{
+    DECLR3CALLBACKMEMBER(int, pfnCodecEmuConstruct, (PCODECState pState));
+    DECLR3CALLBACKMEMBER(int, pfnCodecEmuDestruct, (PCODECState pState));
+    DECLR3CALLBACKMEMBER(int, pfnCodecEmuReset, (PCODECState pState, bool fInit));
+};
+# endif
 #endif
Index: /trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp	(revision 36690)
+++ /trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp	(revision 36691)
@@ -58,4 +58,5 @@
 static DECLCALLBACK(void)  hdaReset (PPDMDEVINS pDevIns);
 
+#define HDA_NREGS 112
 /* Registers */
 #define HDA_REG_IND_NAME(x) ICH6_HDA_REG_##x
@@ -263,4 +264,8 @@
 #define ICH6_HDA_SDCTL_NUM_MASK   (0xF)
 #define ICH6_HDA_SDCTL_NUM_SHIFT  (20)
+#define ICH6_HDA_SDCTL_DIR_SHIFT  (19)
+#define ICH6_HDA_SDCTL_TP_SHIFT   (18)
+#define ICH6_HDA_SDCTL_STRIPE_MASK  (0x3)
+#define ICH6_HDA_SDCTL_STRIPE_SHIFT (16)
 #define ICH6_HDA_SDCTL_DEIE_SHIFT (4)
 #define ICH6_HDA_SDCTL_FEIE_SHIFT (3)
@@ -373,4 +378,6 @@
 #define ICH6_HDA_SDFMT_DIV_SHIFT (8)
 #define ICH6_HDA_SDFMT_DIV_MASK (0x7)
+#define ICH6_HDA_SDFMT_BITS_SHIFT (4)
+#define ICH6_HDA_SDFMT_BITS_MASK (0x7)
 #define SDFMT_BASE_RATE(pState, num) ((SDFMT(pState, num) & HDA_REG_FIELD_FLAG_MASK(SDFMT, BASE_RATE)) >> HDA_REG_FIELD_SHIFT(SDFMT, BASE_RATE))
 #define SDFMT_MULT(pState, num) ((SDFMT((pState), num) & HDA_REG_FIELD_MASK(SDFMT,MULT)) >> HDA_REG_FIELD_SHIFT(SDFMT, MULT))
@@ -435,5 +442,5 @@
     PDMIBASE                IBase;
     RTGCPHYS    addrMMReg;
-    uint32_t     au32Regs[113];
+    uint32_t     au32Regs[HDA_NREGS];
     HDABDLEDESC  stInBdle;
     HDABDLEDESC  stOutBdle;
@@ -522,4 +529,5 @@
 #endif
 
+
 /* see 302349 p 6.2*/
 const static struct stIchIntelHDRegMap
@@ -541,5 +549,5 @@
     /** Full name. */
     const char *name;
-} s_ichIntelHDRegMap[] =
+} s_ichIntelHDRegMap[HDA_NREGS] =
 {
     /* offset  size     read mask   write mask         read callback         write callback         abbrev      full name                     */
@@ -1249,5 +1257,29 @@
     }
     pAudSetting->freq = u32Hz * u32HzMult / u32HzDiv;
-    pAudSetting->nchannels = 2;
+
+    switch (EXTRACT_VALUE(u32SdFmt, ICH6_HDA_SDFMT_BITS_MASK, ICH6_HDA_SDFMT_BITS_SHIFT))
+    {
+        case 0:
+            Log(("hda: %s requested 8 bit\n", __FUNCTION__));
+            pAudSetting->fmt = AUD_FMT_S8;
+        break;
+        case 1:
+            Log(("hda: %s requested 16 bit\n", __FUNCTION__));
+            pAudSetting->fmt = AUD_FMT_S16;
+        break;
+        case 2:
+            Log(("hda: %s requested 20 bit\n", __FUNCTION__));
+        break;
+        case 3:
+            Log(("hda: %s requested 24 bit\n", __FUNCTION__));
+        break;
+        case 4:
+            Log(("hda: %s requested 32 bit\n", __FUNCTION__));
+            pAudSetting->fmt = AUD_FMT_S32;
+        break;
+        default:
+            AssertMsgFailed(("Unsupported"));
+    }
+    pAudSetting->nchannels = (u32SdFmt & 0xf) + 1;
     pAudSetting->fmt = AUD_FMT_S16;
     pAudSetting->endianness = 0;
@@ -1257,24 +1289,28 @@
 DECLCALLBACK(int)hdaRegWriteSDFMT(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value)
 {
-#if 0
-        /* @todo here some more investigations are required. */
-        audsettings_t as;
-        /* no reason to reopen voice with same settings */
-        if (u32Value == HDA_REG_IND(pState, index))
-            return VINF_SUCCESS;
-        hdaSdFmtToAudSettings(u32Value, &as);
-        switch (index)
-        {
-            case ICH6_HDA_REG_SD0FMT:
-                codecOpenVoice(&pState->Codec, PI_INDEX, &as);
-                break;
-            case ICH6_HDA_REG_SD4FMT:
-                codecOpenVoice(&pState->Codec, PO_INDEX, &as);
-                break;
-            default:
-                AssertMsgFailed(("unimplemented"));
-        }
+#ifdef VBOX_WITH_HDA_CODEC_EMU
+    /* @todo here some more investigations are required. */
+    int rc = 0;
+    audsettings_t as;
+    /* no reason to reopen voice with same settings */
+    if (u32Value == HDA_REG_IND(pState, index))
+        return VINF_SUCCESS;
+    hdaSdFmtToAudSettings(u32Value, &as);
+    switch (index)
+    {
+        case ICH6_HDA_REG_SD0FMT:
+            rc = codecOpenVoice(&pState->Codec, PI_INDEX, &as);
+            break;
+        case ICH6_HDA_REG_SD4FMT:
+            rc = codecOpenVoice(&pState->Codec, PO_INDEX, &as);
+            break;
+        default:
+            Log(("HDA: attempt to change format on %d\n", index));
+            rc = 0;
+    }
+    return hdaRegWriteU16(pState, offset, index, u32Value);
+#else
+    return hdaRegWriteU16(pState, offset, index, u32Value);
 #endif
-        return hdaRegWriteU16(pState, offset, index, u32Value);
 }
 
@@ -2061,5 +2097,212 @@
 }
 
+static inline int hdaLookUpRegisterByName(INTELHDLinkState *pState, const char *pszArgs)
+{
+    int iReg = 0;
+    for (; iReg < HDA_NREGS; ++iReg)
+        if (!RTStrICmp(s_ichIntelHDRegMap[iReg].abbrev, pszArgs))
+            return iReg;
+    return -1;
+}
+static inline void hdaDbgPrintRegister(INTELHDLinkState *pState, PCDBGFINFOHLP pHlp, int iHdaIndex)
+{
+    Assert(   pState
+           && iHdaIndex >= 0
+           && iHdaIndex < HDA_NREGS);
+    pHlp->pfnPrintf(pHlp, "hda: %s: 0x%x\n", s_ichIntelHDRegMap[iHdaIndex].abbrev, pState->au32Regs[iHdaIndex]);
+}
+static DECLCALLBACK(void) hdaDbgInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
+    INTELHDLinkState *hda = &pThis->hda;
+    int iHdaRegisterIndex = hdaLookUpRegisterByName(hda, pszArgs);
+    if (iHdaRegisterIndex != -1)
+        hdaDbgPrintRegister(hda, pHlp, iHdaRegisterIndex);
+    else
+        for(iHdaRegisterIndex = 0; (unsigned int)iHdaRegisterIndex < HDA_NREGS; ++iHdaRegisterIndex)
+            hdaDbgPrintRegister(hda, pHlp, iHdaRegisterIndex);
+}
+
+static inline void hdaDbgPrintStream(INTELHDLinkState *pState, PCDBGFINFOHLP pHlp, int iHdaStrmIndex)
+{
+    Assert(   pState
+           && iHdaStrmIndex >= 0
+           && iHdaStrmIndex < 7);
+    pHlp->pfnPrintf(pHlp, "Dump of %d Hda Stream:\n", iHdaStrmIndex);
+    pHlp->pfnPrintf(pHlp, "SD%dCTL: %R[sdctl]\n", iHdaStrmIndex, HDA_STREAM_REG2(pState, CTL, iHdaStrmIndex));
+    pHlp->pfnPrintf(pHlp, "SD%dCTS: %R[sdsts]\n", iHdaStrmIndex, HDA_STREAM_REG2(pState, STS, iHdaStrmIndex));
+    pHlp->pfnPrintf(pHlp, "SD%dFIFOS: %R[sdfifos]\n", iHdaStrmIndex, HDA_STREAM_REG2(pState, FIFOS, iHdaStrmIndex));
+    pHlp->pfnPrintf(pHlp, "SD%dFIFOW: %R[sdfifow]\n", iHdaStrmIndex, HDA_STREAM_REG2(pState, FIFOW, iHdaStrmIndex));
+}
+
+static inline int hdaLookUpStreamIndex(INTELHDLinkState *pState, const char *pszArgs)
+{
+    /* todo: add args parsing */
+    return -1;
+}
+static DECLCALLBACK(void) hdaDbgStreamInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
+    INTELHDLinkState *hda = &pThis->hda;
+    int iHdaStrmIndex = hdaLookUpStreamIndex(hda, pszArgs);
+    if (iHdaStrmIndex != -1)
+        hdaDbgPrintStream(hda, pHlp, iHdaStrmIndex);
+    else
+        for(iHdaStrmIndex = 0; iHdaStrmIndex < 7; ++iHdaStrmIndex)
+            hdaDbgPrintStream(hda, pHlp, iHdaStrmIndex);
+}
+
+/* Codec debugger interface */
+static DECLCALLBACK(void) hdaCodecDbgNodes(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
+    INTELHDLinkState *hda = &pThis->hda;
+    if (hda->Codec.pfnCodecDbgListNodes)
+        hda->Codec.pfnCodecDbgListNodes(&hda->Codec, pHlp, pszArgs);
+    else
+        pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
+}
+
+static DECLCALLBACK(void) hdaCodecDbgSelector(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
+    INTELHDLinkState *hda = &pThis->hda;
+    if (hda->Codec.pfnCodecDbgSelector)
+        hda->Codec.pfnCodecDbgSelector(&hda->Codec, pHlp, pszArgs);
+    else
+        pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
+}
+
 //#define HDA_AS_PCI_EXPRESS
+/* Misc routines */
+static inline bool printHdaIsValid(const char *pszType, const char *pszExpectedFlag)
+{
+    return (RTStrCmp(pszType, pszExpectedFlag) == 0);
+}
+static const char *printHdaYesNo(bool fFlag)
+{
+    return fFlag ? "yes" : "no";
+}
+static DECLCALLBACK(size_t)
+printHdaStrmCtl(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                 const char *pszType, void const *pvValue,
+                 int cchWidth, int cchPrecision, unsigned fFlags,
+                 void *pvUser)
+{
+    uint32_t sdCtl = (uint32_t)(uintptr_t)pvValue;
+    size_t cb = 0;
+    if (!printHdaIsValid(pszType, "sdctl"))
+        return cb;
+    cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                      "SDCTL(raw: %#0x, strm:0x%x, dir:%s, tp:%s strip:%x, deie:%s, ioce:%s, run:%s, srst:%s)",
+                      sdCtl,
+                      ((sdCtl & HDA_REG_FIELD_MASK(SDCTL, NUM)) >> ICH6_HDA_SDCTL_NUM_SHIFT),
+                      printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, DIR))),
+                      printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, TP))),
+                      ((sdCtl & HDA_REG_FIELD_MASK(SDCTL, STRIPE)) >> ICH6_HDA_SDCTL_STRIPE_SHIFT),
+                      printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, DEIE))),
+                      printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE))),
+                      printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN))),
+                      printHdaYesNo(RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST))));
+    return cb;
+}
+
+static DECLCALLBACK(size_t)
+printHdaStrmFifos(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                 const char *pszType, void const *pvValue,
+                 int cchWidth, int cchPrecision, unsigned fFlags,
+                 void *pvUser)
+{
+    uint32_t sdFifos = (uint32_t)(uintptr_t)pvValue;
+    uint32_t u32Bytes = 0;
+    size_t cb = 0;
+    if (!printHdaIsValid(pszType, "sdfifos"))
+        return cb;
+    switch(sdFifos)
+    {
+        case HDA_SDONFIFO_16B: u32Bytes = 16; break;
+        case HDA_SDONFIFO_32B: u32Bytes = 32; break;
+        case HDA_SDONFIFO_64B: u32Bytes = 64; break;
+        case HDA_SDONFIFO_128B: u32Bytes = 128; break;
+        case HDA_SDONFIFO_192B: u32Bytes = 192; break;
+        case HDA_SDONFIFO_256B: u32Bytes = 256; break;
+        case HDA_SDINFIFO_120B: u32Bytes = 120; break;
+        case HDA_SDINFIFO_160B: u32Bytes = 160; break;
+        default:;
+    }
+    cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                      "SDFIFOS(raw: %#0x, sdfifos:%d B)",
+                      sdFifos,
+                      u32Bytes);
+    return cb;
+}
+
+static DECLCALLBACK(size_t)
+printHdaStrmFifow(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                 const char *pszType, void const *pvValue,
+                 int cchWidth, int cchPrecision, unsigned fFlags,
+                 void *pvUser)
+{
+    uint32_t sdFifow = (uint32_t)(uintptr_t)pvValue;
+    uint32_t u32Bytes = 0;
+    size_t cb = 0;
+    if (!printHdaIsValid(pszType, "sdfifow"))
+        return cb;
+    switch(sdFifow)
+    {
+        case HDA_SDFIFOW_8B: u32Bytes = 8; break;
+        case HDA_SDFIFOW_16B: u32Bytes = 16; break;
+        case HDA_SDFIFOW_32B: u32Bytes = 32; break;
+    }
+    cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                      "SDFIFOW(raw: %#0x, sdfifow:%d B)",
+                      sdFifow,
+                      u32Bytes);
+    return cb;
+}
+
+static DECLCALLBACK(size_t)
+printHdaStrmSts(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                 const char *pszType, void const *pvValue,
+                 int cchWidth, int cchPrecision, unsigned fFlags,
+                 void *pvUser)
+{
+    uint32_t sdSts = (uint32_t)(uintptr_t)pvValue;
+    size_t cb = 0;
+    if (!printHdaIsValid(pszType, "sdsts"))
+        return cb;
+    cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+                      "SDSTS(raw: %#0x, fifordy:%s, dese:%s, fifoe:%s, bcis:%s)",
+                      sdSts,
+                      printHdaYesNo(RT_BOOL(sdSts & HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY))),
+                      printHdaYesNo(RT_BOOL(sdSts & HDA_REG_FIELD_FLAG_MASK(SDSTS, DE))),
+                      printHdaYesNo(RT_BOOL(sdSts & HDA_REG_FIELD_FLAG_MASK(SDSTS, FE))),
+                      printHdaYesNo(RT_BOOL(sdSts & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))));
+    return cb;
+}
+/**
+ * This routine registers debugger info extensions and custom printf formatters
+ */
+static inline int hdaInitMisc(PPDMDEVINS pDevIns)
+{
+    int rc;
+    PDMDevHlpDBGFInfoRegister(pDevIns, "hda", "HDA info. (hda [register case-insensitive])", hdaDbgInfo);
+    PDMDevHlpDBGFInfoRegister(pDevIns, "hdastrm", "HDA stream info. (hdastrm [stream number])", hdaDbgStreamInfo);
+    PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes", "HDA codec nodes.", hdaCodecDbgNodes);
+    PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].", hdaCodecDbgSelector);
+    rc = RTStrFormatTypeRegister("sdctl", printHdaStrmCtl, NULL);
+    AssertRC(rc);
+    rc = RTStrFormatTypeRegister("sdsts", printHdaStrmSts, NULL);
+    AssertRC(rc);
+    rc = RTStrFormatTypeRegister("sdfifos", printHdaStrmFifos, NULL);
+    AssertRC(rc);
+    rc = RTStrFormatTypeRegister("sdfifow", printHdaStrmFifow, NULL);
+    AssertRC(rc);
+#if 0
+    rc = RTStrFormatTypeRegister("sdfmt", printHdaStrmFmt, NULL);
+    AssertRC(rc);
+#endif
+    return rc;
+}
 
 /**
@@ -2218,5 +2461,5 @@
 
     pThis->hda.Codec.pHDAState = (void *)&pThis->hda;
-    rc = codecConstruct(pDevIns, &pThis->hda.Codec, /* ALC885_CODEC */ STAC9220_CODEC);
+    rc = codecConstruct(pDevIns, &pThis->hda.Codec, pCfgHandle);
     if (RT_FAILURE(rc))
         AssertRCReturn(rc, rc);
@@ -2239,4 +2482,5 @@
     WAKEEN(&pThis->hda) = 0x0;
     STATESTS(&pThis->hda) = 0x0;
+    hdaInitMisc(pDevIns);
 
     return VINF_SUCCESS;
