VirtualBox

Changeset 32804 in vbox


Ignore:
Timestamp:
Sep 29, 2010 5:39:06 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
66254
Message:

Audio/HDA: more general and re-groupping.

Location:
trunk/src/VBox/Devices/Audio
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevCodec.cpp

    r32803 r32804  
    7474#define CODEC_SET_AMP_INDEX(cmd)             (((cmd) & CODEC_VERB_SET_AMP_INDEX) >> 7)
    7575
     76/* STAC9220 */
    7677const static uint8_t au8Stac9220Ports[] = { 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0};
    7778const static uint8_t au8Stac9220Dacs[] = { 0x2, 0x3, 0x4, 0x5, 0};
     
    8889const static uint8_t au8Stac9220Reserveds[] = { 0x9, 0x19, 0x1a, 0x1b, 0 };
    8990
    90 #define CODEC_POWER_MASK        0x3
    91 #define CODEC_POWER_ACT_SHIFT   (4)
    92 #define CODEC_POWER_SET_SHIFT   (0)
    93 #define CODEC_POWER_D0          (0)
    94 #define CODEC_POWER_D1          (1)
    95 #define CODEC_POWER_D2          (2)
    96 #define CODEC_POWER_D3          (3)
    97 #define CODEC_POWER_PROPOGATE_STATE(node)                                                           \
    98     do {                                                                                            \
    99         node.u32F05_param &= (CODEC_POWER_MASK);                                                    \
    100         node.u32F05_param |= (node.u32F05_param & CODEC_POWER_MASK) << CODEC_POWER_ACT_SHIFT;     \
    101     }while(0)
    102 
    103 #define DECLISNODEOFTYPE(type)                                                                  \
    104     static inline int codecIs##type##Node(struct CODECState *pState, uint8_t cNode)             \
    105     {                                                                                           \
    106         Assert(pState->au8##type##s);                                                           \
    107         for(int i = 0; pState->au8##type##s[i] != 0; ++i)                                       \
    108             if (pState->au8##type##s[i] == cNode)                                               \
    109                 return 1;                                                                       \
    110         return 0;                                                                               \
    111     }
    112 /* codecIsPortNode */
    113 DECLISNODEOFTYPE(Port)
    114 /* codecIsDacNode */
    115 DECLISNODEOFTYPE(Dac)
    116 /* codecIsAdcVolNode */
    117 DECLISNODEOFTYPE(AdcVol)
    118 /* codecIsAdcNode */
    119 DECLISNODEOFTYPE(Adc)
    120 /* codecIsAdcMuxNode */
    121 DECLISNODEOFTYPE(AdcMux)
    122 /* codecIsPcbeepNode */
    123 DECLISNODEOFTYPE(Pcbeep)
    124 /* codecIsSpdifOutNode */
    125 DECLISNODEOFTYPE(SpdifOut)
    126 /* codecIsSpdifInNode */
    127 DECLISNODEOFTYPE(SpdifIn)
    128 /* codecIsDigInPinNode */
    129 DECLISNODEOFTYPE(DigInPin)
    130 /* codecIsDigOutPinNode */
    131 DECLISNODEOFTYPE(DigOutPin)
    132 /* codecIsCdNode */
    133 DECLISNODEOFTYPE(Cd)
    134 /* codecIsVolKnobNode */
    135 DECLISNODEOFTYPE(VolKnob)
    136 /* codecIsReservedNode */
    137 DECLISNODEOFTYPE(Reserved)
    138 
    13991static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode);
    140 static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt);
    141 
    142 static inline void codecSetRegister(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset, uint32_t mask)
    143 {
    144         Assert((pu32Reg && u8Offset < 32));
    145         *pu32Reg &= ~(mask << u8Offset);
    146         *pu32Reg |= (u32Cmd & mask) << u8Offset;
    147 }
    148 static inline void codecSetRegisterU8(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset)
    149 {
    150     codecSetRegister(pu32Reg, u32Cmd, u8Offset, CODEC_VERB_8BIT_DATA);
    151 }
    152 
    153 static inline void codecSetRegisterU16(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset)
    154 {
    155     codecSetRegister(pu32Reg, u32Cmd, u8Offset, CODEC_VERB_16BIT_DATA);
    156 }
    157 
    158 
    159 static int codecUnimplemented(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    160 {
    161     Log(("codecUnimplemented: cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd,
    162         CODEC_CAD(cmd), CODEC_DIRECT(cmd) ? 'N' : 'Y', CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
    163     *pResp = 0;
    164     return VINF_SUCCESS;
    165 }
    166 
    167 static int codecBreak(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    168 {
    169     int rc;
    170     rc = codecUnimplemented(pState, cmd, pResp);
    171     *pResp |= CODEC_RESPONSE_UNSOLICITED;
    172     return rc;
    173 }
    174 /* B-- */
    175 static int codecGetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    176 {
    177     Assert((CODEC_CAD(cmd) == pState->id));
    178     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    179     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    180     {
    181         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    182         return VINF_SUCCESS;
    183     }
    184     *pResp = 0;
    185     /* HDA spec 7.3.3.7 Note A */
    186     /* @todo: if index out of range response should be 0 */
    187     uint8_t u8Index = CODEC_GET_AMP_DIRECTION(cmd) == AMPLIFIER_OUT? 0 : CODEC_GET_AMP_INDEX(cmd);
    188 
    189     PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)];
    190     if (codecIsDacNode(pState, CODEC_NID(cmd)))
    191         *pResp = AMPLIFIER_REGISTER(pNode->dac.B_params,
    192                             CODEC_GET_AMP_DIRECTION(cmd),
    193                             CODEC_GET_AMP_SIDE(cmd),
    194                             u8Index);
    195     else if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
    196         *pResp = AMPLIFIER_REGISTER(pNode->adcvol.B_params,
    197                             CODEC_GET_AMP_DIRECTION(cmd),
    198                             CODEC_GET_AMP_SIDE(cmd),
    199                             u8Index);
    200     else if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
    201         *pResp = AMPLIFIER_REGISTER(pNode->adcmux.B_params,
    202                             CODEC_GET_AMP_DIRECTION(cmd),
    203                             CODEC_GET_AMP_SIDE(cmd),
    204                             u8Index);
    205     else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
    206         *pResp = AMPLIFIER_REGISTER(pNode->pcbeep.B_params,
    207                             CODEC_GET_AMP_DIRECTION(cmd),
    208                             CODEC_GET_AMP_SIDE(cmd),
    209                             u8Index);
    210     else{
    211         AssertMsgReturn(0, ("access to fields of %x need to be implemented\n", CODEC_NID(cmd)), VINF_SUCCESS);
    212     }
    213     return VINF_SUCCESS;
    214 }
    215 /* 3-- */
    216 static int codecSetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    217 {
    218     AMPLIFIER *pAmplifier = NULL;
    219     bool fIsLeft = false;
    220     bool fIsRight = false;
    221     bool fIsOut = false;
    222     bool fIsIn = false;
    223     uint8_t u8Index = 0;
    224     Assert((CODEC_CAD(cmd) == pState->id));
    225     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    226     {
    227         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    228         return VINF_SUCCESS;
    229     }
    230     *pResp = 0;
    231     PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)];
    232     if (codecIsDacNode(pState, CODEC_NID(cmd)))
    233         pAmplifier = &pNode->dac.B_params;
    234     else if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
    235         pAmplifier = &pNode->adcvol.B_params;
    236     else if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
    237         pAmplifier = &pNode->adcmux.B_params;
    238     else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
    239         pAmplifier = &pNode->pcbeep.B_params;
    240     Assert(pAmplifier);
    241     if (pAmplifier)
    242     {
    243         fIsOut = CODEC_SET_AMP_IS_OUT_DIRECTION(cmd);
    244         fIsIn = CODEC_SET_AMP_IS_IN_DIRECTION(cmd);
    245         fIsRight = CODEC_SET_AMP_IS_RIGHT_SIDE(cmd);
    246         fIsLeft = CODEC_SET_AMP_IS_LEFT_SIDE(cmd);
    247         u8Index = CODEC_SET_AMP_INDEX(cmd);
    248         if (   (!fIsLeft && !fIsRight)
    249             || (!fIsOut && !fIsIn))
    250             return VINF_SUCCESS;
    251         if (fIsIn)
    252         {
    253             if (fIsLeft)
    254                 codecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_LEFT, u8Index), cmd, 0);
    255             if (fIsRight)
    256                 codecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0);
    257         }
    258         if (fIsOut)
    259         {
    260             if (fIsLeft)
    261                 codecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_LEFT, u8Index), cmd, 0);
    262             if (fIsRight)
    263                 codecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_RIGHT, u8Index), cmd, 0);
    264         }
    265         if (CODEC_NID(cmd) == 2)
    266             codecToAudVolume(pAmplifier, AUD_MIXER_VOLUME);
    267         if (CODEC_NID(cmd) == 0x17) /* Microphone */
    268             codecToAudVolume(pAmplifier, AUD_MIXER_LINE_IN);
    269     }
    270     return VINF_SUCCESS;
    271 }
    272 
    273 static int codecGetParameter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    274 {
    275     Assert((CODEC_CAD(cmd) == pState->id));
    276     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    277     {
    278         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    279         return VINF_SUCCESS;
    280     }
    281     Assert(((cmd & CODEC_VERB_8BIT_DATA) < CODECNODE_F0_PARAM_LENGTH));
    282     if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F0_PARAM_LENGTH)
    283     {
    284         Log(("HDAcodec: invalid F00 parameter %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
    285         return VINF_SUCCESS;
    286     }
    287     *pResp = 0;
    288     *pResp = pState->pNodes[CODEC_NID(cmd)].node.au32F00_param[cmd & CODEC_VERB_8BIT_DATA];
    289     return VINF_SUCCESS;
    290 }
    291 
    292 /* F01 */
    293 static int codecGetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    294 {
    295     Assert((CODEC_CAD(cmd) == pState->id));
    296     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    297     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    298     {
    299         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    300         return VINF_SUCCESS;
    301     }
    302     *pResp = 0;
    303     if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
    304         *pResp = pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
    305     else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
    306         *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param;
    307     return VINF_SUCCESS;
    308 }
    309 
    310 /* 701 */
    311 static int codecSetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    312 {
    313     uint32_t *pu32Reg = NULL;
    314     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    315     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    316     {
    317         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    318         return VINF_SUCCESS;
    319     }
    320     *pResp = 0;
    321     if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
    322         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
    323     else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
    324         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param;
    325     Assert((pu32Reg));
    326     if (pu32Reg)
    327         codecSetRegisterU8(pu32Reg, cmd, 0);
    328     return VINF_SUCCESS;
    329 }
    330 
    331 /* F07 */
    332 static int codecGetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    333 {
    334     Assert((CODEC_CAD(cmd) == pState->id));
    335     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    336     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    337     {
    338         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    339         return VINF_SUCCESS;
    340     }
    341     *pResp = 0;
    342     if (codecIsPortNode(pState, CODEC_NID(cmd)))
    343         *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F07_param;
    344     else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
    345         *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param;
    346     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    347         *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param;
    348     else if (codecIsCdNode(pState, CODEC_NID(cmd)))
    349         *pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
    350     else if (   codecIsReservedNode(pState, CODEC_NID(cmd))
    351              && CODEC_NID(cmd) == 0x1b)
    352         *pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param;
    353     else
    354         AssertMsgFailed(("Unsupported"));
    355     return VINF_SUCCESS;
    356 }
    357 
    358 /* 707 */
    359 static int codecSetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    360 {
    361     Assert((CODEC_CAD(cmd) == pState->id));
    362     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    363     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    364     {
    365         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    366         return VINF_SUCCESS;
    367     }
    368     *pResp = 0;
    369     uint32_t *pu32Reg = NULL;
    370     if (codecIsPortNode(pState, CODEC_NID(cmd)))
    371         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F07_param;
    372     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    373         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param;
    374     else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
    375         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param;
    376     else if (codecIsCdNode(pState, CODEC_NID(cmd)))
    377         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
    378     else if (   codecIsReservedNode(pState, CODEC_NID(cmd))
    379              && CODEC_NID(cmd) == 0x1b)
    380         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param;
    381     Assert((pu32Reg));
    382     if (pu32Reg)
    383         codecSetRegisterU8(pu32Reg, cmd, 0);
    384     return VINF_SUCCESS;
    385 }
    386 
    387 /* F08 */
    388 static int codecGetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    389 {
    390     Assert((CODEC_CAD(cmd) == pState->id));
    391     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    392     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    393     {
    394         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    395         return VINF_SUCCESS;
    396     }
    397     *pResp = 0;
    398     if (codecIsPortNode(pState, CODEC_NID(cmd)))
    399         *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
    400     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    401         *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
    402     else if ((cmd) == 1 /* AFG */)
    403         *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param;
    404     else if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
    405         *pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
    406     else
    407         AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
    408     return VINF_SUCCESS;
    409 }
    410 
    411 /* 708 */
    412 static int codecSetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    413 {
    414     Assert((CODEC_CAD(cmd) == pState->id));
    415     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    416     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    417     {
    418         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    419         return VINF_SUCCESS;
    420     }
    421     *pResp = 0;
    422     uint32_t *pu32Reg = NULL;
    423     if (codecIsPortNode(pState, CODEC_NID(cmd)))
    424         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
    425     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    426         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
    427     else if (CODEC_NID(cmd) == 1 /* AFG */)
    428         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param;
    429     else if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
    430         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
    431     else
    432         AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
    433     Assert(pu32Reg);
    434     if(pu32Reg)
    435         codecSetRegisterU8(pu32Reg, cmd, 0);
    436     return VINF_SUCCESS;
    437 }
    438 
    439 /* F09 */
    440 static int codecGetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    441 {
    442     Assert((CODEC_CAD(cmd) == pState->id));
    443     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    444     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    445     {
    446         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    447         return VINF_SUCCESS;
    448     }
    449     *pResp = 0;
    450     if (codecIsPortNode(pState, CODEC_NID(cmd)))
    451         *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F09_param;
    452     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    453         *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F09_param;
    454     else
    455         AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
    456     return VINF_SUCCESS;
    457 }
    458 
    459 /* 709 */
    460 static int codecSetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    461 {
    462     Assert((CODEC_CAD(cmd) == pState->id));
    463     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    464     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    465     {
    466         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    467         return VINF_SUCCESS;
    468     }
    469     *pResp = 0;
    470     uint32_t *pu32Reg = NULL;
    471     //** @todo r=michaln: Copy/paste bug? This can't be F08_parm!
    472     if (codecIsPortNode(pState, CODEC_NID(cmd)))
    473         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
    474     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    475         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
    476     Assert(pu32Reg);
    477     if(pu32Reg)
    478         codecSetRegisterU8(pu32Reg, cmd, 0);
    479     return VINF_SUCCESS;
    480 }
    481 
    482 static int codecGetConnectionListEntry(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    483 {
    484     Assert((CODEC_CAD(cmd) == pState->id));
    485     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    486     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    487     {
    488         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    489         return VINF_SUCCESS;
    490     }
    491     Assert((cmd & CODEC_VERB_8BIT_DATA) < 16);
    492     if ((cmd & CODEC_VERB_8BIT_DATA) >= 16)
    493     {
    494         Log(("HDAcodec: access to invalid F02 index %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
    495     }
    496     *pResp = *(uint32_t *)&pState->pNodes[CODEC_NID(cmd)].node.au8F02_param[cmd & CODEC_VERB_8BIT_DATA];
    497     return VINF_SUCCESS;
    498 }
    499 /* F03 */
    500 static int codecGetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    501 {
    502     Assert((CODEC_CAD(cmd) == pState->id));
    503     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    504     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    505     {
    506         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    507         return VINF_SUCCESS;
    508     }
    509     *pResp = 0;
    510     if (codecIsAdcNode(pState, CODEC_NID(cmd)))
    511         *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param;
    512     return VINF_SUCCESS;
    513 }
    514 
    515 /* 703 */
    516 static int codecSetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    517 {
    518     Assert((CODEC_CAD(cmd) == pState->id));
    519     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    520     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    521     {
    522         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    523         return VINF_SUCCESS;
    524     }
    525     *pResp = 0;
    526     if (codecIsAdcNode(pState, CODEC_NID(cmd)))
    527     {
    528         codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param, cmd, 0);
    529     }
    530     return VINF_SUCCESS;
    531 }
    532 
    533 /* F0D */
    534 static int codecGetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    535 {
    536     Assert((CODEC_CAD(cmd) == pState->id));
    537     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    538     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    539     {
    540         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    541         return VINF_SUCCESS;
    542     }
    543     *pResp = 0;
    544     if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
    545         *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param;
    546     else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
    547         *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param;
    548     return VINF_SUCCESS;
    549 }
    550 
    551 static int codecSetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset, uint64_t *pResp)
    552 {
    553     Assert((CODEC_CAD(cmd) == pState->id));
    554     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    555     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    556     {
    557         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    558         return VINF_SUCCESS;
    559     }
    560     *pResp = 0;
    561     if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
    562         codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param, cmd, u8Offset);
    563     else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
    564         codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param, cmd, u8Offset);
    565     return VINF_SUCCESS;
    566 }
    567 
    568 /* 70D */
    569 static int codecSetDigitalConverter1(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    570 {
    571     return codecSetDigitalConverter(pState, cmd, 0, pResp);
    572 }
    573 
    574 /* 70E */
    575 static int codecSetDigitalConverter2(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    576 {
    577     return codecSetDigitalConverter(pState, cmd, 8, pResp);
    578 }
    579 
    580 static int codecGetSubId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    581 {
    582     Assert((CODEC_CAD(cmd) == pState->id));
    583     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    584     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    585     {
    586         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    587         return VINF_SUCCESS;
    588     }
    589     *pResp = 0;
    590     if (CODEC_NID(cmd) == 1 /* AFG */)
    591     {
    592         *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F20_param;
    593     }
    594     return VINF_SUCCESS;
    595 }
    596 
    597 static int codecReset(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    598 {
    599     Assert((CODEC_CAD(cmd) == pState->id));
    600     Assert(CODEC_NID(cmd) == 1 /* AFG */);
    601     if(CODEC_NID(cmd) == 1 /* AFG */)
    602     {
    603         uint8_t i;
    604         Log(("HDAcodec: enters reset\n"));
    605         for (i = 0; i < pState->cTotalNodes; ++i)
    606         {
    607             stac9220ResetNode(pState, i, &pState->pNodes[i]);
    608         }
    609         pState->fInReset = false;
    610         Log(("HDAcodec: exits reset\n"));
    611     }
    612     *pResp = 0;
    613     return VINF_SUCCESS;
    614 }
    615 
    616 /* F05 */
    617 static int codecGetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    618 {
    619     Assert((CODEC_CAD(cmd) == pState->id));
    620     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    621     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    622     {
    623         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    624         return VINF_SUCCESS;
    625     }
    626     *pResp = 0;
    627     if (CODEC_NID(cmd) == 1 /* AFG */)
    628         *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param;
    629     else if (codecIsDacNode(pState, CODEC_NID(cmd)))
    630         *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param;
    631     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    632         *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param;
    633     else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
    634         *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param;
    635     return VINF_SUCCESS;
    636 }
    637 
    638 /* 705 */
    639 static int codecSetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    640 {
    641     Assert((CODEC_CAD(cmd) == pState->id));
    642     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    643     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    644     {
    645         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    646         return VINF_SUCCESS;
    647     }
    648     uint32_t *pu32Reg = NULL;
    649     *pResp = 0;
    650     if (CODEC_NID(cmd) == 1 /* AFG */)
    651         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param;
    652     else if (codecIsDacNode(pState, CODEC_NID(cmd)))
    653         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param;
    654     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    655         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param;
    656     else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
    657         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param;
    658     Assert((pu32Reg));
    659     if (!pu32Reg)
    660         return VINF_SUCCESS;
    661 
    662     if (!CODEC_NID(cmd) == 1 /* AFG */)
    663     {
    664         *pu32Reg &= ~CODEC_VERB_8BIT_DATA;
    665         *pu32Reg |= (pState->pNodes[1].afg.u32F05_param & (CODEC_VERB_4BIT_DATA << 4));
    666     }
    667     else
    668         *pu32Reg &= ~CODEC_VERB_4BIT_DATA;
    669 
    670     *pu32Reg |= cmd & CODEC_VERB_4BIT_DATA;
    671     /* Propogate next power state only if AFG is on or verb modifies AFG power state */
    672     if (   CODEC_NID(cmd) == 1 /* AFG */
    673         || !pState->pNodes[1].afg.u32F05_param)
    674     {
    675         *pu32Reg &= ~(CODEC_POWER_MASK << CODEC_POWER_ACT_SHIFT);
    676         *pu32Reg |= (cmd & CODEC_VERB_4BIT_DATA) << 4;
    677         if (   CODEC_NID(cmd) == 1 /* AFG */
    678             && (cmd & CODEC_POWER_MASK) == CODEC_POWER_D0)
    679         {
    680             CODEC_POWER_PROPOGATE_STATE(pState->pNodes[2].dac);
    681             CODEC_POWER_PROPOGATE_STATE(pState->pNodes[3].dac);
    682             CODEC_POWER_PROPOGATE_STATE(pState->pNodes[4].dac);
    683             CODEC_POWER_PROPOGATE_STATE(pState->pNodes[5].dac);
    684             CODEC_POWER_PROPOGATE_STATE(pState->pNodes[6].dac);
    685             CODEC_POWER_PROPOGATE_STATE(pState->pNodes[7].dac);
    686             CODEC_POWER_PROPOGATE_STATE(pState->pNodes[0x11].dac);
    687         }
    688     }
    689     return VINF_SUCCESS;
    690 }
    691 
    692 static int codecGetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    693 {
    694     Assert((CODEC_CAD(cmd) == pState->id));
    695     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    696     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    697     {
    698         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    699         return VINF_SUCCESS;
    700     }
    701     *pResp = 0;
    702     if (codecIsDacNode(pState, CODEC_NID(cmd)))
    703         *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param;
    704     else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
    705         *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param;
    706     else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
    707         *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
    708     else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
    709         *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
    710     else if (CODEC_NID(cmd) == 0x1A)
    711         *pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F06_param;
    712     return VINF_SUCCESS;
    713 }
    714 static int codecSetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    715 {
    716     Assert((CODEC_CAD(cmd) == pState->id));
    717     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    718     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    719     {
    720         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    721         return VINF_SUCCESS;
    722     }
    723     *pResp = 0;
    724     uint32_t *pu32addr = NULL;
    725     *pResp = 0;
    726     if (codecIsDacNode(pState, CODEC_NID(cmd)))
    727         pu32addr = &pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param;
    728     else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
    729         pu32addr = &pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param;
    730     else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
    731         pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
    732     else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
    733         pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
    734     else if (codecIsReservedNode(pState, CODEC_NID(cmd)))
    735         pu32addr = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F06_param;
    736     Assert((pu32addr));
    737     if (pu32addr)
    738         codecSetRegisterU8(pu32addr, cmd, 0);
    739     return VINF_SUCCESS;
    740 }
    741 static int codecGetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    742 {
    743     Assert((CODEC_CAD(cmd) == pState->id));
    744     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    745     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    746     {
    747         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    748         return VINF_SUCCESS;
    749     }
    750     *pResp = 0;
    751     if (codecIsDacNode(pState, CODEC_NID(cmd)))
    752         *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32A_param;
    753     else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
    754         *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32A_param;
    755     else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
    756         *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param;
    757     else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
    758         *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param;
    759     return VINF_SUCCESS;
    760 }
    761 
    762 static int codecSetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    763 {
    764     Assert((CODEC_CAD(cmd) == pState->id));
    765     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    766     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    767     {
    768         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    769         return VINF_SUCCESS;
    770     }
    771     *pResp = 0;
    772     if (codecIsDacNode(pState, CODEC_NID(cmd)))
    773         codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].dac.u32A_param, cmd, 0);
    774     else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
    775         codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].adc.u32A_param, cmd, 0);
    776     else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
    777         codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param, cmd, 0);
    778     else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
    779         codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param, cmd, 0);
    780     return VINF_SUCCESS;
    781 }
    782 
    783 /* F0C */
    784 static int codecGetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    785 {
    786     Assert((CODEC_CAD(cmd) == pState->id));
    787     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    788     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    789     {
    790         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    791         return VINF_SUCCESS;
    792     }
    793     *pResp = 0;
    794     if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
    795         *pResp = pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
    796     else if (codecIsDacNode(pState, CODEC_NID(cmd)))
    797         *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param;
    798     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    799         *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param;
    800     return VINF_SUCCESS;
    801 }
    802 
    803 /* 70C */
    804 static int codecSetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    805 {
    806     Assert((CODEC_CAD(cmd) == pState->id));
    807     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    808     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    809     {
    810         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    811         return VINF_SUCCESS;
    812     }
    813     *pResp = 0;
    814     uint32_t *pu32Reg = NULL;
    815     if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
    816         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
    817     else if (codecIsDacNode(pState, CODEC_NID(cmd)))
    818         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param;
    819     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    820         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param;
    821     *pResp = 0;
    822     Assert((pu32Reg));
    823     if (pu32Reg)
    824         codecSetRegisterU8(pu32Reg, cmd, 0);
    825     return VINF_SUCCESS;
    826 }
    827 
    828 /* F0F */
    829 static int codecGetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    830 {
    831     Assert((CODEC_CAD(cmd) == pState->id));
    832     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    833     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    834     {
    835         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    836         return VINF_SUCCESS;
    837     }
    838     *pResp = 0;
    839     if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
    840         *pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
    841     return VINF_SUCCESS;
    842 }
    843 
    844 /* 70F */
    845 static int codecSetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    846 {
    847     Assert((CODEC_CAD(cmd) == pState->id));
    848     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    849     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    850     {
    851         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    852         return VINF_SUCCESS;
    853     }
    854     uint32_t *pu32Reg = NULL;
    855     *pResp = 0;
    856     if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
    857         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
    858     Assert((pu32Reg));
    859     if (pu32Reg)
    860         codecSetRegisterU8(pu32Reg, cmd, 0);
    861     return VINF_SUCCESS;
    862 }
    863 
    864 /* F1C */
    865 static int codecGetConfig (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    866 {
    867     Assert((CODEC_CAD(cmd) == pState->id));
    868     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    869     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    870     {
    871         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    872         return VINF_SUCCESS;
    873     }
    874     *pResp = 0;
    875     if (codecIsPortNode(pState, CODEC_NID(cmd)))
    876         *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param;
    877     else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
    878         *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param;
    879     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    880         *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param;
    881     else if (codecIsCdNode(pState, CODEC_NID(cmd)))
    882         *pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
    883     return VINF_SUCCESS;
    884 }
    885 static int codecSetConfigX(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset)
    886 {
    887     Assert((CODEC_CAD(cmd) == pState->id));
    888     Assert((CODEC_NID(cmd) < pState->cTotalNodes));
    889     if (CODEC_NID(cmd) >= pState->cTotalNodes)
    890     {
    891         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    892         return VINF_SUCCESS;
    893     }
    894     uint32_t *pu32Reg = NULL;
    895     if (codecIsPortNode(pState, CODEC_NID(cmd)))
    896         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param;
    897     else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
    898         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param;
    899     else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
    900         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param;
    901     else if (codecIsCdNode(pState, CODEC_NID(cmd)))
    902         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
    903     else if (CODEC_NID(cmd) == 0x1B)
    904         pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
    905     Assert((pu32Reg));
    906     if (pu32Reg)
    907         codecSetRegisterU8(pu32Reg, cmd, u8Offset);
    908     return VINF_SUCCESS;
    909 }
    910 /* 71C */
    911 static int codecSetConfig0 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    912 {
    913     *pResp = 0;
    914     return codecSetConfigX(pState, cmd, 0);
    915 }
    916 /* 71D */
    917 static int codecSetConfig1 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    918 {
    919     *pResp = 0;
    920     return codecSetConfigX(pState, cmd, 8);
    921 }
    922 /* 71E */
    923 static int codecSetConfig2 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    924 {
    925     *pResp = 0;
    926     return codecSetConfigX(pState, cmd, 16);
    927 }
    928 /* 71E */
    929 static int codecSetConfig3 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    930 {
    931     *pResp = 0;
    932     return codecSetConfigX(pState, cmd, 24);
     92
     93static int stac9220Construct(CODECState *pState)
     94{
     95    unconst(pState->cTotalNodes) = 0x1C;
     96    pState->pfnCodecNodeReset = stac9220ResetNode;
     97    pState->pNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pState->cTotalNodes);
     98    pState->fInReset = false;
     99#define STAC9220WIDGET(type) pState->au8##type##s = au8Stac9220##type##s
     100    STAC9220WIDGET(Port);
     101    STAC9220WIDGET(Dac);
     102    STAC9220WIDGET(Adc);
     103    STAC9220WIDGET(AdcVol);
     104    STAC9220WIDGET(AdcMux);
     105    STAC9220WIDGET(Pcbeep);
     106    STAC9220WIDGET(SpdifIn);
     107    STAC9220WIDGET(SpdifOut);
     108    STAC9220WIDGET(DigInPin);
     109    STAC9220WIDGET(DigOutPin);
     110    STAC9220WIDGET(Cd);
     111    STAC9220WIDGET(VolKnob);
     112    STAC9220WIDGET(Reserved);
     113#undef STAC9220WIDGET
     114    unconst(pState->u8AdcVolsLineIn) = 0x17;
     115    unconst(pState->u8DacLineOut) = 0x2;
     116
     117    return VINF_SUCCESS;
    933118}
    934119
     
    1188373}
    1189374
     375/* generic */
     376
     377#define CODEC_POWER_MASK        0x3
     378#define CODEC_POWER_ACT_SHIFT   (4)
     379#define CODEC_POWER_SET_SHIFT   (0)
     380#define CODEC_POWER_D0          (0)
     381#define CODEC_POWER_D1          (1)
     382#define CODEC_POWER_D2          (2)
     383#define CODEC_POWER_D3          (3)
     384#define CODEC_POWER_PROPOGATE_STATE(node)                                                           \
     385    do {                                                                                            \
     386        node.u32F05_param &= (CODEC_POWER_MASK);                                                    \
     387        node.u32F05_param |= (node.u32F05_param & CODEC_POWER_MASK) << CODEC_POWER_ACT_SHIFT;     \
     388    }while(0)
     389
     390#define DECLISNODEOFTYPE(type)                                                                  \
     391    static inline int codecIs##type##Node(struct CODECState *pState, uint8_t cNode)             \
     392    {                                                                                           \
     393        Assert(pState->au8##type##s);                                                           \
     394        for(int i = 0; pState->au8##type##s[i] != 0; ++i)                                       \
     395            if (pState->au8##type##s[i] == cNode)                                               \
     396                return 1;                                                                       \
     397        return 0;                                                                               \
     398    }
     399/* codecIsPortNode */
     400DECLISNODEOFTYPE(Port)
     401/* codecIsDacNode */
     402DECLISNODEOFTYPE(Dac)
     403/* codecIsAdcVolNode */
     404DECLISNODEOFTYPE(AdcVol)
     405/* codecIsAdcNode */
     406DECLISNODEOFTYPE(Adc)
     407/* codecIsAdcMuxNode */
     408DECLISNODEOFTYPE(AdcMux)
     409/* codecIsPcbeepNode */
     410DECLISNODEOFTYPE(Pcbeep)
     411/* codecIsSpdifOutNode */
     412DECLISNODEOFTYPE(SpdifOut)
     413/* codecIsSpdifInNode */
     414DECLISNODEOFTYPE(SpdifIn)
     415/* codecIsDigInPinNode */
     416DECLISNODEOFTYPE(DigInPin)
     417/* codecIsDigOutPinNode */
     418DECLISNODEOFTYPE(DigOutPin)
     419/* codecIsCdNode */
     420DECLISNODEOFTYPE(Cd)
     421/* codecIsVolKnobNode */
     422DECLISNODEOFTYPE(VolKnob)
     423/* codecIsReservedNode */
     424DECLISNODEOFTYPE(Reserved)
     425
     426static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt);
     427
     428static inline void codecSetRegister(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset, uint32_t mask)
     429{
     430        Assert((pu32Reg && u8Offset < 32));
     431        *pu32Reg &= ~(mask << u8Offset);
     432        *pu32Reg |= (u32Cmd & mask) << u8Offset;
     433}
     434static inline void codecSetRegisterU8(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset)
     435{
     436    codecSetRegister(pu32Reg, u32Cmd, u8Offset, CODEC_VERB_8BIT_DATA);
     437}
     438
     439static inline void codecSetRegisterU16(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset)
     440{
     441    codecSetRegister(pu32Reg, u32Cmd, u8Offset, CODEC_VERB_16BIT_DATA);
     442}
     443
     444
     445static int codecUnimplemented(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     446{
     447    Log(("codecUnimplemented: cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd,
     448        CODEC_CAD(cmd), CODEC_DIRECT(cmd) ? 'N' : 'Y', CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
     449    *pResp = 0;
     450    return VINF_SUCCESS;
     451}
     452
     453static int codecBreak(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     454{
     455    int rc;
     456    rc = codecUnimplemented(pState, cmd, pResp);
     457    *pResp |= CODEC_RESPONSE_UNSOLICITED;
     458    return rc;
     459}
     460/* B-- */
     461static int codecGetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     462{
     463    Assert((CODEC_CAD(cmd) == pState->id));
     464    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     465    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     466    {
     467        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     468        return VINF_SUCCESS;
     469    }
     470    *pResp = 0;
     471    /* HDA spec 7.3.3.7 Note A */
     472    /* @todo: if index out of range response should be 0 */
     473    uint8_t u8Index = CODEC_GET_AMP_DIRECTION(cmd) == AMPLIFIER_OUT? 0 : CODEC_GET_AMP_INDEX(cmd);
     474
     475    PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)];
     476    if (codecIsDacNode(pState, CODEC_NID(cmd)))
     477        *pResp = AMPLIFIER_REGISTER(pNode->dac.B_params,
     478                            CODEC_GET_AMP_DIRECTION(cmd),
     479                            CODEC_GET_AMP_SIDE(cmd),
     480                            u8Index);
     481    else if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
     482        *pResp = AMPLIFIER_REGISTER(pNode->adcvol.B_params,
     483                            CODEC_GET_AMP_DIRECTION(cmd),
     484                            CODEC_GET_AMP_SIDE(cmd),
     485                            u8Index);
     486    else if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
     487        *pResp = AMPLIFIER_REGISTER(pNode->adcmux.B_params,
     488                            CODEC_GET_AMP_DIRECTION(cmd),
     489                            CODEC_GET_AMP_SIDE(cmd),
     490                            u8Index);
     491    else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
     492        *pResp = AMPLIFIER_REGISTER(pNode->pcbeep.B_params,
     493                            CODEC_GET_AMP_DIRECTION(cmd),
     494                            CODEC_GET_AMP_SIDE(cmd),
     495                            u8Index);
     496    else{
     497        AssertMsgReturn(0, ("access to fields of %x need to be implemented\n", CODEC_NID(cmd)), VINF_SUCCESS);
     498    }
     499    return VINF_SUCCESS;
     500}
     501/* 3-- */
     502static int codecSetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     503{
     504    AMPLIFIER *pAmplifier = NULL;
     505    bool fIsLeft = false;
     506    bool fIsRight = false;
     507    bool fIsOut = false;
     508    bool fIsIn = false;
     509    uint8_t u8Index = 0;
     510    Assert((CODEC_CAD(cmd) == pState->id));
     511    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     512    {
     513        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     514        return VINF_SUCCESS;
     515    }
     516    *pResp = 0;
     517    PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)];
     518    if (codecIsDacNode(pState, CODEC_NID(cmd)))
     519        pAmplifier = &pNode->dac.B_params;
     520    else if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
     521        pAmplifier = &pNode->adcvol.B_params;
     522    else if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
     523        pAmplifier = &pNode->adcmux.B_params;
     524    else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
     525        pAmplifier = &pNode->pcbeep.B_params;
     526    Assert(pAmplifier);
     527    if (pAmplifier)
     528    {
     529        fIsOut = CODEC_SET_AMP_IS_OUT_DIRECTION(cmd);
     530        fIsIn = CODEC_SET_AMP_IS_IN_DIRECTION(cmd);
     531        fIsRight = CODEC_SET_AMP_IS_RIGHT_SIDE(cmd);
     532        fIsLeft = CODEC_SET_AMP_IS_LEFT_SIDE(cmd);
     533        u8Index = CODEC_SET_AMP_INDEX(cmd);
     534        if (   (!fIsLeft && !fIsRight)
     535            || (!fIsOut && !fIsIn))
     536            return VINF_SUCCESS;
     537        if (fIsIn)
     538        {
     539            if (fIsLeft)
     540                codecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_LEFT, u8Index), cmd, 0);
     541            if (fIsRight)
     542                codecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0);
     543        }
     544        if (fIsOut)
     545        {
     546            if (fIsLeft)
     547                codecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_LEFT, u8Index), cmd, 0);
     548            if (fIsRight)
     549                codecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_RIGHT, u8Index), cmd, 0);
     550        }
     551        if (CODEC_NID(cmd) == 2)
     552            codecToAudVolume(pAmplifier, AUD_MIXER_VOLUME);
     553        if (CODEC_NID(cmd) == 0x17) /* Microphone */
     554            codecToAudVolume(pAmplifier, AUD_MIXER_LINE_IN);
     555    }
     556    return VINF_SUCCESS;
     557}
     558
     559static int codecGetParameter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     560{
     561    Assert((CODEC_CAD(cmd) == pState->id));
     562    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     563    {
     564        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     565        return VINF_SUCCESS;
     566    }
     567    Assert(((cmd & CODEC_VERB_8BIT_DATA) < CODECNODE_F0_PARAM_LENGTH));
     568    if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F0_PARAM_LENGTH)
     569    {
     570        Log(("HDAcodec: invalid F00 parameter %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
     571        return VINF_SUCCESS;
     572    }
     573    *pResp = 0;
     574    *pResp = pState->pNodes[CODEC_NID(cmd)].node.au32F00_param[cmd & CODEC_VERB_8BIT_DATA];
     575    return VINF_SUCCESS;
     576}
     577
     578/* F01 */
     579static int codecGetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     580{
     581    Assert((CODEC_CAD(cmd) == pState->id));
     582    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     583    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     584    {
     585        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     586        return VINF_SUCCESS;
     587    }
     588    *pResp = 0;
     589    if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
     590        *pResp = pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
     591    else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
     592        *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param;
     593    return VINF_SUCCESS;
     594}
     595
     596/* 701 */
     597static int codecSetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     598{
     599    uint32_t *pu32Reg = NULL;
     600    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     601    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     602    {
     603        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     604        return VINF_SUCCESS;
     605    }
     606    *pResp = 0;
     607    if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
     608        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
     609    else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
     610        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param;
     611    Assert((pu32Reg));
     612    if (pu32Reg)
     613        codecSetRegisterU8(pu32Reg, cmd, 0);
     614    return VINF_SUCCESS;
     615}
     616
     617/* F07 */
     618static int codecGetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     619{
     620    Assert((CODEC_CAD(cmd) == pState->id));
     621    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     622    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     623    {
     624        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     625        return VINF_SUCCESS;
     626    }
     627    *pResp = 0;
     628    if (codecIsPortNode(pState, CODEC_NID(cmd)))
     629        *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F07_param;
     630    else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
     631        *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param;
     632    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     633        *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param;
     634    else if (codecIsCdNode(pState, CODEC_NID(cmd)))
     635        *pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
     636    else if (   codecIsReservedNode(pState, CODEC_NID(cmd))
     637             && CODEC_NID(cmd) == 0x1b)
     638        *pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param;
     639    else
     640        AssertMsgFailed(("Unsupported"));
     641    return VINF_SUCCESS;
     642}
     643
     644/* 707 */
     645static int codecSetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     646{
     647    Assert((CODEC_CAD(cmd) == pState->id));
     648    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     649    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     650    {
     651        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     652        return VINF_SUCCESS;
     653    }
     654    *pResp = 0;
     655    uint32_t *pu32Reg = NULL;
     656    if (codecIsPortNode(pState, CODEC_NID(cmd)))
     657        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F07_param;
     658    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     659        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param;
     660    else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
     661        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param;
     662    else if (codecIsCdNode(pState, CODEC_NID(cmd)))
     663        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
     664    else if (   codecIsReservedNode(pState, CODEC_NID(cmd))
     665             && CODEC_NID(cmd) == 0x1b)
     666        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param;
     667    Assert((pu32Reg));
     668    if (pu32Reg)
     669        codecSetRegisterU8(pu32Reg, cmd, 0);
     670    return VINF_SUCCESS;
     671}
     672
     673/* F08 */
     674static int codecGetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     675{
     676    Assert((CODEC_CAD(cmd) == pState->id));
     677    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     678    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     679    {
     680        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     681        return VINF_SUCCESS;
     682    }
     683    *pResp = 0;
     684    if (codecIsPortNode(pState, CODEC_NID(cmd)))
     685        *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
     686    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     687        *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
     688    else if ((cmd) == 1 /* AFG */)
     689        *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param;
     690    else if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
     691        *pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
     692    else
     693        AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
     694    return VINF_SUCCESS;
     695}
     696
     697/* 708 */
     698static int codecSetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     699{
     700    Assert((CODEC_CAD(cmd) == pState->id));
     701    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     702    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     703    {
     704        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     705        return VINF_SUCCESS;
     706    }
     707    *pResp = 0;
     708    uint32_t *pu32Reg = NULL;
     709    if (codecIsPortNode(pState, CODEC_NID(cmd)))
     710        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
     711    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     712        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
     713    else if (CODEC_NID(cmd) == 1 /* AFG */)
     714        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param;
     715    else if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
     716        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
     717    else
     718        AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
     719    Assert(pu32Reg);
     720    if(pu32Reg)
     721        codecSetRegisterU8(pu32Reg, cmd, 0);
     722    return VINF_SUCCESS;
     723}
     724
     725/* F09 */
     726static int codecGetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     727{
     728    Assert((CODEC_CAD(cmd) == pState->id));
     729    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     730    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     731    {
     732        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     733        return VINF_SUCCESS;
     734    }
     735    *pResp = 0;
     736    if (codecIsPortNode(pState, CODEC_NID(cmd)))
     737        *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F09_param;
     738    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     739        *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F09_param;
     740    else
     741        AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
     742    return VINF_SUCCESS;
     743}
     744
     745/* 709 */
     746static int codecSetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     747{
     748    Assert((CODEC_CAD(cmd) == pState->id));
     749    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     750    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     751    {
     752        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     753        return VINF_SUCCESS;
     754    }
     755    *pResp = 0;
     756    uint32_t *pu32Reg = NULL;
     757    //** @todo r=michaln: Copy/paste bug? This can't be F08_parm!
     758    if (codecIsPortNode(pState, CODEC_NID(cmd)))
     759        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
     760    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     761        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
     762    Assert(pu32Reg);
     763    if(pu32Reg)
     764        codecSetRegisterU8(pu32Reg, cmd, 0);
     765    return VINF_SUCCESS;
     766}
     767
     768static int codecGetConnectionListEntry(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     769{
     770    Assert((CODEC_CAD(cmd) == pState->id));
     771    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     772    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     773    {
     774        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     775        return VINF_SUCCESS;
     776    }
     777    Assert((cmd & CODEC_VERB_8BIT_DATA) < 16);
     778    if ((cmd & CODEC_VERB_8BIT_DATA) >= 16)
     779    {
     780        Log(("HDAcodec: access to invalid F02 index %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
     781    }
     782    *pResp = *(uint32_t *)&pState->pNodes[CODEC_NID(cmd)].node.au8F02_param[cmd & CODEC_VERB_8BIT_DATA];
     783    return VINF_SUCCESS;
     784}
     785/* F03 */
     786static int codecGetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     787{
     788    Assert((CODEC_CAD(cmd) == pState->id));
     789    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     790    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     791    {
     792        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     793        return VINF_SUCCESS;
     794    }
     795    *pResp = 0;
     796    if (codecIsAdcNode(pState, CODEC_NID(cmd)))
     797        *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param;
     798    return VINF_SUCCESS;
     799}
     800
     801/* 703 */
     802static int codecSetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     803{
     804    Assert((CODEC_CAD(cmd) == pState->id));
     805    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     806    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     807    {
     808        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     809        return VINF_SUCCESS;
     810    }
     811    *pResp = 0;
     812    if (codecIsAdcNode(pState, CODEC_NID(cmd)))
     813    {
     814        codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param, cmd, 0);
     815    }
     816    return VINF_SUCCESS;
     817}
     818
     819/* F0D */
     820static int codecGetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     821{
     822    Assert((CODEC_CAD(cmd) == pState->id));
     823    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     824    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     825    {
     826        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     827        return VINF_SUCCESS;
     828    }
     829    *pResp = 0;
     830    if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
     831        *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param;
     832    else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
     833        *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param;
     834    return VINF_SUCCESS;
     835}
     836
     837static int codecSetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset, uint64_t *pResp)
     838{
     839    Assert((CODEC_CAD(cmd) == pState->id));
     840    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     841    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     842    {
     843        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     844        return VINF_SUCCESS;
     845    }
     846    *pResp = 0;
     847    if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
     848        codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param, cmd, u8Offset);
     849    else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
     850        codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param, cmd, u8Offset);
     851    return VINF_SUCCESS;
     852}
     853
     854/* 70D */
     855static int codecSetDigitalConverter1(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     856{
     857    return codecSetDigitalConverter(pState, cmd, 0, pResp);
     858}
     859
     860/* 70E */
     861static int codecSetDigitalConverter2(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     862{
     863    return codecSetDigitalConverter(pState, cmd, 8, pResp);
     864}
     865
     866static int codecGetSubId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     867{
     868    Assert((CODEC_CAD(cmd) == pState->id));
     869    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     870    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     871    {
     872        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     873        return VINF_SUCCESS;
     874    }
     875    *pResp = 0;
     876    if (CODEC_NID(cmd) == 1 /* AFG */)
     877    {
     878        *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F20_param;
     879    }
     880    return VINF_SUCCESS;
     881}
     882
     883static int codecReset(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     884{
     885    Assert((CODEC_CAD(cmd) == pState->id));
     886    Assert(CODEC_NID(cmd) == 1 /* AFG */);
     887    if(CODEC_NID(cmd) == 1 /* AFG */)
     888    {
     889        uint8_t i;
     890        Log(("HDAcodec: enters reset\n"));
     891        Assert(pState->pfnCodecNodeReset);
     892        for (i = 0; i < pState->cTotalNodes; ++i)
     893        {
     894            pState->pfnCodecNodeReset(pState, i, &pState->pNodes[i]);
     895        }
     896        pState->fInReset = false;
     897        Log(("HDAcodec: exits reset\n"));
     898    }
     899    *pResp = 0;
     900    return VINF_SUCCESS;
     901}
     902
     903/* F05 */
     904static int codecGetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     905{
     906    Assert((CODEC_CAD(cmd) == pState->id));
     907    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     908    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     909    {
     910        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     911        return VINF_SUCCESS;
     912    }
     913    *pResp = 0;
     914    if (CODEC_NID(cmd) == 1 /* AFG */)
     915        *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param;
     916    else if (codecIsDacNode(pState, CODEC_NID(cmd)))
     917        *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param;
     918    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     919        *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param;
     920    else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
     921        *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param;
     922    return VINF_SUCCESS;
     923}
     924
     925/* 705 */
     926static int codecSetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     927{
     928    Assert((CODEC_CAD(cmd) == pState->id));
     929    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     930    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     931    {
     932        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     933        return VINF_SUCCESS;
     934    }
     935    uint32_t *pu32Reg = NULL;
     936    *pResp = 0;
     937    if (CODEC_NID(cmd) == 1 /* AFG */)
     938        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param;
     939    else if (codecIsDacNode(pState, CODEC_NID(cmd)))
     940        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param;
     941    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     942        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param;
     943    else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
     944        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param;
     945    Assert((pu32Reg));
     946    if (!pu32Reg)
     947        return VINF_SUCCESS;
     948
     949    if (!CODEC_NID(cmd) == 1 /* AFG */)
     950    {
     951        *pu32Reg &= ~CODEC_VERB_8BIT_DATA;
     952        *pu32Reg |= (pState->pNodes[1].afg.u32F05_param & (CODEC_VERB_4BIT_DATA << 4));
     953    }
     954    else
     955        *pu32Reg &= ~CODEC_VERB_4BIT_DATA;
     956
     957    *pu32Reg |= cmd & CODEC_VERB_4BIT_DATA;
     958    /* Propogate next power state only if AFG is on or verb modifies AFG power state */
     959    if (   CODEC_NID(cmd) == 1 /* AFG */
     960        || !pState->pNodes[1].afg.u32F05_param)
     961    {
     962        *pu32Reg &= ~(CODEC_POWER_MASK << CODEC_POWER_ACT_SHIFT);
     963        *pu32Reg |= (cmd & CODEC_VERB_4BIT_DATA) << 4;
     964        if (   CODEC_NID(cmd) == 1 /* AFG */
     965            && (cmd & CODEC_POWER_MASK) == CODEC_POWER_D0)
     966        {
     967            CODEC_POWER_PROPOGATE_STATE(pState->pNodes[2].dac);
     968            CODEC_POWER_PROPOGATE_STATE(pState->pNodes[3].dac);
     969            CODEC_POWER_PROPOGATE_STATE(pState->pNodes[4].dac);
     970            CODEC_POWER_PROPOGATE_STATE(pState->pNodes[5].dac);
     971            CODEC_POWER_PROPOGATE_STATE(pState->pNodes[6].dac);
     972            CODEC_POWER_PROPOGATE_STATE(pState->pNodes[7].dac);
     973            CODEC_POWER_PROPOGATE_STATE(pState->pNodes[0x11].dac);
     974        }
     975    }
     976    return VINF_SUCCESS;
     977}
     978
     979static int codecGetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     980{
     981    Assert((CODEC_CAD(cmd) == pState->id));
     982    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     983    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     984    {
     985        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     986        return VINF_SUCCESS;
     987    }
     988    *pResp = 0;
     989    if (codecIsDacNode(pState, CODEC_NID(cmd)))
     990        *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param;
     991    else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
     992        *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param;
     993    else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
     994        *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
     995    else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
     996        *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
     997    else if (CODEC_NID(cmd) == 0x1A)
     998        *pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F06_param;
     999    return VINF_SUCCESS;
     1000}
     1001static int codecSetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1002{
     1003    Assert((CODEC_CAD(cmd) == pState->id));
     1004    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     1005    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     1006    {
     1007        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     1008        return VINF_SUCCESS;
     1009    }
     1010    *pResp = 0;
     1011    uint32_t *pu32addr = NULL;
     1012    *pResp = 0;
     1013    if (codecIsDacNode(pState, CODEC_NID(cmd)))
     1014        pu32addr = &pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param;
     1015    else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
     1016        pu32addr = &pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param;
     1017    else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
     1018        pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
     1019    else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
     1020        pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
     1021    else if (codecIsReservedNode(pState, CODEC_NID(cmd)))
     1022        pu32addr = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F06_param;
     1023    Assert((pu32addr));
     1024    if (pu32addr)
     1025        codecSetRegisterU8(pu32addr, cmd, 0);
     1026    return VINF_SUCCESS;
     1027}
     1028static int codecGetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1029{
     1030    Assert((CODEC_CAD(cmd) == pState->id));
     1031    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     1032    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     1033    {
     1034        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     1035        return VINF_SUCCESS;
     1036    }
     1037    *pResp = 0;
     1038    if (codecIsDacNode(pState, CODEC_NID(cmd)))
     1039        *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32A_param;
     1040    else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
     1041        *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32A_param;
     1042    else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
     1043        *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param;
     1044    else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
     1045        *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param;
     1046    return VINF_SUCCESS;
     1047}
     1048
     1049static int codecSetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1050{
     1051    Assert((CODEC_CAD(cmd) == pState->id));
     1052    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     1053    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     1054    {
     1055        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     1056        return VINF_SUCCESS;
     1057    }
     1058    *pResp = 0;
     1059    if (codecIsDacNode(pState, CODEC_NID(cmd)))
     1060        codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].dac.u32A_param, cmd, 0);
     1061    else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
     1062        codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].adc.u32A_param, cmd, 0);
     1063    else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
     1064        codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param, cmd, 0);
     1065    else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
     1066        codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param, cmd, 0);
     1067    return VINF_SUCCESS;
     1068}
     1069
     1070/* F0C */
     1071static int codecGetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1072{
     1073    Assert((CODEC_CAD(cmd) == pState->id));
     1074    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     1075    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     1076    {
     1077        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     1078        return VINF_SUCCESS;
     1079    }
     1080    *pResp = 0;
     1081    if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
     1082        *pResp = pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
     1083    else if (codecIsDacNode(pState, CODEC_NID(cmd)))
     1084        *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param;
     1085    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     1086        *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param;
     1087    return VINF_SUCCESS;
     1088}
     1089
     1090/* 70C */
     1091static int codecSetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1092{
     1093    Assert((CODEC_CAD(cmd) == pState->id));
     1094    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     1095    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     1096    {
     1097        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     1098        return VINF_SUCCESS;
     1099    }
     1100    *pResp = 0;
     1101    uint32_t *pu32Reg = NULL;
     1102    if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
     1103        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
     1104    else if (codecIsDacNode(pState, CODEC_NID(cmd)))
     1105        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param;
     1106    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     1107        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param;
     1108    *pResp = 0;
     1109    Assert((pu32Reg));
     1110    if (pu32Reg)
     1111        codecSetRegisterU8(pu32Reg, cmd, 0);
     1112    return VINF_SUCCESS;
     1113}
     1114
     1115/* F0F */
     1116static int codecGetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1117{
     1118    Assert((CODEC_CAD(cmd) == pState->id));
     1119    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     1120    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     1121    {
     1122        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     1123        return VINF_SUCCESS;
     1124    }
     1125    *pResp = 0;
     1126    if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
     1127        *pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
     1128    return VINF_SUCCESS;
     1129}
     1130
     1131/* 70F */
     1132static int codecSetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1133{
     1134    Assert((CODEC_CAD(cmd) == pState->id));
     1135    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     1136    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     1137    {
     1138        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     1139        return VINF_SUCCESS;
     1140    }
     1141    uint32_t *pu32Reg = NULL;
     1142    *pResp = 0;
     1143    if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
     1144        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
     1145    Assert((pu32Reg));
     1146    if (pu32Reg)
     1147        codecSetRegisterU8(pu32Reg, cmd, 0);
     1148    return VINF_SUCCESS;
     1149}
     1150
     1151/* F1C */
     1152static int codecGetConfig (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1153{
     1154    Assert((CODEC_CAD(cmd) == pState->id));
     1155    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     1156    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     1157    {
     1158        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     1159        return VINF_SUCCESS;
     1160    }
     1161    *pResp = 0;
     1162    if (codecIsPortNode(pState, CODEC_NID(cmd)))
     1163        *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param;
     1164    else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
     1165        *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param;
     1166    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     1167        *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param;
     1168    else if (codecIsCdNode(pState, CODEC_NID(cmd)))
     1169        *pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
     1170    return VINF_SUCCESS;
     1171}
     1172static int codecSetConfigX(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset)
     1173{
     1174    Assert((CODEC_CAD(cmd) == pState->id));
     1175    Assert((CODEC_NID(cmd) < pState->cTotalNodes));
     1176    if (CODEC_NID(cmd) >= pState->cTotalNodes)
     1177    {
     1178        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     1179        return VINF_SUCCESS;
     1180    }
     1181    uint32_t *pu32Reg = NULL;
     1182    if (codecIsPortNode(pState, CODEC_NID(cmd)))
     1183        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param;
     1184    else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
     1185        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param;
     1186    else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
     1187        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param;
     1188    else if (codecIsCdNode(pState, CODEC_NID(cmd)))
     1189        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
     1190    else if (CODEC_NID(cmd) == 0x1B)
     1191        pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
     1192    Assert((pu32Reg));
     1193    if (pu32Reg)
     1194        codecSetRegisterU8(pu32Reg, cmd, u8Offset);
     1195    return VINF_SUCCESS;
     1196}
     1197/* 71C */
     1198static int codecSetConfig0 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1199{
     1200    *pResp = 0;
     1201    return codecSetConfigX(pState, cmd, 0);
     1202}
     1203/* 71D */
     1204static int codecSetConfig1 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1205{
     1206    *pResp = 0;
     1207    return codecSetConfigX(pState, cmd, 8);
     1208}
     1209/* 71E */
     1210static int codecSetConfig2 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1211{
     1212    *pResp = 0;
     1213    return codecSetConfigX(pState, cmd, 16);
     1214}
     1215/* 71E */
     1216static int codecSetConfig3 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
     1217{
     1218    *pResp = 0;
     1219    return codecSetConfigX(pState, cmd, 24);
     1220}
     1221
     1222
    11901223static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt)
    11911224{
     
    12111244}
    12121245
    1213 static CODECVERB STAC9220VERB[] =
     1246static CODECVERB CODECVERBS[] =
    12141247{
    12151248/*    verb     | verb mask              | callback               */
     
    12801313}
    12811314
    1282 static int codec_dac_to_aud(CODECState *pState, int dacnum, audsettings_t *paud)
     1315static int codec_dac_to_aud(CODECState *pState, audsettings_t *paud)
    12831316{
    12841317    paud->freq = 44100;
     
    13071340    pState->pfnTransfer(pState, MC_INDEX, avail);
    13081341}
    1309 #define STAC9220_DAC_PI (0x2)
    1310 #define STAC9220_DAC_MC (0x3)
    1311 #define STAC9220_DAC_PO (0x4)
    1312 int stac9220Construct(CODECState *pState)
     1342
     1343int codecConstruct(CODECState *pState, ENMCODEC enmCodec)
    13131344{
    13141345    audsettings_t as;
    1315     pState->pVerbs = (CODECVERB *)&STAC9220VERB;
    1316     pState->cVerbs = sizeof(STAC9220VERB)/sizeof(CODECVERB);
     1346    int rc;
     1347    pState->pVerbs = (CODECVERB *)&CODECVERBS;
     1348    pState->cVerbs = sizeof(CODECVERBS)/sizeof(CODECVERB);
    13171349    pState->pfnLookup = codecLookup;
    1318     unconst(pState->cTotalNodes) = 0x1C;
    1319     pState->pNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pState->cTotalNodes);
    1320     pState->fInReset = false;
    1321 #define STAC9220WIDGET(type) pState->au8##type##s = au8Stac9220##type##s
    1322     STAC9220WIDGET(Port);
    1323     STAC9220WIDGET(Dac);
    1324     STAC9220WIDGET(Adc);
    1325     STAC9220WIDGET(AdcVol);
    1326     STAC9220WIDGET(AdcMux);
    1327     STAC9220WIDGET(Pcbeep);
    1328     STAC9220WIDGET(SpdifIn);
    1329     STAC9220WIDGET(SpdifOut);
    1330     STAC9220WIDGET(DigInPin);
    1331     STAC9220WIDGET(DigOutPin);
    1332     STAC9220WIDGET(Cd);
    1333     STAC9220WIDGET(VolKnob);
    1334     STAC9220WIDGET(Reserved);
    1335 #undef STAC9220WIDGET
    1336    
     1350    pState->enmCodec = enmCodec;
     1351    if (enmCodec == STAC9220_CODEC)
     1352    {
     1353        rc = stac9220Construct(pState);
     1354        AssertRC(rc);
     1355    }
    13371356    uint8_t i;
     1357    Assert(pState->pNodes);
     1358    Assert(pState->pfnCodecNodeReset);
    13381359    for (i = 0; i < pState->cTotalNodes; ++i)
    13391360    {
    1340         stac9220ResetNode(pState, i, &pState->pNodes[i]);
     1361        pState->pfnCodecNodeReset(pState, i, &pState->pNodes[i]);
    13411362    }
    13421363    //** @todo r=michaln: Was this meant to be 'HDA' or something like that? (AC'97 was on ICH0)
    13431364    AUD_register_card ("ICH0", &pState->card);
    13441365
    1345 
    1346     codec_dac_to_aud(pState, STAC9220_DAC_PI, &as);
     1366    codec_dac_to_aud(pState, &as);
    13471367    pState->voice_pi = AUD_open_in(&pState->card, pState->voice_pi, "hda.in", pState, pi_callback, &as);
    1348     codec_dac_to_aud(pState, STAC9220_DAC_PO, &as);
     1368    codec_dac_to_aud(pState, &as);
    13491369    pState->voice_po = AUD_open_out(&pState->card, pState->voice_po, "hda.out", pState, po_callback, &as);
    1350     codec_dac_to_aud(pState, STAC9220_DAC_MC, &as);
    1351     pState->voice_mc = AUD_open_in(&pState->card, pState->voice_mc, "hda.mc", pState, mc_callback, &as);
    13521370    if (!pState->voice_pi)
    13531371        LogRel (("HDAcodec: WARNING: Unable to open PCM IN!\n"));
    1354     if (!pState->voice_mc)
    1355         LogRel (("HDAcodec: WARNING: Unable to open PCM MC!\n"));
    13561372    if (!pState->voice_po)
    13571373        LogRel (("HDAcodec: WARNING: Unable to open PCM OUT!\n"));
    1358     codecToAudVolume(&pState->pNodes[2].dac.B_params, AUD_MIXER_VOLUME);
    1359     codecToAudVolume(&pState->pNodes[0x17].adcvol.B_params, AUD_MIXER_LINE_IN);
    1360 
    1361     return VINF_SUCCESS;
    1362 }
    1363 int stac9220Destruct(CODECState *pCodecState)
     1374    codecToAudVolume(&pState->pNodes[pState->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
     1375    codecToAudVolume(&pState->pNodes[pState->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
     1376
     1377    return VINF_SUCCESS;
     1378}
     1379int codecDestruct(CODECState *pCodecState)
    13641380{
    13651381    RTMemFree(pCodecState->pNodes);
     
    13671383}
    13681384
    1369 int stac9220SaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle)
     1385int codecSaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle)
    13701386{
    13711387    SSMR3PutMem (pSSMHandle, pCodecState->pNodes, sizeof(CODECNODE) * pCodecState->cTotalNodes);
    13721388    return VINF_SUCCESS;
    13731389}
    1374 int stac9220LoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle)
     1390
     1391int codecLoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle)
    13751392{
    13761393    SSMR3GetMem (pSSMHandle, pCodecState->pNodes, sizeof(CODECNODE) * pCodecState->cTotalNodes);
    1377     codecToAudVolume(&pCodecState->pNodes[2].dac.B_params, AUD_MIXER_VOLUME);
    1378     codecToAudVolume(&pCodecState->pNodes[0x17].adcvol.B_params, AUD_MIXER_LINE_IN);
    1379     return VINF_SUCCESS;
    1380 }
     1394    codecToAudVolume(&pCodecState->pNodes[pCodecState->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
     1395    codecToAudVolume(&pCodecState->pNodes[pCodecState->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
     1396    return VINF_SUCCESS;
     1397}
  • trunk/src/VBox/Devices/Audio/DevCodec.h

    r32803 r32804  
    219219} ENMSOUNDSOURCE;
    220220
     221typedef enum
     222{
     223    STAC9220_CODEC
     224} ENMCODEC;
    221225typedef struct CODECState
    222226{
     
    232236    /** Mic in */
    233237    SWVoiceIn               *voice_mc;
     238    ENMCODEC                enmCodec;
    234239    void                    *pHDAState;
    235240    bool                    fInReset;
     
    248253    const uint8_t           *au8VolKnobs;
    249254    const uint8_t           *au8Reserveds;
     255    const uint8_t           u8AdcVolsLineIn;
     256    const uint8_t           u8DacLineOut;
    250257    DECLR3CALLBACKMEMBER(int, pfnProcess, (struct CODECState *));
    251258    DECLR3CALLBACKMEMBER(int, pfnLookup, (struct CODECState *pState, uint32_t verb, PPFNCODECVERBPROCESSOR));
    252259    DECLR3CALLBACKMEMBER(int, pfnReset, (struct CODECState *pState));
    253260    DECLR3CALLBACKMEMBER(void, pfnTransfer, (struct CODECState *pState, ENMSOUNDSOURCE, int avail));
     261    DECLR3CALLBACKMEMBER(int, pfnCodecNodeReset, (struct CODECState *pState, uint8_t, PCODECNODE));
    254262
    255263} CODECState;
    256264
    257265
    258 int stac9220Construct(CODECState *pCodecState);
    259 int stac9220Destruct(CODECState *pCodecState);
    260 int stac9220SaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle);
    261 int stac9220LoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle);
     266int codecConstruct(CODECState *pCodecState, ENMCODEC enmCodec);
     267int codecDestruct(CODECState *pCodecState);
     268int codecSaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle);
     269int codecLoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle);
    262270
    263271#endif
  • trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp

    r32765 r32804  
    14991499    PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
    15001500    /* Save Codec nodes states */
    1501     stac9220SaveState(&pThis->hda.Codec, pSSMHandle);
     1501    codecSaveState(&pThis->hda.Codec, pSSMHandle);
    15021502    /* Save MMIO registers */
    15031503    SSMR3PutMem (pSSMHandle, pThis->hda.au32Regs, sizeof (pThis->hda.au32Regs));
     
    15271527    PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
    15281528    /* Load Codec nodes states */
    1529     stac9220LoadState(&pThis->hda.Codec, pSSMHandle);
     1529    AssertMsgReturn (uVersion == HDA_SSM_VERSION, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
     1530    Assert (uPass == SSM_PASS_FINAL); NOREF(uPass);
     1531
     1532    codecLoadState(&pThis->hda.Codec, pSSMHandle);
    15301533    /* Load MMIO registers */
    15311534    SSMR3GetMem (pSSMHandle, pThis->hda.au32Regs, sizeof (pThis->hda.au32Regs));
     
    17791782
    17801783    pThis->hda.Codec.pHDAState = (void *)&pThis->hda;
    1781     rc = stac9220Construct(&pThis->hda.Codec);
     1784    rc = codecConstruct(&pThis->hda.Codec, STAC9220_CODEC);
    17821785    if (RT_FAILURE(rc))
    17831786        AssertRCReturn(rc, rc);
     
    18031806    PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *);
    18041807
    1805     int rc = stac9220Destruct(&pThis->hda.Codec);
     1808    int rc = codecDestruct(&pThis->hda.Codec);
    18061809    AssertRC(rc);
    18071810    if (pThis->hda.pu32CorbBuf)
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