Index: /trunk/src/VBox/Devices/Audio/DevCodec.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevCodec.cpp	(revision 31262)
+++ /trunk/src/VBox/Devices/Audio/DevCodec.cpp	(revision 31263)
@@ -91,5 +91,7 @@
     || CODEC_NID(cmd) == 0x13)
 
+#define STAC9220_IS_PCBEEP_CMD(cmd) (CODEC_NID((cmd)) == 0x14)
 #define STAC9220_IS_SPDIFOUT_CMD(cmd) (CODEC_NID((cmd)) == 0x8)
+#define STAC9220_IS_SPDIFIN_CMD(cmd) (CODEC_NID((cmd)) == 0x9)
 
 #define STAC9220_IS_DIGINPIN_CMD(cmd) (CODEC_NID((cmd)) == 0x11)
@@ -98,10 +100,9 @@
 #define STAC9220_IS_CD_CMD(cmd) (CODEC_NID((cmd)) == 0x15)
 
-#define STAC9220_IS_VOLKNOB_CMD(cmd) (CODEC_NID((cmd)) == 0x15)
+#define STAC9220_IS_VOLKNOB_CMD(cmd) (CODEC_NID((cmd)) == 0x16)
 
 /* STAC9220 6.2 & 6.12 */
 #define STAC9220_IS_RESERVED_CMD(cmd) ( \
-       CODEC_NID((cmd)) == 0x9          \
-    || CODEC_NID((cmd)) == 0x19         \
+    CODEC_NID((cmd)) == 0x19            \
     || CODEC_NID((cmd)) == 0x1A         \
     || CODEC_NID((cmd)) == 0x1B)
@@ -145,5 +146,10 @@
                             CODEC_B_SIDE(cmd),
                             CODEC_B_INDEX(cmd));
-    else {
+    else if (STAC9220_IS_PCBEEP_CMD(cmd))
+        *pResp = AMPLIFIER_REGISTER(pNode->pcbeep.B_params,
+                            CODEC_B_DIRECTION(cmd),
+                            CODEC_B_SIDE(cmd),
+                            CODEC_B_INDEX(cmd));
+    else{
         *pResp = 0;
         AssertMsgReturn(0, ("access to fields of %x need to be implemented\n", CODEC_NID(cmd)), VINF_SUCCESS);
@@ -173,4 +179,9 @@
             CODEC_B_SIDE(cmd),
             CODEC_B_INDEX(cmd));
+    else if (STAC9220_IS_PCBEEP_CMD(cmd))
+        pu32Bparam = &AMPLIFIER_REGISTER(pNode->pcbeep.B_params,
+            CODEC_B_DIRECTION(cmd),
+            CODEC_B_SIDE(cmd),
+            CODEC_B_INDEX(cmd));
     Assert(pu32Bparam);
     if (pu32Bparam)
@@ -194,9 +205,9 @@
 {
     Assert((CODEC_CAD(cmd) == pState->id));
+    *pResp = 0;
     if (STAC9220_IS_ADCMUX_CMD(cmd))
         *pResp = pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
     else if (STAC9220_IS_DIGOUTPIN_CMD(cmd))
-        //** @todo r=michaln: Is that really u32F07, or should it be u32F01?
-        *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param;
+        *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param;
     //** @todo r=michaln: Else what? We must always fill out *pResp!
     return VINF_SUCCESS;
@@ -362,4 +373,6 @@
     if (STAC9220_IS_SPDIFOUT_CMD(cmd))
         *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param;
+    else if (STAC9220_IS_SPDIFIN_CMD(cmd))
+        *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param;
     return VINF_SUCCESS;
 }
@@ -373,4 +386,9 @@
         pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param |= cmd & CODEC_VERB_8BIT_DATA;
     }
+    else if (STAC9220_IS_SPDIFIN_CMD(cmd))
+    {
+        pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param &= ~CODEC_VERB_8BIT_DATA;
+        pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param |= cmd & CODEC_VERB_8BIT_DATA;
+    }
     *pResp = 0;
     return VINF_SUCCESS;
@@ -384,4 +402,9 @@
         pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param &= ~(CODEC_VERB_8BIT_DATA << 8);
         pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param |= cmd & (CODEC_VERB_8BIT_DATA << 8);
+    }
+    else if (STAC9220_IS_SPDIFIN_CMD(cmd))
+    {
+        pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param &= ~(CODEC_VERB_8BIT_DATA << 8);
+        pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param |= cmd & (CODEC_VERB_8BIT_DATA << 8);
     }
     *pResp = 0;
@@ -453,5 +476,6 @@
         return VINF_SUCCESS;
     *pu32Reg &= ~CODEC_VERB_8BIT_DATA;
-    *pu32Reg |= cmd & CODEC_VERB_8BIT_DATA;
+    *pu32Reg |= cmd & CODEC_VERB_4BIT_DATA;
+    *pu32Reg |= (cmd & CODEC_VERB_4BIT_DATA) << 4;
     return VINF_SUCCESS;
 }
@@ -473,17 +497,18 @@
 {
     Assert((CODEC_CAD(cmd) == pState->id));
+    uint32_t *pu32addr = NULL;
+    *pResp = 0;
     if (STAC9220_IS_DAC_CMD(cmd))
-    {
-        pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param &= ~CODEC_VERB_8BIT_DATA;
-        pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param |= cmd & CODEC_VERB_8BIT_DATA;
-    }
+        pu32addr = &pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param;
     else if (STAC9220_IS_ADC_CMD(cmd))
-    {
-        pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param &= ~CODEC_VERB_8BIT_DATA;
-        pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param |= cmd & CODEC_VERB_8BIT_DATA;
-    }
-    else
-        AssertMsgFailed(("Unsupported"));
-    *pResp = 0;
+        pu32addr = &pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param;
+    else if (STAC9220_IS_SPDIFOUT_CMD(cmd))
+        pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
+    Assert((pu32addr));
+    if (pu32addr)
+    {
+        *pu32addr &= ~CODEC_VERB_8BIT_DATA;
+        *pu32addr |= cmd & CODEC_VERB_8BIT_DATA;
+    }
     return VINF_SUCCESS;
 }
@@ -497,4 +522,6 @@
     else if (STAC9220_IS_SPDIFOUT_CMD(cmd))
         *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param;
+    else if (STAC9220_IS_SPDIFIN_CMD(cmd))
+        *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param;
     else
         *pResp = 0;
@@ -520,4 +547,9 @@
         pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param |= cmd & CODEC_VERB_16BIT_DATA;
     }
+    else if (STAC9220_IS_SPDIFIN_CMD(cmd))
+    {
+        pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param &= ~CODEC_VERB_16BIT_DATA;
+        pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param |= cmd & CODEC_VERB_16BIT_DATA;
+    }
     *pResp = 0;
     return VINF_SUCCESS;
@@ -528,4 +560,5 @@
 {
     Assert((CODEC_CAD(cmd) == pState->id));
+    *pResp = 0;
     if (STAC9220_IS_ADCVOL_CMD(cmd))
         *pResp = pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
@@ -534,6 +567,4 @@
     else if (STAC9220_IS_DIGINPIN_CMD(cmd))
         *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param;
-    //** @todo r=michaln: Do we really always want to return zero?
-    *pResp = 0;
     return VINF_SUCCESS;
 }
@@ -665,10 +696,10 @@
             // code much harder to read, not easier.
             pNode->node.au32F00_param[0] = RT_MAKE_U32_FROM_U8(0x80, 0x76, 0x84, 0x83); /* VendorID = STAC9220/ DevId = 0x7680 */
-            pNode->node.au32F00_param[2] = RT_MAKE_U32_FROM_U8(0x1, 0x31, 0x10, 0x00); /* rev id */
+            pNode->node.au32F00_param[2] = RT_MAKE_U32_FROM_U8(0x1, 0x34, 0x10, 0x00); /* rev id */
             pNode->node.au32F00_param[4] = RT_MAKE_U32_FROM_U8(0x1, 0x00, 0x01, 0x00); /* node info (start node: 1, start id = 1) */
             break;
         case 1:
             pNode->afg.node.name = "AFG";
-            pNode->node.au32F00_param[4] = RT_MAKE_U32_FROM_U8(0x1a, 0x00, 0x02, 0x00);
+            pNode->node.au32F00_param[4] = 2 << 16 | 0x17; /* starting node - 2; total numbers of nodes  0x17 */
             pNode->node.au32F00_param[5] = RT_BIT(8)|RT_BIT(0);
             pNode->node.au32F00_param[8] = RT_MAKE_U32_FROM_U8(0x0d, 0x0d, 0x01, 0x0); /* Capabilities */
@@ -680,7 +711,8 @@
             pNode->node.au32F00_param[0x12] = RT_BIT(31)|(0x2 << 16)|(0x7f << 8)|0x7f;
             pNode->node.au32F00_param[0x11] = 0;
-            pNode->afg.u32F05_param = 0x3 << 4; /* PS-Act: D3 -> D0 */
+            pNode->node.au32F00_param[0xF] = RT_BIT(30)|RT_BIT(3)|RT_BIT(0); /* Power statest Supported: D0-yes, D1, D2, D3-no*/
+            pNode->afg.u32F05_param = 0x3 << 4| 0x3; /* PS-Act: D3, PS->Set D3  */
             pNode->afg.u32F20_param = 0x83847882;
-            pNode->afg.u32F08_param = RT_BIT(7);
+            pNode->afg.u32F08_param = 0;
             break;
         case 2:
@@ -697,5 +729,5 @@
         dac_init:
             memset(pNode->dac.B_params, 0, AMPLIFIER_SIZE);
-            pNode->dac.u32A_param = RT_BIT(14)|(0x1 << 3)|0x2; /* 441000Hz/16bit/2ch */
+            pNode->dac.u32A_param = RT_BIT(14)|(0x1 << 4)|0x2; /* 441000Hz/16bit/2ch */
 
             AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) = 0x7F | RT_BIT(7);
@@ -705,5 +737,5 @@
             pNode->dac.node.au32F00_param[5] = (0x3 << 4) | 0x3;
             pNode->dac.u32F0c_param = 0;
-            pNode->dac.u32F05_param = 0x3 << 4; /* PS-Act: D3 -> D0 */
+            pNode->dac.u32F05_param = 0x3 << 4 | 0x3; /* PS-Act: D3, Set: D3  */
         break;
         case 6:
@@ -718,5 +750,5 @@
             pNode->adc.node.au32F00_param[0xE] = RT_BIT(0);
             pNode->adc.u32F03_param = RT_BIT(0);
-            pNode->adc.u32F05_param = 0x3 << 4; /* PS-Act: D3 -> D0 */
+            pNode->adc.u32F05_param = 0x3 << 4 | 0x3; /* PS-Act: D3 Set: D3 */
             pNode->adc.u32F06_param = 0;
             pNode->adc.node.au32F00_param[9] = RT_BIT(20)| (0xd << 16) |  RT_BIT(10) | RT_BIT(8) | RT_BIT(6)| RT_BIT(0);
@@ -724,21 +756,27 @@
         case 8:
             pNode->spdifout.node.name = "SPDIFOut";
-            pNode->spdifout.u32A_param = (0x3<<4) | 0x1;
+            pNode->spdifout.u32A_param = (1<<14)|(0x1<<4) | 0x1;
             pNode->spdifout.node.au32F00_param[9] = (4 << 16) | RT_BIT(9)|RT_BIT(4)|0x1;
-            //pNode->spdifout.node.au32F00_param[0xA] = RT_BIT(19)|RT_BIT(18)|RT_BIT(17)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(7)|RT_BIT(6);
             pNode->node.au32F00_param[0xa] = RT_BIT(17)|RT_BIT(5);
             pNode->spdifout.node.au32F00_param[0xB] = RT_BIT(2)|RT_BIT(0);
             pNode->spdifout.u32F06_param = 0;
             pNode->spdifout.u32F0d_param = 0;
+            //pNode->spdifout.node.au32F00_param[0xA] = RT_BIT(19)|RT_BIT(18)|RT_BIT(17)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(7)|RT_BIT(6);
         break;
         case 9:
             pNode->node.name = "Reserved_0";
+            pNode->spdifin.u32A_param = (0x1<<4) | 0x1;
+            pNode->spdifin.node.au32F00_param[9] = (0x1 << 20)|(4 << 16) | RT_BIT(9)|RT_BIT(4)|0x1;
+            pNode->node.au32F00_param[0xa] = RT_BIT(17)|RT_BIT(5);
+            pNode->spdifin.node.au32F00_param[0xB] = RT_BIT(2)|RT_BIT(0);
+            pNode->spdifin.u32F06_param = 0;
+            pNode->spdifin.u32F0d_param = 0;
         break;
         case 0xA:
             pNode->node.name = "PortA";
-            pNode->node.au32F00_param[0xC] = 0x173d;
+            pNode->node.au32F00_param[0xC] = 0x173f;
             *(uint32_t *)pNode->node.au8F02_param = 0x2;
             pNode->port.u32F07_param = RT_BIT(6);
-            pNode->port.u32F08_param = RT_BIT(7);
+            pNode->port.u32F08_param = 0;
             pNode->port.u32F09_param = RT_BIT(31)|RT_BIT(30); /* 39.2 kOm */
             pNode->port.u32F1c_param = RT_MAKE_U32_FROM_U8(0x20, 0x40, 0x21, 0x02);
@@ -763,4 +801,5 @@
             pNode->node.name = "PortD";
             pNode->port.u32F09_param = 0;
+            pNode->node.au32F00_param[0xC] = 0x173f;
             *(uint32_t *)pNode->node.au8F02_param = 0x2;
         port_init:
@@ -791,9 +830,10 @@
         case 0x10:
             pNode->node.name = "DigOut_0";
-            pNode->node.au32F00_param[9] = RT_BIT(9)|RT_BIT(8)|RT_BIT(0);
+            pNode->node.au32F00_param[9] = (4<<20)|RT_BIT(9)|RT_BIT(8)|RT_BIT(0);
             pNode->node.au32F00_param[0xC] = RT_BIT(4);
-            pNode->node.au32F00_param[0xE] = 0x3;
+            pNode->node.au32F00_param[0xE] = 0x2;
             pNode->digout.u32F01_param = 0;
-            *(uint32_t *)pNode->node.au8F02_param = RT_MAKE_U32_FROM_U8(0x08, 0x17, 0x19, 0);
+            /* STAC9220 spec defines default connection list containing reserved nodes, that confuses some drivers. */
+            *(uint32_t *)pNode->node.au8F02_param = RT_MAKE_U32_FROM_U8(0x08, 0x17, 0x0, 0);
             pNode->digout.u32F07_param = 0;
             pNode->digout.u32F1c_param = RT_MAKE_U32_FROM_U8(0x30, 0x10, 0x45, 0x01);
@@ -803,5 +843,5 @@
             pNode->node.au32F00_param[9] = (4 << 20)|(3<<16)|RT_BIT(10)|RT_BIT(9)|RT_BIT(7)|RT_BIT(0);
             pNode->node.au32F00_param[0xC] = /* RT_BIT(16)|*/ RT_BIT(5)|RT_BIT(2);
-            pNode->digin.u32F05_param = 0x3 << 4; /* PS-Act: D3 -> D0 */
+            pNode->digin.u32F05_param = 0x3 << 4 | 0x3; /* PS-Act: D3 -> D3 */
             pNode->digin.u32F07_param = 0;
             pNode->digin.u32F08_param = 0;
@@ -861,6 +901,6 @@
             pNode->node.au32F00_param[0x9] = (0x3 << 20)|RT_BIT(11)|RT_BIT(8)|RT_BIT(1)|RT_BIT(0);
             pNode->node.au32F00_param[0xe] = 0x1;
-            AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_LEFT, 0) = RT_BIT(1);
-            AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_RIGHT, 0) = RT_BIT(1);
+            AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_LEFT, 0) = RT_BIT(7);
+            AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_RIGHT, 0) = RT_BIT(7);
             pNode->adcvol.u32F0c_param = 0;
         default:
Index: /trunk/src/VBox/Devices/Audio/DevCodec.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevCodec.h	(revision 31262)
+++ /trunk/src/VBox/Devices/Audio/DevCodec.h	(revision 31263)
@@ -94,4 +94,15 @@
 } SPDIFOUTNODE, *PSPDIFOUTNODE;
 
+typedef struct SPDIFINNODE
+{
+    CODECCOMMONNODE node;
+    uint32_t    u32F06_param;
+    uint32_t    u32F09_param;
+    uint32_t    u32F0d_param;
+
+    uint32_t    u32A_param;
+    AMPLIFIER   B_params;
+} SPDIFINNODE, *PSPDIFINNODE;
+
 typedef struct AFGCODECNODE
 {
@@ -180,4 +191,5 @@
     ADCNODE         adc;
     SPDIFOUTNODE    spdifout;
+    SPDIFINNODE     spdifin;
     PORTNODE        port;
     DIGOUTNODE      digout;
Index: /trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp	(revision 31262)
+++ /trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp	(revision 31263)
@@ -1280,9 +1280,9 @@
     }
     Assert(   index != -1
-           && u32Offset == s_ichIntelHDRegMap[index].offset
            && cb <= 4);
     if (index != -1)
     {
         uint32_t mask = 0;
+        uint32_t shift = (u32Offset - s_ichIntelHDRegMap[index].offset) % sizeof(uint32_t) * 8;
         uint32_t v = 0;
         switch(cb)
@@ -1293,7 +1293,7 @@
             case 4: mask = 0xffffffff; break;
         }
-        Assert(u32Offset == s_ichIntelHDRegMap[index].offset);
+        mask <<= shift;
         rc = s_ichIntelHDRegMap[index].pfnRead(&pThis->hda, u32Offset, index, &v);
-        *(uint32_t *)pv = v & mask;
+        *(uint32_t *)pv = (v & mask) >> shift;
         Log(("hda: read %s[%x/%x]\n", s_ichIntelHDRegMap[index].abbrev, v, *(uint32_t *)pv));
         return rc;
@@ -1504,5 +1504,5 @@
     PCIDevSetRevisionId         (&pThis->dev, 0x01);   /* 08 ro - rid. */
     PCIDevSetClassProg          (&pThis->dev, 0x00);   /* 09 ro - pi. */
-    PCIDevSetClassSub           (&pThis->dev, 0x02);   /* 0a ro - scc; 02 == HDA. */
+    PCIDevSetClassSub           (&pThis->dev, 0x03);   /* 0a ro - scc; 03 == HDA. */
     PCIDevSetClassBase          (&pThis->dev, 0x04);   /* 0b ro - bcc; 04 == multimedia. */
     PCIDevSetHeaderType         (&pThis->dev, 0x00);   /* 0e ro - headtyp. */
