VirtualBox

Changeset 87799 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Feb 19, 2021 10:44:27 AM (4 years ago)
Author:
vboxsync
Message:

HDA/Codec: Codec now also can run in R0 to speed up interrupt handling and therefore lowering DPC latency on Windows guests. ticketoem2ref:36

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

Legend:

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

    r87767 r87799  
    674674}
    675675
     676#endif /* IN_RING3 */
    676677
    677678/**
     
    687688 * @todo r=andy Break this up into two functions?
    688689 */
    689 static int hdaR3CmdSync(PPDMDEVINS pDevIns, PHDASTATE pThis, bool fLocal)
     690static int hdaCmdSync(PPDMDEVINS pDevIns, PHDASTATE pThis, bool fLocal)
    690691{
    691692    int rc = VINF_SUCCESS;
     
    701702            rc = PDMDevHlpPhysRead(pDevIns, pThis->u64CORBBase, pThis->au32CorbBuf,
    702703                                   RT_MIN(pThis->cbCorbBuf, sizeof(pThis->au32CorbBuf)));
    703             Log(("hdaR3CmdSync/CORB: read %RGp LB %#x (%Rrc)\n", pThis->u64CORBBase, pThis->cbCorbBuf, rc));
     704            Log3Func(("CORB: read %RGp LB %#x (%Rrc)\n", pThis->u64CORBBase, pThis->cbCorbBuf, rc));
    704705            AssertRCReturn(rc, rc);
    705706        }
     
    713714            rc = PDMDevHlpPCIPhysWrite(pDevIns, pThis->u64RIRBBase, pThis->au64RirbBuf,
    714715                                       RT_MIN(pThis->cbRirbBuf, sizeof(pThis->au64RirbBuf)));
    715             Log(("hdaR3CmdSync/RIRB: phys read %RGp LB %#x (%Rrc)\n", pThis->u64RIRBBase, pThis->cbRirbBuf, rc));
     716            Log3Func(("RIRB: phys read %RGp LB %#x (%Rrc)\n", pThis->u64RIRBBase, pThis->cbRirbBuf, rc));
    716717            AssertRCReturn(rc, rc);
    717718        }
     
    762763}
    763764
    764 /**
    765  * Processes the next CORB buffer command in the queue.
     765#ifdef IN_RING3
     766
     767/**
     768 * Processes the next CORB buffer command in the queue (ring-3).
    766769 *
    767  * This will invoke the HDA codec verb dispatcher.
     770 * Note: This function only will be called when the ring-0 version did not have an appropriate dispatcher.
     771 *
     772 * This will invoke the HDA codec ring-3 verb dispatcher.
    768773 *
    769774 * @returns VBox status code suitable for MMIO write return.
    770775 * @param   pDevIns             The device instance.
    771776 * @param   pThis               The shared HDA device state.
    772  * @param   pThisCC             The ring-3 HDA device state.
     777 * @param   pThisCC             The ring-0 HDA device state.
    773778 */
    774779static int hdaR3CORBCmdProcess(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC)
    775780{
    776     Log3Func(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));
     781    Log3Func(("ENTER CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));
    777782
    778783    if (!(HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA))
     
    782787    }
    783788
     789    /* Note: Command buffer syncing was already done in R0. */
     790
    784791    Assert(pThis->cbCorbBuf);
    785792
    786     int rc = hdaR3CmdSync(pDevIns, pThis, true /* Sync from guest */);
    787     AssertRCReturn(rc, rc);
     793    int rc;
    788794
    789795    /*
     
    795801
    796802    uint32_t const cCorbEntries = RT_MIN(RT_MAX(pThis->cbCorbBuf, 1), sizeof(pThis->au32CorbBuf)) / HDA_CORB_ELEMENT_SIZE;
    797     uint8_t const corbWp       = HDA_REG(pThis, CORBWP) % cCorbEntries;
     803    uint8_t  const corbWp       = HDA_REG(pThis, CORBWP) % cCorbEntries;
    798804    uint8_t        corbRp       = HDA_REG(pThis, CORBRP);
    799805    uint8_t        rirbWp       = HDA_REG(pThis, RIRBWP);
     
    813819         */
    814820        uint64_t uResp = 0;
    815         rc = pThisCC->pCodec->pfnLookup(pThisCC->pCodec, HDA_CODEC_CMD(uCmd, 0 /* Codec index */), &uResp);
    816         if (RT_FAILURE(rc))
    817             LogFunc(("Codec lookup failed with rc=%Rrc\n", rc));
     821        rc = pThisCC->pCodec->pfnLookup(&pThis->Codec, pThisCC->pCodec, HDA_CODEC_CMD(uCmd, 0 /* Codec index */), &uResp);
     822        if (RT_FAILURE(rc)) /* Can return VERR_NOT_FOUND. */
     823            Log3Func(("Lookup for codec verb %08x failed: %Rrc\n", uCmd, rc));
     824
     825        /* Note: No return here (as we're doing for the ring-0 version);
     826                 we still need to do the interrupt handling below. */
     827
    818828        Log3Func(("Codec verb %08x -> response %016RX64\n", uCmd, uResp));
    819829
     
    874884     * Write out the response.
    875885     */
    876     rc = hdaR3CmdSync(pDevIns, pThis, false /* Sync to guest */);
     886    rc = hdaCmdSync(pDevIns, pThis, false /* Sync to guest */);
    877887    AssertRC(rc);
    878888
     
    881891
    882892#endif /* IN_RING3 */
     893
     894/**
     895 * Processes the next CORB buffer command in the queue (ring-0).
     896 *
     897 * This will invoke the HDA codec verb dispatcher.
     898 *
     899 * @returns VBox status code suitable for MMIO write return.
     900 * @param   pDevIns             The device instance.
     901 * @param   pThis               The shared HDA device state.
     902 * @param   pThisCC             The ring-0 HDA device state.
     903 */
     904static int hdaR0CORBCmdProcess(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER0 pThisCC)
     905{
     906    Log3Func(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));
     907
     908    if (!(HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA))
     909    {
     910        LogFunc(("CORB DMA not active, skipping\n"));
     911        return VINF_SUCCESS;
     912    }
     913
     914    Assert(pThis->cbCorbBuf);
     915
     916    int rc = hdaCmdSync(pDevIns, pThis, true /* Sync from guest */);
     917    AssertRCReturn(rc, rc);
     918
     919    /*
     920     * Prepare local copies of relevant registers.
     921     */
     922    uint16_t cIntCnt = HDA_REG(pThis, RINTCNT) & 0xff;
     923    if (!cIntCnt) /* 0 means 256 interrupts. */
     924        cIntCnt = HDA_MAX_RINTCNT;
     925
     926    uint32_t const cCorbEntries = RT_MIN(RT_MAX(pThis->cbCorbBuf, 1), sizeof(pThis->au32CorbBuf)) / HDA_CORB_ELEMENT_SIZE;
     927    uint8_t  const corbWp       = HDA_REG(pThis, CORBWP) % cCorbEntries;
     928    uint8_t        corbRp       = HDA_REG(pThis, CORBRP);
     929    uint8_t        rirbWp       = HDA_REG(pThis, RIRBWP);
     930
     931    /*
     932     * The loop.
     933     */
     934    Log3Func(("START CORB(RP:%x, WP:%x) RIRBWP:%x, RINTCNT:%RU8/%RU8\n", corbRp, corbWp, rirbWp, pThis->u16RespIntCnt, cIntCnt));
     935    while (corbRp != corbWp)
     936    {
     937        /* Fetch the command from the CORB. */
     938        corbRp = (corbRp + 1) /* Advance +1 as the first command(s) are at CORBWP + 1. */ % cCorbEntries;
     939        uint32_t const uCmd = pThis->au32CorbBuf[corbRp];
     940
     941        /*
     942         * Execute the command.
     943         */
     944        uint64_t uResp = 0;
     945        rc = pThisCC->Codec.pfnLookup(&pThis->Codec, &pThisCC->Codec, HDA_CODEC_CMD(uCmd, 0 /* Codec index */), &uResp);
     946        if (RT_FAILURE(rc)) /* Can return VERR_NOT_FOUND. */
     947        {
     948            Log3Func(("Lookup for codec verb %08x failed: %Rrc\n", uCmd, rc));
     949            return rc;
     950        }
     951        Log3Func(("Codec verb %08x -> response %016RX64\n", uCmd, uResp));
     952
     953        if (   (uResp & CODEC_RESPONSE_UNSOLICITED)
     954            && !(HDA_REG(pThis, GCTL) & HDA_GCTL_UNSOL))
     955        {
     956            LogFunc(("Unexpected unsolicited response.\n"));
     957            HDA_REG(pThis, CORBRP) = corbRp;
     958            /** @todo r=andy No RIRB syncing to guest required in that case? */
     959            /** @todo r=bird: Why isn't RIRBWP updated here.  The response might come
     960             *        after already processing several commands, can't it?  (When you think
     961             *        about it, it is bascially the same question as Andy is asking.) */
     962            return VINF_SUCCESS;
     963        }
     964
     965        /*
     966         * Store the response in the RIRB.
     967         */
     968        AssertCompile(HDA_RIRB_SIZE == RT_ELEMENTS(pThis->au64RirbBuf));
     969        rirbWp = (rirbWp + 1) % HDA_RIRB_SIZE;
     970        pThis->au64RirbBuf[rirbWp] = uResp;
     971
     972        /*
     973         * Send interrupt if needed.
     974         */
     975        bool fSendInterrupt = false;
     976        pThis->u16RespIntCnt++;
     977        if (pThis->u16RespIntCnt >= cIntCnt) /* Response interrupt count reached? */
     978        {
     979            pThis->u16RespIntCnt = 0; /* Reset internal interrupt response counter. */
     980
     981            Log3Func(("Response interrupt count reached (%RU16)\n", pThis->u16RespIntCnt));
     982            fSendInterrupt = true;
     983        }
     984        else if (corbRp == corbWp) /* Did we reach the end of the current command buffer? */
     985        {
     986            Log3Func(("Command buffer empty\n"));
     987            fSendInterrupt = true;
     988        }
     989        if (fSendInterrupt)
     990        {
     991            if (HDA_REG(pThis, RIRBCTL) & HDA_RIRBCTL_RINTCTL) /* Response Interrupt Control (RINTCTL) enabled? */
     992            {
     993                HDA_REG(pThis, RIRBSTS) |= HDA_RIRBSTS_RINTFL;
     994                HDA_PROCESS_INTERRUPT(pDevIns, pThis);
     995            }
     996        }
     997    }
     998
     999    /*
     1000     * Put register locals back.
     1001     */
     1002    Log3Func(("END CORB(RP:%x, WP:%x) RIRBWP:%x, RINTCNT:%RU8/%RU8\n", corbRp, corbWp, rirbWp, pThis->u16RespIntCnt, cIntCnt));
     1003    HDA_REG(pThis, CORBRP) = corbRp;
     1004    HDA_REG(pThis, RIRBWP) = rirbWp;
     1005
     1006    /*
     1007     * Write out the response.
     1008     */
     1009    rc = hdaCmdSync(pDevIns, pThis, false /* Sync to guest */);
     1010    AssertRC(rc);
     1011
     1012    return rc;
     1013}
    8831014
    8841015/* Register access handlers. */
     
    10941225static VBOXSTRICTRC hdaRegWriteCORBCTL(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    10951226{
    1096 #ifdef IN_RING3
    10971227    VBOXSTRICTRC rc = hdaRegWriteU8(pDevIns, pThis, iReg, u32Value);
    10981228    AssertRCSuccess(VBOXSTRICTRC_VAL(rc));
    10991229
    1100     if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* Start DMA engine. */
    1101         rc = hdaR3CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3));
     1230    if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* DMA engine started? */
     1231    {
     1232#ifdef IN_RING3
     1233        /* ignore rc */ hdaR3CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3));
     1234
     1235#else
     1236        if (hdaR0CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER0)) == VERR_NOT_FOUND)
     1237            return VINF_IOM_R3_MMIO_WRITE; /* Try ring-3. */
     1238#endif
     1239    }
    11021240    else
    11031241        LogFunc(("CORB DMA not running, skipping\n"));
    11041242
    1105     return rc;
    1106 #else
    1107     RT_NOREF(pDevIns, pThis, iReg, u32Value);
    1108     return VINF_IOM_R3_MMIO_WRITE;
    1109 #endif
     1243    return VINF_SUCCESS;
    11101244}
    11111245
     
    11671301static VBOXSTRICTRC hdaRegWriteCORBWP(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    11681302{
    1169 #ifdef IN_RING3
    11701303    VBOXSTRICTRC rc = hdaRegWriteU16(pDevIns, pThis, iReg, u32Value);
    11711304    AssertRCSuccess(VBOXSTRICTRC_VAL(rc));
    11721305
    1173     return hdaR3CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3));
     1306#ifdef IN_RING3
     1307    rc = hdaR3CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3));
     1308    if (rc == VERR_NOT_FOUND)
     1309        rc = VINF_SUCCESS;
    11741310#else
    1175     RT_NOREF(pDevIns, pThis, iReg, u32Value);
    1176     return VINF_IOM_R3_MMIO_WRITE;
     1311    rc = hdaR0CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER0));
     1312    if (rc == VERR_NOT_FOUND) /* Try ring-3. */
     1313        rc = VINF_IOM_R3_MMIO_WRITE;
    11771314#endif
     1315
     1316    return rc;
    11781317}
    11791318
     
    16771816            pCfg->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
    16781817
    1679             rc = hdaCodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_FRONT, pCfg);
     1818            rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_FRONT, pCfg);
    16801819        }
    16811820
     
    16921831            pCfg->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
    16931832
    1694             rc = hdaCodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_CENTER_LFE, pCfg);
     1833            rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_CENTER_LFE, pCfg);
    16951834        }
    16961835
     
    17061845            pCfg->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
    17071846
    1708             rc = hdaCodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_REAR, pCfg);
     1847            rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_REAR, pCfg);
    17091848        }
    17101849# endif /* VBOX_WITH_AUDIO_HDA_51_SURROUND */
     
    17351874    {
    17361875        case PDMAUDIORECSRC_LINE:
    1737             rc = hdaCodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_LINE_IN, pCfg);
     1876            rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_LINE_IN, pCfg);
    17381877            break;
    17391878# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    17401879        case PDMAUDIORECSRC_MIC:
    1741             rc = hdaCodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_MIC_IN, pCfg);
     1880            rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_MIC_IN, pCfg);
    17421881            break;
    17431882# endif
     
    18481987        && enmMixerCtl != PDMAUDIOMIXERCTL_UNKNOWN)
    18491988    {
    1850         rc = hdaCodecRemoveStream(pThisCC->pCodec, enmMixerCtl);
     1989        rc = hdaR3CodecRemoveStream(pThisCC->pCodec, enmMixerCtl);
    18511990    }
    18521991
     
    19562095        PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3);
    19572096        uint64_t    uResp   = 0;
    1958         int rc2 = pThisCC->pCodec->pfnLookup(pThisCC->pCodec, HDA_CODEC_CMD(uCmd, 0 /* LUN */), &uResp);
     2097        int rc2 = pThisCC->pCodec->pfnLookup(&pThis->Codec, pThisCC->pCodec, HDA_CODEC_CMD(uCmd, 0 /* LUN */), &uResp);
    19592098        if (RT_FAILURE(rc2))
    19602099            LogFunc(("Codec lookup failed with rc2=%Rrc\n", rc2));
     
    29033042     * Reset the codec.
    29043043     */
    2905     if (   pThisCC->pCodec
    2906         && pThisCC->pCodec->pfnReset)
    2907     {
    2908         pThisCC->pCodec->pfnReset(pThisCC->pCodec);
    2909     }
     3044    hdaCodecReset(&pThis->Codec);
    29103045
    29113046    /*
     
    34923627
    34933628    /* Save Codec nodes states. */
    3494     hdaCodecSaveState(pDevIns, pThisCC->pCodec, pSSM);
     3629    hdaCodecSaveState(pDevIns, &pThis->Codec, pSSM);
    34953630
    34963631    /* Save MMIO registers. */
     
    38233958     * Load Codec nodes states.
    38243959     */
    3825     int rc = hdaCodecLoadState(pDevIns, pThisCC->pCodec, pSSM, uVersion);
     3960    int rc = hdaR3CodecLoadState(pDevIns, &pThis->Codec, pThisCC->pCodec, pSSM, uVersion);
    38263961    if (RT_FAILURE(rc))
    38273962    {
     
    42514386static DECLCALLBACK(void) hdaR3DbgInfoCodecNodes(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    42524387{
     4388    PHDASTATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
    42534389    PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3);
    42544390
    42554391    if (pThisCC->pCodec->pfnDbgListNodes)
    4256         pThisCC->pCodec->pfnDbgListNodes(pThisCC->pCodec, pHlp, pszArgs);
     4392        pThisCC->pCodec->pfnDbgListNodes(&pThis->Codec, pThisCC->pCodec, pHlp, pszArgs);
    42574393    else
    42584394        pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback\n");
     
    42644400static DECLCALLBACK(void) hdaR3DbgInfoCodecSelector(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    42654401{
     4402    PHDASTATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
    42664403    PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3);
    42674404
    42684405    if (pThisCC->pCodec->pfnDbgSelector)
    4269         pThisCC->pCodec->pfnDbgSelector(pThisCC->pCodec, pHlp, pszArgs);
     4406        pThisCC->pCodec->pfnDbgSelector(&pThis->Codec, pThisCC->pCodec, pHlp, pszArgs);
    42704407    else
    42714408        pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback\n");
     
    45104647
    45114648    /* Ditto goes for the codec, which in turn uses the mixer. */
    4512     hdaCodecPowerOff(pThisCC->pCodec);
     4649    hdaR3CodecPowerOff(pThisCC->pCodec);
    45134650
    45144651    /*
     
    45954732    if (pThisCC->pCodec)
    45964733    {
    4597         hdaCodecDestruct(pThisCC->pCodec);
    4598 
    45994734        RTMemFree(pThisCC->pCodec);
    46004735        pThisCC->pCodec = NULL;
    46014736    }
     4737
     4738    hdaCodecDestruct(&pThis->Codec);
    46024739
    46034740    for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
     
    47304867    PDMPciDevSetInterruptPin(  pPciDev, 0x01);   /* 3d ro - INTA#. */
    47314868
    4732 #if defined(HDA_AS_PCI_EXPRESS)
     4869# if defined(HDA_AS_PCI_EXPRESS)
    47334870    PDMPciDevSetCapabilityList(pPciDev, 0x80);
    4734 #elif defined(VBOX_WITH_MSI_DEVICES)
     4871# elif defined(VBOX_WITH_MSI_DEVICES)
    47354872    PDMPciDevSetCapabilityList(pPciDev, 0x60);
    4736 #else
     4873# else
    47374874    PDMPciDevSetCapabilityList(pPciDev, 0x50);   /* ICH6 datasheet 18.1.16 */
    4738 #endif
     4875# endif
    47394876
    47404877    /// @todo r=michaln: If there are really no PDMPciDevSetXx for these, the
     
    47484885    PDMPciDevSetWord(          pPciDev, 0x50 + 2, VBOX_PCI_PM_CAP_DSI | 0x02 /* version, PM1.1 */ );
    47494886
    4750 #ifdef HDA_AS_PCI_EXPRESS
     4887# ifdef HDA_AS_PCI_EXPRESS
    47514888    /* PCI Express */
    47524889    PDMPciDevSetByte(          pPciDev, 0x80 + 0, VBOX_PCI_CAP_ID_EXP); /* PCI_Express */
     
    47894926    /* Slot control 2 */
    47904927    PDMPciDevSetWord(          pPciDev, 0x80 + 56, 0);
    4791 #endif
     4928# endif /* HDA_AS_PCI_EXPRESS */
    47924929
    47934930    /*
     
    48074944    AssertRCReturn(rc, rc);
    48084945
    4809 #ifdef VBOX_WITH_MSI_DEVICES
     4946# ifdef VBOX_WITH_MSI_DEVICES
    48104947    PDMMSIREG MsiReg;
    48114948    RT_ZERO(MsiReg);
     
    48194956        PDMPciDevSetCapabilityList(pPciDev, 0x50);
    48204957    }
    4821 #endif
     4958# endif
    48224959
    48234960    rc = PDMDevHlpSSMRegister(pDevIns, HDA_SAVED_STATE_VERSION, sizeof(*pThis), hdaR3SaveExec, hdaR3LoadExec);
    48244961    AssertRCReturn(rc, rc);
    48254962
    4826 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
     4963# ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
    48274964    LogRel(("HDA: Asynchronous I/O enabled\n"));
    4828 #endif
     4965# endif
    48294966
    48304967    /*
     
    48614998     * Add mixer output sinks.
    48624999     */
    4863 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     5000# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    48645001    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Front", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkFront.pMixSink);
    48655002    AssertRCReturn(rc, rc);
     
    48685005    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Rear", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkRear.pMixSink);
    48695006    AssertRCReturn(rc, rc);
    4870 #else
     5007# else
    48715008    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkFront.pMixSink);
    48725009    AssertRCReturn(rc, rc);
    4873 #endif
     5010# endif /* VBOX_WITH_AUDIO_HDA_51_SURROUND */
    48745011
    48755012    /*
     
    48785015    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThisCC->SinkLineIn.pMixSink);
    48795016    AssertRCReturn(rc, rc);
    4880 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     5017# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    48815018    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThisCC->SinkMicIn.pMixSink);
    48825019    AssertRCReturn(rc, rc);
    4883 #endif
     5020# endif
    48845021
    48855022    /* There is no master volume control. Set the master to max. */
     
    48895026
    48905027    /* Allocate codec. */
    4891     PHDACODEC pCodec = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC));
    4892     pThisCC->pCodec = pCodec;
    4893     AssertReturn(pCodec, VERR_NO_MEMORY);
     5028    PHDACODECR3 pCodecR3 = (PHDACODECR3)RTMemAllocZ(sizeof(HDACODECR3));
     5029    AssertPtrReturn(pCodecR3, VERR_NO_MEMORY);
    48945030
    48955031    /* Set codec callbacks to this controller. */
    4896     pCodec->pDevIns                = pDevIns;
    4897     pCodec->pfnCbMixerAddStream    = hdaR3MixerAddStream;
    4898     pCodec->pfnCbMixerRemoveStream = hdaR3MixerRemoveStream;
    4899     pCodec->pfnCbMixerControl      = hdaR3MixerControl;
    4900     pCodec->pfnCbMixerSetVolume    = hdaR3MixerSetVolume;
    4901 
    4902     /* Construct the codec. */
    4903     rc = hdaCodecConstruct(pDevIns, pCodec, 0 /* Codec index */, pCfg);
     5032    pCodecR3->pDevIns                = pDevIns;
     5033    pCodecR3->pfnCbMixerAddStream    = hdaR3MixerAddStream;
     5034    pCodecR3->pfnCbMixerRemoveStream = hdaR3MixerRemoveStream;
     5035    pCodecR3->pfnCbMixerControl      = hdaR3MixerControl;
     5036    pCodecR3->pfnCbMixerSetVolume    = hdaR3MixerSetVolume;
     5037
     5038    /* Construct the common + R3 codec part. */
     5039    rc = hdaR3CodecConstruct(pDevIns, &pThis->Codec, pCodecR3, 0 /* Codec index */, pCfg);
    49045040    AssertRCReturn(rc, rc);
     5041
     5042    pThisCC->pCodec = pCodecR3;
    49055043
    49065044    /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for
    49075045       verb F20 should provide device/codec recognition. */
    4908     Assert(pCodec->u16VendorId);
    4909     Assert(pCodec->u16DeviceId);
    4910     PDMPciDevSetSubSystemVendorId(pPciDev, pCodec->u16VendorId); /* 2c ro - intel.) */
    4911     PDMPciDevSetSubSystemId(      pPciDev, pCodec->u16DeviceId); /* 2e ro. */
     5046    Assert(pThis->Codec.u16VendorId);
     5047    Assert(pThis->Codec.u16DeviceId);
     5048    PDMPciDevSetSubSystemVendorId(pPciDev, pThis->Codec.u16VendorId); /* 2c ro - intel.) */
     5049    PDMPciDevSetSubSystemId(      pPciDev, pThis->Codec.u16DeviceId); /* 2e ro. */
    49125050
    49135051    /*
     
    49485086    }
    49495087
    4950 #ifdef VBOX_WITH_AUDIO_HDA_ONETIME_INIT
     5088# ifdef VBOX_WITH_AUDIO_HDA_ONETIME_INIT
    49515089    /*
    49525090     * Initialize the driver chain.
     
    49665104
    49675105        bool fValidLineIn = AudioMixerStreamIsValid(pDrv->LineIn.pMixStrm);
    4968 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     5106#  ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    49695107        bool fValidMicIn  = AudioMixerStreamIsValid(pDrv->MicIn.pMixStrm);
    4970 # endif
     5108#  endif
    49715109        bool fValidOut    = AudioMixerStreamIsValid(pDrv->Front.pMixStrm);
    4972 # ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     5110#  ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    49735111        /** @todo Anything to do here? */
    4974 # endif
     5112#  endif
    49755113
    49765114        if (    !fValidLineIn
    4977 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     5115#  ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    49785116             && !fValidMicIn
    4979 # endif
     5117#  endif
    49805118             && !fValidOut)
    49815119        {
     
    49975135                if (BackendCfg.cMaxStreamsIn)
    49985136                {
    4999 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     5137#  ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    50005138                    /* If the audio backend supports two or more input streams at once,
    50015139                     * warn if one of our two inputs (microphone-in and line-in) failed to initialize. */
     
    50085146                        fWarn = !fValidLineIn && !fValidMicIn;
    50095147                    /* Don't warn if our backend is not able of supporting any input streams at all. */
    5010 # else  /* !VBOX_WITH_AUDIO_HDA_MIC_IN */
     5148#  else  /* !VBOX_WITH_AUDIO_HDA_MIC_IN */
    50115149                    /* We only have line-in as input source. */
    50125150                    fWarn = !fValidLineIn;
    5013 # endif /* !VBOX_WITH_AUDIO_HDA_MIC_IN */
     5151#  endif /* !VBOX_WITH_AUDIO_HDA_MIC_IN */
    50145152                }
    50155153
     
    50335171                    len = RTStrPrintf(szMissingStreams, sizeof(szMissingStreams), "PCM Input");
    50345172                }
    5035 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     5173#  ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    50365174                if (!fValidMicIn)
    50375175                {
     
    50405178                                       sizeof(szMissingStreams) - len, len ? ", PCM Microphone" : "PCM Microphone");
    50415179                }
    5042 # endif
     5180#  endif /* VBOX_WITH_AUDIO_HDA_MIC_IN */
    50435181                if (!fValidOut)
    50445182                {
     
    50565194        }
    50575195    }
    5058 #endif /* VBOX_WITH_AUDIO_HDA_ONETIME_INIT */
     5196# endif /* VBOX_WITH_AUDIO_HDA_ONETIME_INIT */
    50595197
    50605198    hdaR3Reset(pDevIns);
     
    51775315{
    51785316    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); /* this shall come first */
    5179     PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
     5317    PHDASTATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
     5318    PHDASTATER0 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER0);
    51805319
    51815320    int rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
     
    51835322
    51845323    rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, hdaMmioWrite, hdaMmioRead, NULL /*pvUser*/);
     5324    AssertRCReturn(rc, rc);
     5325
     5326    /* Construct the R0 codec part. */
     5327    rc = hdaR0CodecConstruct(pDevIns, &pThis->Codec, &pThisCC->Codec);
    51855328    AssertRCReturn(rc, rc);
    51865329
     
    52035346    /* .uSharedVersion = */         42,
    52045347    /* .cbInstanceShared = */       sizeof(HDASTATE),
    5205     /* .cbInstanceCC = */           CTX_EXPR(sizeof(HDASTATER3), 0, 0),
     5348    /* .cbInstanceCC = */           CTX_EXPR(sizeof(HDASTATER3), sizeof(HDASTATER0), 0),
    52065349    /* .cbInstanceRC = */           0,
    52075350    /* .cMaxPciDevices = */         1,
  • trunk/src/VBox/Devices/Audio/DevHDA.h

    r87758 r87799  
    147147    IOMMMIOHANDLE           hMmio;
    148148
     149    /** Shared R0/R3 HDA codec to use. */
     150    HDACODEC                Codec;
     151
    149152#ifdef VBOX_WITH_STATISTICS
    150153    STAMPROFILE             StatIn;
     
    215218#define HDASTATE_ALIGNMENT_CHECK_MAGIC  UINT64_C(0x1298afb75893e059)
    216219
     220/**
     221 * Ring-0 ICH Intel HD audio controller state.
     222 */
     223typedef struct HDASTATER0
     224{
     225    /** Pointer to HDA codec to use. */
     226    HDACODECR0              Codec;
     227} HDASTATER0;
     228/** Pointer to a ring-0 HDA device state.  */
     229typedef HDASTATER0 *PHDASTATER0;
    217230
    218231/**
     
    233246    PDMIBASE                IBase;
    234247    /** Pointer to HDA codec to use. */
    235     R3PTRTYPE(PHDACODEC  pCodec;
     248    R3PTRTYPE(PHDACODECR3)  pCodec;
    236249    /** List of associated LUN drivers (HDADRIVER). */
    237250    RTLISTANCHORR3          lstDrv;
  • trunk/src/VBox/Devices/Audio/HDACodec.cpp

    r87758 r87799  
    2424*********************************************************************************************************************************/
    2525#define LOG_GROUP LOG_GROUP_DEV_HDA_CODEC
     26#include <VBox/log.h>
     27
    2628#include <VBox/AssertGuest.h>
    2729#include <VBox/vmm/pdmdev.h>
    2830#include <VBox/vmm/pdmaudioifs.h>
     31
    2932#include <iprt/assert.h>
    3033#include <iprt/uuid.h>
     
    4447*   Defined Constants And Macros                                                                                                 *
    4548*********************************************************************************************************************************/
    46 /* PRM 5.3.1 */
    47 /** Codec address mask. */
    48 #define CODEC_CAD_MASK                                     0xF0000000
    49 /** Codec address shift. */
    50 #define CODEC_CAD_SHIFT                                    28
    51 #define CODEC_DIRECT_MASK                                  RT_BIT(27)
    52 /** Node ID mask. */
    53 #define CODEC_NID_MASK                                     0x07F00000
    54 /** Node ID shift. */
    55 #define CODEC_NID_SHIFT                                    20
    56 #define CODEC_VERBDATA_MASK                                0x000FFFFF
    57 #define CODEC_VERB_4BIT_CMD                                0x000FFFF0
    58 #define CODEC_VERB_4BIT_DATA                               0x0000000F
    59 #define CODEC_VERB_8BIT_CMD                                0x000FFF00
    60 #define CODEC_VERB_8BIT_DATA                               0x000000FF
    61 #define CODEC_VERB_16BIT_CMD                               0x000F0000
    62 #define CODEC_VERB_16BIT_DATA                              0x0000FFFF
    63 
    64 #define CODEC_CAD(cmd)                                     (((cmd) & CODEC_CAD_MASK) >> CODEC_CAD_SHIFT)
    65 #define CODEC_DIRECT(cmd)                                  ((cmd) & CODEC_DIRECT_MASK)
    66 #define CODEC_NID(cmd)                                     ((((cmd) & CODEC_NID_MASK)) >> CODEC_NID_SHIFT)
    67 #define CODEC_VERBDATA(cmd)                                ((cmd) & CODEC_VERBDATA_MASK)
    68 #define CODEC_VERB_CMD(cmd, mask, x)                       (((cmd) & (mask)) >> (x))
    69 #define CODEC_VERB_CMD4(cmd)                               (CODEC_VERB_CMD((cmd), CODEC_VERB_4BIT_CMD, 4))
    70 #define CODEC_VERB_CMD8(cmd)                               (CODEC_VERB_CMD((cmd), CODEC_VERB_8BIT_CMD, 8))
    71 #define CODEC_VERB_CMD16(cmd)                              (CODEC_VERB_CMD((cmd), CODEC_VERB_16BIT_CMD, 16))
    72 #define CODEC_VERB_PAYLOAD4(cmd)                           ((cmd) & CODEC_VERB_4BIT_DATA)
    73 #define CODEC_VERB_PAYLOAD8(cmd)                           ((cmd) & CODEC_VERB_8BIT_DATA)
    74 #define CODEC_VERB_PAYLOAD16(cmd)                          ((cmd) & CODEC_VERB_16BIT_DATA)
    75 
    76 #define CODEC_VERB_GET_AMP_DIRECTION                       RT_BIT(15)
    77 #define CODEC_VERB_GET_AMP_SIDE                            RT_BIT(13)
    78 #define CODEC_VERB_GET_AMP_INDEX                           0x7
    79 
    80 /* HDA spec 7.3.3.7 NoteA */
    81 #define CODEC_GET_AMP_DIRECTION(cmd)                       (((cmd) & CODEC_VERB_GET_AMP_DIRECTION) >> 15)
    82 #define CODEC_GET_AMP_SIDE(cmd)                            (((cmd) & CODEC_VERB_GET_AMP_SIDE) >> 13)
    83 #define CODEC_GET_AMP_INDEX(cmd)                           (CODEC_GET_AMP_DIRECTION(cmd) ? 0 : ((cmd) & CODEC_VERB_GET_AMP_INDEX))
    84 
    85 /* HDA spec 7.3.3.7 NoteC */
    86 #define CODEC_VERB_SET_AMP_OUT_DIRECTION                   RT_BIT(15)
    87 #define CODEC_VERB_SET_AMP_IN_DIRECTION                    RT_BIT(14)
    88 #define CODEC_VERB_SET_AMP_LEFT_SIDE                       RT_BIT(13)
    89 #define CODEC_VERB_SET_AMP_RIGHT_SIDE                      RT_BIT(12)
    90 #define CODEC_VERB_SET_AMP_INDEX                           (0x7 << 8)
    91 #define CODEC_VERB_SET_AMP_MUTE                            RT_BIT(7)
    92 /** Note: 7-bit value [6:0]. */
    93 #define CODEC_VERB_SET_AMP_GAIN                            0x7F
    94 
    95 #define CODEC_SET_AMP_IS_OUT_DIRECTION(cmd)                (((cmd) & CODEC_VERB_SET_AMP_OUT_DIRECTION) != 0)
    96 #define CODEC_SET_AMP_IS_IN_DIRECTION(cmd)                 (((cmd) & CODEC_VERB_SET_AMP_IN_DIRECTION) != 0)
    97 #define CODEC_SET_AMP_IS_LEFT_SIDE(cmd)                    (((cmd) & CODEC_VERB_SET_AMP_LEFT_SIDE) != 0)
    98 #define CODEC_SET_AMP_IS_RIGHT_SIDE(cmd)                   (((cmd) & CODEC_VERB_SET_AMP_RIGHT_SIDE) != 0)
    99 #define CODEC_SET_AMP_INDEX(cmd)                           (((cmd) & CODEC_VERB_SET_AMP_INDEX) >> 7)
    100 #define CODEC_SET_AMP_MUTE(cmd)                            ((cmd) & CODEC_VERB_SET_AMP_MUTE)
    101 #define CODEC_SET_AMP_GAIN(cmd)                            ((cmd) & CODEC_VERB_SET_AMP_GAIN)
    102 
    103 /* HDA spec 7.3.3.1 defines layout of configuration registers/verbs (0xF00) */
    104 /* VendorID (7.3.4.1) */
    105 #define CODEC_MAKE_F00_00(vendorID, deviceID)              (((vendorID) << 16) | (deviceID))
    106 #define CODEC_F00_00_VENDORID(f00_00)                      (((f00_00) >> 16) & 0xFFFF)
    107 #define CODEC_F00_00_DEVICEID(f00_00)                      ((f00_00) & 0xFFFF)
    108 
    109 /** RevisionID (7.3.4.2). */
    110 #define CODEC_MAKE_F00_02(majRev, minRev, venFix, venProg, stepFix, stepProg) \
    111     (  (((majRev)   & 0xF) << 20) \
    112      | (((minRev)   & 0xF) << 16) \
    113      | (((venFix)   & 0xF) << 12) \
    114      | (((venProg)  & 0xF) << 8)  \
    115      | (((stepFix)  & 0xF) << 4)  \
    116      |  ((stepProg) & 0xF))
    117 
    118 /** Subordinate node count (7.3.4.3). */
    119 #define CODEC_MAKE_F00_04(startNodeNumber, totalNodeNumber) ((((startNodeNumber) & 0xFF) << 16)|((totalNodeNumber) & 0xFF))
    120 #define CODEC_F00_04_TO_START_NODE_NUMBER(f00_04)          (((f00_04) >> 16) & 0xFF)
    121 #define CODEC_F00_04_TO_NODE_COUNT(f00_04)                 ((f00_04) & 0xFF)
    122 /*
    123  * Function Group Type  (7.3.4.4)
    124  * 0 & [0x3-0x7f] are reserved types
    125  * [0x80 - 0xff] are vendor defined function groups
    126  */
    127 #define CODEC_MAKE_F00_05(UnSol, NodeType)                 (((UnSol) << 8)|(NodeType))
    128 #define CODEC_F00_05_UNSOL                                 RT_BIT(8)
    129 #define CODEC_F00_05_AFG                                   (0x1)
    130 #define CODEC_F00_05_MFG                                   (0x2)
    131 #define CODEC_F00_05_IS_UNSOL(f00_05)                      RT_BOOL((f00_05) & RT_BIT(8))
    132 #define CODEC_F00_05_GROUP(f00_05)                         ((f00_05) & 0xff)
    133 /* Audio Function Group capabilities (7.3.4.5). */
    134 #define CODEC_MAKE_F00_08(BeepGen, InputDelay, OutputDelay) ((((BeepGen) & 0x1) << 16)| (((InputDelay) & 0xF) << 8) | ((OutputDelay) & 0xF))
    135 #define CODEC_F00_08_BEEP_GEN(f00_08)                      ((f00_08) & RT_BIT(16)
    136 
    137 /* Converter Stream, Channel (7.3.3.11). */
    138 #define CODEC_F00_06_GET_STREAM_ID(cmd)                    (((cmd) >> 4) & 0x0F)
    139 #define CODEC_F00_06_GET_CHANNEL_ID(cmd)                   (((cmd) & 0x0F))
    140 
    141 /* Widget Capabilities (7.3.4.6). */
    142 #define CODEC_MAKE_F00_09(type, delay, chan_ext) \
    143     ( (((type)     & 0xF) << 20)            \
    144     | (((delay)    & 0xF) << 16)           \
    145     | (((chan_ext) & 0xF) << 13))
    146 /* note: types 0x8-0xe are reserved */
    147 #define CODEC_F00_09_TYPE_AUDIO_OUTPUT                     (0x0)
    148 #define CODEC_F00_09_TYPE_AUDIO_INPUT                      (0x1)
    149 #define CODEC_F00_09_TYPE_AUDIO_MIXER                      (0x2)
    150 #define CODEC_F00_09_TYPE_AUDIO_SELECTOR                   (0x3)
    151 #define CODEC_F00_09_TYPE_PIN_COMPLEX                      (0x4)
    152 #define CODEC_F00_09_TYPE_POWER_WIDGET                     (0x5)
    153 #define CODEC_F00_09_TYPE_VOLUME_KNOB                      (0x6)
    154 #define CODEC_F00_09_TYPE_BEEP_GEN                         (0x7)
    155 #define CODEC_F00_09_TYPE_VENDOR_DEFINED                   (0xF)
    156 
    157 #define CODEC_F00_09_CAP_CP                                RT_BIT(12)
    158 #define CODEC_F00_09_CAP_L_R_SWAP                          RT_BIT(11)
    159 #define CODEC_F00_09_CAP_POWER_CTRL                        RT_BIT(10)
    160 #define CODEC_F00_09_CAP_DIGITAL                           RT_BIT(9)
    161 #define CODEC_F00_09_CAP_CONNECTION_LIST                   RT_BIT(8)
    162 #define CODEC_F00_09_CAP_UNSOL                             RT_BIT(7)
    163 #define CODEC_F00_09_CAP_PROC_WIDGET                       RT_BIT(6)
    164 #define CODEC_F00_09_CAP_STRIPE                            RT_BIT(5)
    165 #define CODEC_F00_09_CAP_FMT_OVERRIDE                      RT_BIT(4)
    166 #define CODEC_F00_09_CAP_AMP_FMT_OVERRIDE                  RT_BIT(3)
    167 #define CODEC_F00_09_CAP_OUT_AMP_PRESENT                   RT_BIT(2)
    168 #define CODEC_F00_09_CAP_IN_AMP_PRESENT                    RT_BIT(1)
    169 #define CODEC_F00_09_CAP_STEREO                            RT_BIT(0)
    170 
    171 #define CODEC_F00_09_TYPE(f00_09)                          (((f00_09) >> 20) & 0xF)
    172 
    173 #define CODEC_F00_09_IS_CAP_CP(f00_09)                     RT_BOOL((f00_09) & RT_BIT(12))
    174 #define CODEC_F00_09_IS_CAP_L_R_SWAP(f00_09)               RT_BOOL((f00_09) & RT_BIT(11))
    175 #define CODEC_F00_09_IS_CAP_POWER_CTRL(f00_09)             RT_BOOL((f00_09) & RT_BIT(10))
    176 #define CODEC_F00_09_IS_CAP_DIGITAL(f00_09)                RT_BOOL((f00_09) & RT_BIT(9))
    177 #define CODEC_F00_09_IS_CAP_CONNECTION_LIST(f00_09)        RT_BOOL((f00_09) & RT_BIT(8))
    178 #define CODEC_F00_09_IS_CAP_UNSOL(f00_09)                  RT_BOOL((f00_09) & RT_BIT(7))
    179 #define CODEC_F00_09_IS_CAP_PROC_WIDGET(f00_09)            RT_BOOL((f00_09) & RT_BIT(6))
    180 #define CODEC_F00_09_IS_CAP_STRIPE(f00_09)                 RT_BOOL((f00_09) & RT_BIT(5))
    181 #define CODEC_F00_09_IS_CAP_FMT_OVERRIDE(f00_09)           RT_BOOL((f00_09) & RT_BIT(4))
    182 #define CODEC_F00_09_IS_CAP_AMP_OVERRIDE(f00_09)           RT_BOOL((f00_09) & RT_BIT(3))
    183 #define CODEC_F00_09_IS_CAP_OUT_AMP_PRESENT(f00_09)        RT_BOOL((f00_09) & RT_BIT(2))
    184 #define CODEC_F00_09_IS_CAP_IN_AMP_PRESENT(f00_09)         RT_BOOL((f00_09) & RT_BIT(1))
    185 #define CODEC_F00_09_IS_CAP_LSB(f00_09)                    RT_BOOL((f00_09) & RT_BIT(0))
    186 
    187 /* Supported PCM size, rates (7.3.4.7) */
    188 #define CODEC_F00_0A_32_BIT                                RT_BIT(19)
    189 #define CODEC_F00_0A_24_BIT                                RT_BIT(18)
    190 #define CODEC_F00_0A_16_BIT                                RT_BIT(17)
    191 #define CODEC_F00_0A_8_BIT                                 RT_BIT(16)
    192 
    193 #define CODEC_F00_0A_48KHZ_MULT_8X                         RT_BIT(11)
    194 #define CODEC_F00_0A_48KHZ_MULT_4X                         RT_BIT(10)
    195 #define CODEC_F00_0A_44_1KHZ_MULT_4X                       RT_BIT(9)
    196 #define CODEC_F00_0A_48KHZ_MULT_2X                         RT_BIT(8)
    197 #define CODEC_F00_0A_44_1KHZ_MULT_2X                       RT_BIT(7)
    198 #define CODEC_F00_0A_48KHZ                                 RT_BIT(6)
    199 #define CODEC_F00_0A_44_1KHZ                               RT_BIT(5)
    200 /* 2/3 * 48kHz */
    201 #define CODEC_F00_0A_48KHZ_2_3X                            RT_BIT(4)
    202 /* 1/2 * 44.1kHz */
    203 #define CODEC_F00_0A_44_1KHZ_1_2X                          RT_BIT(3)
    204 /* 1/3 * 48kHz */
    205 #define CODEC_F00_0A_48KHZ_1_3X                            RT_BIT(2)
    206 /* 1/4 * 44.1kHz */
    207 #define CODEC_F00_0A_44_1KHZ_1_4X                          RT_BIT(1)
    208 /* 1/6 * 48kHz */
    209 #define CODEC_F00_0A_48KHZ_1_6X                            RT_BIT(0)
    210 
    211 /* Supported streams formats (7.3.4.8) */
    212 #define CODEC_F00_0B_AC3                                   RT_BIT(2)
    213 #define CODEC_F00_0B_FLOAT32                               RT_BIT(1)
    214 #define CODEC_F00_0B_PCM                                   RT_BIT(0)
    215 
    216 /* Pin Capabilities (7.3.4.9)*/
    217 #define CODEC_MAKE_F00_0C(vref_ctrl) (((vref_ctrl) & 0xFF) << 8)
    218 #define CODEC_F00_0C_CAP_HBR                               RT_BIT(27)
    219 #define CODEC_F00_0C_CAP_DP                                RT_BIT(24)
    220 #define CODEC_F00_0C_CAP_EAPD                              RT_BIT(16)
    221 #define CODEC_F00_0C_CAP_HDMI                              RT_BIT(7)
    222 #define CODEC_F00_0C_CAP_BALANCED_IO                       RT_BIT(6)
    223 #define CODEC_F00_0C_CAP_INPUT                             RT_BIT(5)
    224 #define CODEC_F00_0C_CAP_OUTPUT                            RT_BIT(4)
    225 #define CODEC_F00_0C_CAP_HEADPHONE_AMP                     RT_BIT(3)
    226 #define CODEC_F00_0C_CAP_PRESENCE_DETECT                   RT_BIT(2)
    227 #define CODEC_F00_0C_CAP_TRIGGER_REQUIRED                  RT_BIT(1)
    228 #define CODEC_F00_0C_CAP_IMPENDANCE_SENSE                  RT_BIT(0)
    229 
    230 #define CODEC_F00_0C_IS_CAP_HBR(f00_0c)                    ((f00_0c) & RT_BIT(27))
    231 #define CODEC_F00_0C_IS_CAP_DP(f00_0c)                     ((f00_0c) & RT_BIT(24))
    232 #define CODEC_F00_0C_IS_CAP_EAPD(f00_0c)                   ((f00_0c) & RT_BIT(16))
    233 #define CODEC_F00_0C_IS_CAP_HDMI(f00_0c)                   ((f00_0c) & RT_BIT(7))
    234 #define CODEC_F00_0C_IS_CAP_BALANCED_IO(f00_0c)            ((f00_0c) & RT_BIT(6))
    235 #define CODEC_F00_0C_IS_CAP_INPUT(f00_0c)                  ((f00_0c) & RT_BIT(5))
    236 #define CODEC_F00_0C_IS_CAP_OUTPUT(f00_0c)                 ((f00_0c) & RT_BIT(4))
    237 #define CODEC_F00_0C_IS_CAP_HP(f00_0c)                     ((f00_0c) & RT_BIT(3))
    238 #define CODEC_F00_0C_IS_CAP_PRESENCE_DETECT(f00_0c)        ((f00_0c) & RT_BIT(2))
    239 #define CODEC_F00_0C_IS_CAP_TRIGGER_REQUIRED(f00_0c)       ((f00_0c) & RT_BIT(1))
    240 #define CODEC_F00_0C_IS_CAP_IMPENDANCE_SENSE(f00_0c)       ((f00_0c) & RT_BIT(0))
    241 
    242 /* Input Amplifier capabilities (7.3.4.10). */
    243 #define CODEC_MAKE_F00_0D(mute_cap, step_size, num_steps, offset) \
    244         (  (((mute_cap)  & UINT32_C(0x1))  << 31) \
    245          | (((step_size) & UINT32_C(0xFF)) << 16) \
    246          | (((num_steps) & UINT32_C(0xFF)) << 8) \
    247          |  ((offset)    & UINT32_C(0xFF)))
    248 
    249 #define CODEC_F00_0D_CAP_MUTE                              RT_BIT(7)
    250 
    251 #define CODEC_F00_0D_IS_CAP_MUTE(f00_0d)                   ( ( f00_0d) & RT_BIT(31))
    252 #define CODEC_F00_0D_STEP_SIZE(f00_0d)                     ((( f00_0d) & (0x7F << 16)) >> 16)
    253 #define CODEC_F00_0D_NUM_STEPS(f00_0d)                     ((((f00_0d) & (0x7F << 8)) >> 8) + 1)
    254 #define CODEC_F00_0D_OFFSET(f00_0d)                        (  (f00_0d) & 0x7F)
    255 
    256 /** Indicates that the amplifier can be muted. */
    257 #define CODEC_AMP_CAP_MUTE                                 0x1
    258 /** The amplifier's maximum number of steps. We want
    259  *  a ~90dB dynamic range, so 64 steps with 1.25dB each
    260  *  should do the trick.
    261  *
    262  *  As we want to map our range to [0..128] values we can avoid
    263  *  multiplication and simply doing a shift later.
    264  *
    265  *  Produces -96dB to +0dB.
    266  *  "0" indicates a step of 0.25dB, "127" indicates a step of 32dB.
    267  */
    268 #define CODEC_AMP_NUM_STEPS                                0x7F
    269 /** The initial gain offset (and when doing a node reset). */
    270 #define CODEC_AMP_OFF_INITIAL                              0x7F
    271 /** The amplifier's gain step size. */
    272 #define CODEC_AMP_STEP_SIZE                                0x2
    273 
    274 /* Output Amplifier capabilities (7.3.4.10) */
    275 #define CODEC_MAKE_F00_12                                  CODEC_MAKE_F00_0D
    276 
    277 #define CODEC_F00_12_IS_CAP_MUTE(f00_12)                   CODEC_F00_0D_IS_CAP_MUTE(f00_12)
    278 #define CODEC_F00_12_STEP_SIZE(f00_12)                     CODEC_F00_0D_STEP_SIZE(f00_12)
    279 #define CODEC_F00_12_NUM_STEPS(f00_12)                     CODEC_F00_0D_NUM_STEPS(f00_12)
    280 #define CODEC_F00_12_OFFSET(f00_12)                        CODEC_F00_0D_OFFSET(f00_12)
    281 
    282 /* Connection list lenght (7.3.4.11). */
    283 #define CODEC_MAKE_F00_0E(long_form, length)    \
    284     (  (((long_form) & 0x1) << 7)               \
    285      | ((length) & 0x7F))
    286 /* Indicates short-form NIDs. */
    287 #define CODEC_F00_0E_LIST_NID_SHORT                        0
    288 /* Indicates long-form NIDs. */
    289 #define CODEC_F00_0E_LIST_NID_LONG                         1
    290 #define CODEC_F00_0E_IS_LONG(f00_0e)                       RT_BOOL((f00_0e) & RT_BIT(7))
    291 #define CODEC_F00_0E_COUNT(f00_0e)                         ((f00_0e) & 0x7F)
    292 /* Supported Power States (7.3.4.12) */
    293 #define CODEC_F00_0F_EPSS                                  RT_BIT(31)
    294 #define CODEC_F00_0F_CLKSTOP                               RT_BIT(30)
    295 #define CODEC_F00_0F_S3D3                                  RT_BIT(29)
    296 #define CODEC_F00_0F_D3COLD                                RT_BIT(4)
    297 #define CODEC_F00_0F_D3                                    RT_BIT(3)
    298 #define CODEC_F00_0F_D2                                    RT_BIT(2)
    299 #define CODEC_F00_0F_D1                                    RT_BIT(1)
    300 #define CODEC_F00_0F_D0                                    RT_BIT(0)
    301 
    302 /* Processing capabilities 7.3.4.13 */
    303 #define CODEC_MAKE_F00_10(num, benign)                     ((((num) & 0xFF) << 8) | ((benign) & 0x1))
    304 #define CODEC_F00_10_NUM(f00_10)                           (((f00_10) & (0xFF << 8)) >> 8)
    305 #define CODEC_F00_10_BENING(f00_10)                        ((f00_10) & 0x1)
    306 
    307 /* GPIO count (7.3.4.14). */
    308 #define CODEC_MAKE_F00_11(wake, unsol, numgpi, numgpo, numgpio) \
    309     (  (((wake)   & UINT32_C(0x1))  << 31) \
    310      | (((unsol)  & UINT32_C(0x1))  << 30) \
    311      | (((numgpi) & UINT32_C(0xFF)) << 16) \
    312      | (((numgpo) & UINT32_C(0xFF)) << 8) \
    313      | ((numgpio) & UINT32_C(0xFF)))
    314 
    315 /* Processing States (7.3.3.4). */
    316 #define CODEC_F03_OFF                                      (0)
    317 #define CODEC_F03_ON                                       RT_BIT(0)
    318 #define CODEC_F03_BENING                                   RT_BIT(1)
    319 /* Power States (7.3.3.10). */
    320 #define CODEC_MAKE_F05(reset, stopok, error, act, set) \
    321     (  (((reset)  & 0x1) << 10) \
    322      | (((stopok) & 0x1) << 9) \
    323      | (((error)  & 0x1) << 8) \
    324      | (((act)    & 0xF) << 4) \
    325      | ((set)     & 0xF))
    326 #define CODEC_F05_D3COLD                                   (4)
    327 #define CODEC_F05_D3                                       (3)
    328 #define CODEC_F05_D2                                       (2)
    329 #define CODEC_F05_D1                                       (1)
    330 #define CODEC_F05_D0                                       (0)
    331 
    332 #define CODEC_F05_IS_RESET(value)                          (((value) & RT_BIT(10)) != 0)
    333 #define CODEC_F05_IS_STOPOK(value)                         (((value) & RT_BIT(9)) != 0)
    334 #define CODEC_F05_IS_ERROR(value)                          (((value) & RT_BIT(8)) != 0)
    335 #define CODEC_F05_ACT(value)                               (((value) & 0xF0) >> 4)
    336 #define CODEC_F05_SET(value)                               (((value) & 0xF))
    337 
    338 #define CODEC_F05_GE(p0, p1)                               ((p0) <= (p1))
    339 #define CODEC_F05_LE(p0, p1)                               ((p0) >= (p1))
    340 
    341 /* Converter Stream, Channel (7.3.3.11). */
    342 #define CODEC_MAKE_F06(stream, channel) \
    343     (  (((stream)  & 0xF) << 4)         \
    344      |  ((channel) & 0xF))
    345 #define CODEC_F06_STREAM(value)                            ((value) & 0xF0)
    346 #define CODEC_F06_CHANNEL(value)                           ((value) & 0xF)
    347 
    348 /* Pin Widged Control (7.3.3.13). */
    349 #define CODEC_F07_VREF_HIZ                                 (0)
    350 #define CODEC_F07_VREF_50                                  (0x1)
    351 #define CODEC_F07_VREF_GROUND                              (0x2)
    352 #define CODEC_F07_VREF_80                                  (0x4)
    353 #define CODEC_F07_VREF_100                                 (0x5)
    354 #define CODEC_F07_IN_ENABLE                                RT_BIT(5)
    355 #define CODEC_F07_OUT_ENABLE                               RT_BIT(6)
    356 #define CODEC_F07_OUT_H_ENABLE                             RT_BIT(7)
    357 
    358 /* Volume Knob Control (7.3.3.29). */
    359 #define CODEC_F0F_IS_DIRECT                                RT_BIT(7)
    360 #define CODEC_F0F_VOLUME                                   (0x7F)
    361 
    362 /* Unsolicited enabled (7.3.3.14). */
    363 #define CODEC_MAKE_F08(enable, tag) ((((enable) & 1) << 7) | ((tag) & 0x3F))
    364 
    365 /* Converter formats (7.3.3.8) and (3.7.1). */
    366 /* This is the same format as SDnFMT. */
    367 #define CODEC_MAKE_A                                       HDA_SDFMT_MAKE
    368 
    369 #define CODEC_A_TYPE                                       HDA_SDFMT_TYPE
    370 #define CODEC_A_TYPE_PCM                                   HDA_SDFMT_TYPE_PCM
    371 #define CODEC_A_TYPE_NON_PCM                               HDA_SDFMT_TYPE_NON_PCM
    372 
    373 #define CODEC_A_BASE                                       HDA_SDFMT_BASE
    374 #define CODEC_A_BASE_48KHZ                                 HDA_SDFMT_BASE_48KHZ
    375 #define CODEC_A_BASE_44KHZ                                 HDA_SDFMT_BASE_44KHZ
    376 
    377 /* Pin Sense (7.3.3.15). */
    378 #define CODEC_MAKE_F09_ANALOG(fPresent, impedance)  \
    379 (  (((fPresent) & 0x1) << 31)                       \
    380  | (((impedance) & UINT32_C(0x7FFFFFFF))))
    381 #define CODEC_F09_ANALOG_NA    UINT32_C(0x7FFFFFFF)
    382 #define CODEC_MAKE_F09_DIGITAL(fPresent, fELDValid) \
    383 (   (((fPresent)  & UINT32_C(0x1)) << 31)                      \
    384   | (((fELDValid) & UINT32_C(0x1)) << 30))
    385 
    386 #define CODEC_MAKE_F0C(lrswap, eapd, btl) ((((lrswap) & 1) << 2) | (((eapd) & 1) << 1) | ((btl) & 1))
    387 #define CODEC_FOC_IS_LRSWAP(f0c)                           RT_BOOL((f0c) & RT_BIT(2))
    388 #define CODEC_FOC_IS_EAPD(f0c)                             RT_BOOL((f0c) & RT_BIT(1))
    389 #define CODEC_FOC_IS_BTL(f0c)                              RT_BOOL((f0c) & RT_BIT(0))
    390 /* HDA spec 7.3.3.31 defines layout of configuration registers/verbs (0xF1C) */
    391 /* Configuration's port connection */
    392 #define CODEC_F1C_PORT_MASK                                (0x3)
    393 #define CODEC_F1C_PORT_SHIFT                               (30)
    394 
    395 #define CODEC_F1C_PORT_COMPLEX                             (0x0)
    396 #define CODEC_F1C_PORT_NO_PHYS                             (0x1)
    397 #define CODEC_F1C_PORT_FIXED                               (0x2)
    398 #define CODEC_F1C_BOTH                                     (0x3)
    399 
    400 /* Configuration default: connection */
    401 #define CODEC_F1C_PORT_MASK                                (0x3)
    402 #define CODEC_F1C_PORT_SHIFT                               (30)
    403 
    404 /* Connected to a jack (1/8", ATAPI, ...). */
    405 #define CODEC_F1C_PORT_COMPLEX                             (0x0)
    406 /* No physical connection. */
    407 #define CODEC_F1C_PORT_NO_PHYS                             (0x1)
    408 /* Fixed function device (integrated speaker, integrated mic, ...). */
    409 #define CODEC_F1C_PORT_FIXED                               (0x2)
    410 /* Both, a jack and an internal device are attached. */
    411 #define CODEC_F1C_BOTH                                     (0x3)
    412 
    413 /* Configuration default: Location */
    414 #define CODEC_F1C_LOCATION_MASK                            (0x3F)
    415 #define CODEC_F1C_LOCATION_SHIFT                           (24)
    416 
    417 /* [4:5] bits of location region means chassis attachment */
    418 #define CODEC_F1C_LOCATION_PRIMARY_CHASSIS                 (0)
    419 #define CODEC_F1C_LOCATION_INTERNAL                        RT_BIT(4)
    420 #define CODEC_F1C_LOCATION_SECONDRARY_CHASSIS              RT_BIT(5)
    421 #define CODEC_F1C_LOCATION_OTHER                           RT_BIT(5)
    422 
    423 /* [0:3] bits of location region means geometry location attachment */
    424 #define CODEC_F1C_LOCATION_NA                              (0)
    425 #define CODEC_F1C_LOCATION_REAR                            (0x1)
    426 #define CODEC_F1C_LOCATION_FRONT                           (0x2)
    427 #define CODEC_F1C_LOCATION_LEFT                            (0x3)
    428 #define CODEC_F1C_LOCATION_RIGTH                           (0x4)
    429 #define CODEC_F1C_LOCATION_TOP                             (0x5)
    430 #define CODEC_F1C_LOCATION_BOTTOM                          (0x6)
    431 #define CODEC_F1C_LOCATION_SPECIAL_0                       (0x7)
    432 #define CODEC_F1C_LOCATION_SPECIAL_1                       (0x8)
    433 #define CODEC_F1C_LOCATION_SPECIAL_2                       (0x9)
    434 
    435 /* Configuration default: Device type */
    436 #define CODEC_F1C_DEVICE_MASK                              (0xF)
    437 #define CODEC_F1C_DEVICE_SHIFT                             (20)
    438 #define CODEC_F1C_DEVICE_LINE_OUT                          (0)
    439 #define CODEC_F1C_DEVICE_SPEAKER                           (0x1)
    440 #define CODEC_F1C_DEVICE_HP                                (0x2)
    441 #define CODEC_F1C_DEVICE_CD                                (0x3)
    442 #define CODEC_F1C_DEVICE_SPDIF_OUT                         (0x4)
    443 #define CODEC_F1C_DEVICE_DIGITAL_OTHER_OUT                 (0x5)
    444 #define CODEC_F1C_DEVICE_MODEM_LINE_SIDE                   (0x6)
    445 #define CODEC_F1C_DEVICE_MODEM_HANDSET_SIDE                (0x7)
    446 #define CODEC_F1C_DEVICE_LINE_IN                           (0x8)
    447 #define CODEC_F1C_DEVICE_AUX                               (0x9)
    448 #define CODEC_F1C_DEVICE_MIC                               (0xA)
    449 #define CODEC_F1C_DEVICE_PHONE                             (0xB)
    450 #define CODEC_F1C_DEVICE_SPDIF_IN                          (0xC)
    451 #define CODEC_F1C_DEVICE_RESERVED                          (0xE)
    452 #define CODEC_F1C_DEVICE_OTHER                             (0xF)
    453 
    454 /* Configuration default: Connection type */
    455 #define CODEC_F1C_CONNECTION_TYPE_MASK                     (0xF)
    456 #define CODEC_F1C_CONNECTION_TYPE_SHIFT                    (16)
    457 
    458 #define CODEC_F1C_CONNECTION_TYPE_UNKNOWN                  (0)
    459 #define CODEC_F1C_CONNECTION_TYPE_1_8INCHES                (0x1)
    460 #define CODEC_F1C_CONNECTION_TYPE_1_4INCHES                (0x2)
    461 #define CODEC_F1C_CONNECTION_TYPE_ATAPI                    (0x3)
    462 #define CODEC_F1C_CONNECTION_TYPE_RCA                      (0x4)
    463 #define CODEC_F1C_CONNECTION_TYPE_OPTICAL                  (0x5)
    464 #define CODEC_F1C_CONNECTION_TYPE_OTHER_DIGITAL            (0x6)
    465 #define CODEC_F1C_CONNECTION_TYPE_ANALOG                   (0x7)
    466 #define CODEC_F1C_CONNECTION_TYPE_DIN                      (0x8)
    467 #define CODEC_F1C_CONNECTION_TYPE_XLR                      (0x9)
    468 #define CODEC_F1C_CONNECTION_TYPE_RJ_11                    (0xA)
    469 #define CODEC_F1C_CONNECTION_TYPE_COMBO                    (0xB)
    470 #define CODEC_F1C_CONNECTION_TYPE_OTHER                    (0xF)
    471 
    472 /* Configuration's color */
    473 #define CODEC_F1C_COLOR_MASK                               (0xF)
    474 #define CODEC_F1C_COLOR_SHIFT                              (12)
    475 #define CODEC_F1C_COLOR_UNKNOWN                            (0)
    476 #define CODEC_F1C_COLOR_BLACK                              (0x1)
    477 #define CODEC_F1C_COLOR_GREY                               (0x2)
    478 #define CODEC_F1C_COLOR_BLUE                               (0x3)
    479 #define CODEC_F1C_COLOR_GREEN                              (0x4)
    480 #define CODEC_F1C_COLOR_RED                                (0x5)
    481 #define CODEC_F1C_COLOR_ORANGE                             (0x6)
    482 #define CODEC_F1C_COLOR_YELLOW                             (0x7)
    483 #define CODEC_F1C_COLOR_PURPLE                             (0x8)
    484 #define CODEC_F1C_COLOR_PINK                               (0x9)
    485 #define CODEC_F1C_COLOR_RESERVED_0                         (0xA)
    486 #define CODEC_F1C_COLOR_RESERVED_1                         (0xB)
    487 #define CODEC_F1C_COLOR_RESERVED_2                         (0xC)
    488 #define CODEC_F1C_COLOR_RESERVED_3                         (0xD)
    489 #define CODEC_F1C_COLOR_WHITE                              (0xE)
    490 #define CODEC_F1C_COLOR_OTHER                              (0xF)
    491 
    492 /* Configuration's misc */
    493 #define CODEC_F1C_MISC_MASK                                (0xF)
    494 #define CODEC_F1C_MISC_SHIFT                               (8)
    495 #define CODEC_F1C_MISC_NONE                                0
    496 #define CODEC_F1C_MISC_JACK_NO_PRESENCE_DETECT             RT_BIT(0)
    497 #define CODEC_F1C_MISC_RESERVED_0                          RT_BIT(1)
    498 #define CODEC_F1C_MISC_RESERVED_1                          RT_BIT(2)
    499 #define CODEC_F1C_MISC_RESERVED_2                          RT_BIT(3)
    500 
    501 /* Configuration default: Association */
    502 #define CODEC_F1C_ASSOCIATION_MASK                         (0xF)
    503 #define CODEC_F1C_ASSOCIATION_SHIFT                        (4)
    504 
    505 /** Reserved; don't use. */
    506 #define CODEC_F1C_ASSOCIATION_INVALID                      0x0
    507 #define CODEC_F1C_ASSOCIATION_GROUP_0                      0x1
    508 #define CODEC_F1C_ASSOCIATION_GROUP_1                      0x2
    509 #define CODEC_F1C_ASSOCIATION_GROUP_2                      0x3
    510 #define CODEC_F1C_ASSOCIATION_GROUP_3                      0x4
    511 #define CODEC_F1C_ASSOCIATION_GROUP_4                      0x5
    512 #define CODEC_F1C_ASSOCIATION_GROUP_5                      0x6
    513 #define CODEC_F1C_ASSOCIATION_GROUP_6                      0x7
    514 #define CODEC_F1C_ASSOCIATION_GROUP_7                      0x8
    515 /* Note: Windows OSes will treat group 15 (0xF) as single PIN devices.
    516  *       The sequence number associated with that group then will be ignored. */
    517 #define CODEC_F1C_ASSOCIATION_GROUP_15                     0xF
    518 
    519 /* Configuration default: Association Sequence. */
    520 #define CODEC_F1C_SEQ_MASK                                 (0xF)
    521 #define CODEC_F1C_SEQ_SHIFT                                (0)
    522 
    523 /* Implementation identification (7.3.3.30). */
    524 #define CODEC_MAKE_F20(bmid, bsku, aid)     \
    525     (  (((bmid) & 0xFFFF) << 16)            \
    526      | (((bsku) & 0xFF) << 8)               \
    527      | (((aid) & 0xFF))                     \
    528     )
    529 
    530 /* Macro definition helping in filling the configuration registers. */
    531 #define CODEC_MAKE_F1C(port_connectivity, location, device, connection_type, color, misc, association, sequence)    \
    532     (  (((port_connectivity) & 0xF) << CODEC_F1C_PORT_SHIFT)            \
    533      | (((location)          & 0xF) << CODEC_F1C_LOCATION_SHIFT)        \
    534      | (((device)            & 0xF) << CODEC_F1C_DEVICE_SHIFT)          \
    535      | (((connection_type)   & 0xF) << CODEC_F1C_CONNECTION_TYPE_SHIFT) \
    536      | (((color)             & 0xF) << CODEC_F1C_COLOR_SHIFT)           \
    537      | (((misc)              & 0xF) << CODEC_F1C_MISC_SHIFT)            \
    538      | (((association)       & 0xF) << CODEC_F1C_ASSOCIATION_SHIFT)     \
    539      | (((sequence)          & 0xF)))
    540 
    541 
    542 /*********************************************************************************************************************************
    543 *   Structures and Typedefs                                                                                                      *
    544 *********************************************************************************************************************************/
    545 /** The F00 parameter length (in dwords). */
    546 #define CODECNODE_F00_PARAM_LENGTH  20
    547 /** The F02 parameter length (in dwords). */
    548 #define CODECNODE_F02_PARAM_LENGTH  16
    549 
    550 /**
    551  * Common (or core) codec node structure.
    552  */
    553 typedef struct CODECCOMMONNODE
    554 {
    555     /** The node's ID. */
    556     uint8_t         uID;
    557     /** The node's name. */
    558     char const     *pszName;
    559     /** The SDn ID this node is assigned to.
    560      *  0 means not assigned, 1 is SDn0. */
    561     uint8_t         uSD;
    562     /** The SDn's channel to use.
    563      *  Only valid if a valid SDn ID is set. */
    564     uint8_t         uChannel;
    565     /* PRM 5.3.6 */
    566     uint32_t au32F00_param[CODECNODE_F00_PARAM_LENGTH];
    567     uint32_t au32F02_param[CODECNODE_F02_PARAM_LENGTH];
    568 } CODECCOMMONNODE;
    569 typedef CODECCOMMONNODE *PCODECCOMMONNODE;
    570 AssertCompile(CODECNODE_F00_PARAM_LENGTH == 20);  /* saved state */
    571 AssertCompile(CODECNODE_F02_PARAM_LENGTH == 16); /* saved state */
    572 
    573 /**
    574  * Compile time assertion on the expected node size.
    575  */
    576 #define AssertNodeSize(a_Node, a_cParams) \
    577     AssertCompile((a_cParams) <= (60 + 6)); /* the max size - saved state */ \
    578     AssertCompile(   sizeof(a_Node) - sizeof(CODECCOMMONNODE)  \
    579                   == (((a_cParams) * sizeof(uint32_t) + sizeof(void *) - 1) & ~(sizeof(void *) - 1)) )
    580 
    581 typedef struct ROOTCODECNODE
    582 {
    583     CODECCOMMONNODE node;
    584 } ROOTCODECNODE, *PROOTCODECNODE;
    585 AssertNodeSize(ROOTCODECNODE, 0);
    586 
    587 #define AMPLIFIER_SIZE 60
    588 typedef uint32_t AMPLIFIER[AMPLIFIER_SIZE];
     49
     50
    58951#define AMPLIFIER_IN    0
    59052#define AMPLIFIER_OUT   1
     
    59254#define AMPLIFIER_RIGHT 0
    59355#define AMPLIFIER_REGISTER(amp, inout, side, index) ((amp)[30*(inout) + 15*(side) + (index)])
    594 typedef struct DACNODE
    595 {
    596     CODECCOMMONNODE node;
    597     uint32_t    u32F0d_param;
    598     uint32_t    u32F04_param;
    599     uint32_t    u32F05_param;
    600     uint32_t    u32F06_param;
    601     uint32_t    u32F0c_param;
    602 
    603     uint32_t    u32A_param;
    604     AMPLIFIER   B_params;
    605 
    606 } DACNODE, *PDACNODE;
    607 AssertNodeSize(DACNODE, 6 + 60);
    608 
    609 typedef struct ADCNODE
    610 {
    611     CODECCOMMONNODE node;
    612     uint32_t    u32F01_param;
    613     uint32_t    u32F03_param;
    614     uint32_t    u32F05_param;
    615     uint32_t    u32F06_param;
    616     uint32_t    u32F09_param;
    617 
    618     uint32_t    u32A_param;
    619     AMPLIFIER   B_params;
    620 } ADCNODE, *PADCNODE;
    621 AssertNodeSize(DACNODE, 6 + 60);
    622 
    623 typedef struct SPDIFOUTNODE
    624 {
    625     CODECCOMMONNODE node;
    626     uint32_t    u32F05_param;
    627     uint32_t    u32F06_param;
    628     uint32_t    u32F09_param;
    629     uint32_t    u32F0d_param;
    630 
    631     uint32_t    u32A_param;
    632     AMPLIFIER   B_params;
    633 } SPDIFOUTNODE, *PSPDIFOUTNODE;
    634 AssertNodeSize(SPDIFOUTNODE, 5 + 60);
    635 
    636 typedef struct SPDIFINNODE
    637 {
    638     CODECCOMMONNODE node;
    639     uint32_t    u32F05_param;
    640     uint32_t    u32F06_param;
    641     uint32_t    u32F09_param;
    642     uint32_t    u32F0d_param;
    643 
    644     uint32_t    u32A_param;
    645     AMPLIFIER   B_params;
    646 } SPDIFINNODE, *PSPDIFINNODE;
    647 AssertNodeSize(SPDIFINNODE, 5 + 60);
    648 
    649 typedef struct AFGCODECNODE
    650 {
    651     CODECCOMMONNODE node;
    652     uint32_t  u32F05_param;
    653     uint32_t  u32F08_param;
    654     uint32_t  u32F17_param;
    655     uint32_t  u32F20_param;
    656 } AFGCODECNODE, *PAFGCODECNODE;
    657 AssertNodeSize(AFGCODECNODE, 4);
    658 
    659 typedef struct PORTNODE
    660 {
    661     CODECCOMMONNODE node;
    662     uint32_t u32F01_param;
    663     uint32_t u32F07_param;
    664     uint32_t u32F08_param;
    665     uint32_t u32F09_param;
    666     uint32_t u32F1c_param;
    667     AMPLIFIER   B_params;
    668 } PORTNODE, *PPORTNODE;
    669 AssertNodeSize(PORTNODE, 5 + 60);
    670 
    671 typedef struct DIGOUTNODE
    672 {
    673     CODECCOMMONNODE node;
    674     uint32_t u32F01_param;
    675     uint32_t u32F05_param;
    676     uint32_t u32F07_param;
    677     uint32_t u32F08_param;
    678     uint32_t u32F09_param;
    679     uint32_t u32F1c_param;
    680 } DIGOUTNODE, *PDIGOUTNODE;
    681 AssertNodeSize(DIGOUTNODE, 6);
    682 
    683 typedef struct DIGINNODE
    684 {
    685     CODECCOMMONNODE node;
    686     uint32_t u32F05_param;
    687     uint32_t u32F07_param;
    688     uint32_t u32F08_param;
    689     uint32_t u32F09_param;
    690     uint32_t u32F0c_param;
    691     uint32_t u32F1c_param;
    692     uint32_t u32F1e_param;
    693 } DIGINNODE, *PDIGINNODE;
    694 AssertNodeSize(DIGINNODE, 7);
    695 
    696 typedef struct ADCMUXNODE
    697 {
    698     CODECCOMMONNODE node;
    699     uint32_t    u32F01_param;
    700 
    701     uint32_t    u32A_param;
    702     AMPLIFIER   B_params;
    703 } ADCMUXNODE, *PADCMUXNODE;
    704 AssertNodeSize(ADCMUXNODE, 2 + 60);
    705 
    706 typedef struct PCBEEPNODE
    707 {
    708     CODECCOMMONNODE node;
    709     uint32_t    u32F07_param;
    710     uint32_t    u32F0a_param;
    711 
    712     uint32_t    u32A_param;
    713     AMPLIFIER   B_params;
    714     uint32_t    u32F1c_param;
    715 } PCBEEPNODE, *PPCBEEPNODE;
    716 AssertNodeSize(PCBEEPNODE, 3 + 60 + 1);
    717 
    718 typedef struct CDNODE
    719 {
    720     CODECCOMMONNODE node;
    721     uint32_t u32F07_param;
    722     uint32_t u32F1c_param;
    723 } CDNODE, *PCDNODE;
    724 AssertNodeSize(CDNODE, 2);
    725 
    726 typedef struct VOLUMEKNOBNODE
    727 {
    728     CODECCOMMONNODE node;
    729     uint32_t    u32F08_param;
    730     uint32_t    u32F0f_param;
    731 } VOLUMEKNOBNODE, *PVOLUMEKNOBNODE;
    732 AssertNodeSize(VOLUMEKNOBNODE, 2);
    733 
    734 typedef struct ADCVOLNODE
    735 {
    736     CODECCOMMONNODE node;
    737     uint32_t    u32F0c_param;
    738     uint32_t    u32F01_param;
    739     uint32_t    u32A_params;
    740     AMPLIFIER   B_params;
    741 } ADCVOLNODE, *PADCVOLNODE;
    742 AssertNodeSize(ADCVOLNODE, 3 + 60);
    743 
    744 typedef struct RESNODE
    745 {
    746     CODECCOMMONNODE node;
    747     uint32_t    u32F05_param;
    748     uint32_t    u32F06_param;
    749     uint32_t    u32F07_param;
    750     uint32_t    u32F1c_param;
    751 
    752     uint32_t    u32A_param;
    753 } RESNODE, *PRESNODE;
    754 AssertNodeSize(RESNODE, 5);
    755 
    756 /**
    757  * Used for the saved state.
    758  */
    759 typedef struct CODECSAVEDSTATENODE
    760 {
    761     CODECCOMMONNODE Core;
    762     uint32_t        au32Params[60 + 6];
    763 } CODECSAVEDSTATENODE;
    764 AssertNodeSize(CODECSAVEDSTATENODE, 60 + 6);
    765 
    766 typedef union CODECNODE
    767 {
    768     CODECCOMMONNODE node;
    769     ROOTCODECNODE   root;
    770     AFGCODECNODE    afg;
    771     DACNODE         dac;
    772     ADCNODE         adc;
    773     SPDIFOUTNODE    spdifout;
    774     SPDIFINNODE     spdifin;
    775     PORTNODE        port;
    776     DIGOUTNODE      digout;
    777     DIGINNODE       digin;
    778     ADCMUXNODE      adcmux;
    779     PCBEEPNODE      pcbeep;
    780     CDNODE          cdnode;
    781     VOLUMEKNOBNODE  volumeKnob;
    782     ADCVOLNODE      adcvol;
    783     RESNODE         reserved;
    784     CODECSAVEDSTATENODE SavedState;
    785 } CODECNODE, *PCODECNODE;
    786 AssertNodeSize(CODECNODE, 60 + 6);
    78756
    78857
     
    845114static uint8_t const g_abStac9220Reserveds[]  = { STAC9220_NID_SPDIF_IN, STAC9221_NID_ADAT_OUT, STAC9221_NID_I2S_OUT, STAC9221_NID_PIN_I2S_OUT, 0 };
    846115
    847 /** SSM description of a CODECNODE. */
     116#ifdef IN_RING3
     117
     118/** SSM description of CODECCOMMONNODE. */
    848119static SSMFIELD const g_aCodecNodeFields[] =
    849120{
     
    856127};
    857128
    858 /** Backward compatibility with v1 of the CODECNODE. */
     129/** Backward compatibility with v1 of CODECCOMMONNODE. */
    859130static SSMFIELD const g_aCodecNodeFieldsV1[] =
    860131{
     
    868139};
    869140
    870 
     141#endif /* IN_RING3 */
    871142
    872143#if 0 /* unused */
     
    876147    for (uint8_t i = 1; i < pThis->cTotalNodes; i++)
    877148    {
    878         PCODECNODE pNode = &pThis->paNodes[i];
     149        PCODECNODE pNode = &pThis->aNodes[i];
    879150        AMPLIFIER *pAmp = &pNode->dac.B_params;
    880151
     
    886157}
    887158#endif
    888 
    889 /**
    890  * Resets the codec with all its connected nodes.
    891  *
    892  * @param   pThis               HDA codec to reset.
    893  */
    894 static DECLCALLBACK(void) stac9220Reset(PHDACODEC pThis)
    895 {
    896     AssertPtrReturnVoid(pThis->paNodes);
    897     AssertPtrReturnVoid(pThis->pfnNodeReset);
    898 
    899     LogRel(("HDA: Codec reset\n"));
    900 
    901     pThis->fInReset = true;
    902 
    903     for (uint8_t i = 0; i < pThis->cTotalNodes; i++)
    904         pThis->pfnNodeReset(pThis, i, &pThis->paNodes[i]);
    905 
    906     pThis->fInReset = false;
    907 }
    908159
    909160/**
    910161 * Resets a single node of the codec.
    911162 *
    912  * @returns IPRT status code.
    913163 * @param   pThis               HDA codec of node to reset.
    914164 * @param   uNID                Node ID to set node to.
    915165 * @param   pNode               Node to reset.
    916166 */
    917 static DECLCALLBACK(int) stac9220ResetNode(PHDACODEC pThis, uint8_t uNID, PCODECNODE pNode)
     167static void stac9220NodeReset(PHDACODEC pThis, uint8_t uNID, PCODECNODE pNode)
    918168{
    919169    LogFlowFunc(("NID=0x%x (%RU8)\n", uNID, uNID));
     
    1062312
    1063313            /* Use a fixed format from AFG. */
    1064             pNode->spdifout.node.au32F00_param[0xA] = pThis->paNodes[STAC9220_NID_AFG].node.au32F00_param[0xA];
     314            pNode->spdifout.node.au32F00_param[0xA] = pThis->aNodes[STAC9220_NID_AFG].node.au32F00_param[0xA];
    1065315            pNode->spdifout.node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
    1066316            break;
     
    1080330
    1081331            /* Use a fixed format from AFG. */
    1082             pNode->spdifin.node.au32F00_param[0xA] = pThis->paNodes[STAC9220_NID_AFG].node.au32F00_param[0xA];
     332            pNode->spdifin.node.au32F00_param[0xA] = pThis->aNodes[STAC9220_NID_AFG].node.au32F00_param[0xA];
    1083333            pNode->spdifin.node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
    1084334
     
    1475725            break;
    1476726    }
    1477 
    1478     return VINF_SUCCESS;
     727}
     728
     729/**
     730 * Resets the codec with all its connected nodes.
     731 *
     732 * @param   pThis               HDA codec to reset.
     733 */
     734static DECLCALLBACK(void) stac9220Reset(PHDACODEC pThis)
     735{
     736    AssertPtrReturnVoid(pThis->aNodes);
     737
     738    LogRel(("HDA: Codec reset\n"));
     739
     740    pThis->fInReset = true;
     741
     742    for (uint8_t i = 0; i < pThis->cTotalNodes; i++)
     743        stac9220NodeReset(pThis, i, &pThis->aNodes[i]);
     744
     745    pThis->fInReset = false;
    1479746}
    1480747
    1481748static int stac9220Construct(PHDACODEC pThis)
    1482749{
    1483     unconst(pThis->cTotalNodes) = STAC9221_NUM_NODES;
    1484 
    1485     pThis->pfnReset     = stac9220Reset;
    1486     pThis->pfnNodeReset = stac9220ResetNode;
    1487 
    1488750    pThis->u16VendorId  = 0x8384; /* SigmaTel */
    1489751    /*
     
    1496758    pThis->u8AssemblyId = 0x80;
    1497759
    1498     pThis->paNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pThis->cTotalNodes);
    1499     if (!pThis->paNodes)
    1500         return VERR_NO_MEMORY;
    1501 
    1502760    pThis->fInReset = false;
    1503761
    1504 #define STAC9220WIDGET(type) pThis->au8##type##s = g_abStac9220##type##s
     762#define STAC9220WIDGET(type) memcpy(&pThis->au8##type##s, &g_abStac9220##type##s, sizeof(uint8_t) * RT_ELEMENTS(g_abStac9220##type##s));
    1505763    STAC9220WIDGET(Port);
    1506764    STAC9220WIDGET(Dac);
     
    1518776#undef STAC9220WIDGET
    1519777
    1520     unconst(pThis->u8AdcVolsLineIn) = STAC9220_NID_AMP_ADC0;
    1521     unconst(pThis->u8DacLineOut)    = STAC9220_NID_DAC1;
     778    pThis->cTotalNodes = STAC9221_NUM_NODES;
     779    Assert(pThis->cTotalNodes <= CODEC_NODES_MAX);
     780
     781    pThis->u8AdcVolsLineIn = STAC9220_NID_AMP_ADC0;
     782    pThis->u8DacLineOut    = STAC9220_NID_DAC1;
    1522783
    1523784    /*
     
    1528789     *       initialize the node default configuration values then!
    1529790     */
    1530     AssertPtr(pThis->paNodes);
    1531     AssertPtr(pThis->pfnNodeReset);
    1532 
    1533791    for (uint8_t i = 0; i < pThis->cTotalNodes; i++)
    1534     {
    1535         int rc2 = stac9220ResetNode(pThis, i, &pThis->paNodes[i]);
    1536         AssertRC(rc2);
    1537     }
     792        stac9220NodeReset(pThis, i, &pThis->aNodes[i]);
     793
     794    /* Common root node initializers. */
     795    pThis->aNodes[STAC9220_NID_ROOT].root.node.au32F00_param[0] = CODEC_MAKE_F00_00(pThis->u16VendorId, pThis->u16DeviceId);
     796    pThis->aNodes[STAC9220_NID_ROOT].root.node.au32F00_param[4] = CODEC_MAKE_F00_04(0x1, 0x1);
     797
     798    /* Common AFG node initializers. */
     799    pThis->aNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0x4] = CODEC_MAKE_F00_04(0x2, pThis->cTotalNodes - 2);
     800    pThis->aNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0x5] = CODEC_MAKE_F00_05(1, CODEC_F00_05_AFG);
     801    pThis->aNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0xA] = CODEC_F00_0A_44_1KHZ | CODEC_F00_0A_16_BIT;
     802    pThis->aNodes[STAC9220_NID_AFG].afg.u32F20_param = CODEC_MAKE_F20(pThis->u16VendorId, pThis->u8BSKU, pThis->u8AssemblyId);
    1538803
    1539804    return VINF_SUCCESS;
     
    1581846DECLISNODEOFTYPE(Reserved)
    1582847
     848#ifdef IN_RING3
    1583849
    1584850/*
    1585851 * Misc helpers.
    1586852 */
    1587 static int hdaCodecToAudVolume(PHDACODEC pThis, PCODECNODE pNode, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL enmMixerCtl)
     853static int hdaR3CodecToAudVolume(PHDACODECR3 pThisCC, PCODECNODE pNode, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL enmMixerCtl)
    1588854{
    1589855    RT_NOREF(pNode);
     
    1631897             DrvAudioHlpAudMixerCtlToStr(enmMixerCtl), lVol, rVol, RT_BOOL(iMute) ? "Muted" : "Unmuted"));
    1632898
    1633     return pThis->pfnCbMixerSetVolume(pThis->pDevIns, enmMixerCtl, &Vol);
    1634 }
     899    return pThisCC->pfnCbMixerSetVolume(pThisCC->pDevIns, enmMixerCtl, &Vol);
     900}
     901
     902#endif /* IN_RING3 */
    1635903
    1636904DECLINLINE(void) hdaCodecSetRegister(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset, uint32_t mask)
     
    1685953    uint8_t u8Index = CODEC_GET_AMP_DIRECTION(cmd) == AMPLIFIER_OUT ? 0 : CODEC_GET_AMP_INDEX(cmd);
    1686954
    1687     PCODECNODE pNode = &pThis->paNodes[CODEC_NID(cmd)];
     955    PCODECNODE pNode = &pThis->aNodes[CODEC_NID(cmd)];
    1688956    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    1689957        *pResp = AMPLIFIER_REGISTER(pNode->dac.B_params,
     
    1722990}
    1723991
     992#ifdef IN_RING3
     993
    1724994/* 3-- */
    1725 static DECLCALLBACK(int) vrbProcSetAmplifier(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1726 {
    1727     *pResp = 0;
    1728 
    1729     PCODECNODE pNode      = &pThis->paNodes[CODEC_NID(cmd)];
     995static DECLCALLBACK(int) vrbProcR3SetAmplifier(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *pResp)
     996{
     997    *pResp = 0;
     998
     999    PCODECNODE pNode      = &pThis->aNodes[CODEC_NID(cmd)];
    17301000    AMPLIFIER *pAmplifier = NULL;
    17311001    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
     
    17701040    //    if (CODEC_NID(cmd) == pThis->u8AdcVolsLineIn)
    17711041    //    {
    1772             hdaCodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
     1042            hdaR3CodecToAudVolume(pThisCC, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
    17731043    //    }
    17741044    }
     
    17811051
    17821052        if (CODEC_NID(cmd) == pThis->u8DacLineOut)
    1783             hdaCodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_FRONT);
    1784     }
    1785 
    1786     return VINF_SUCCESS;
    1787 }
     1053            hdaR3CodecToAudVolume(pThisCC, pNode, pAmplifier, PDMAUDIOMIXERCTL_FRONT);
     1054    }
     1055
     1056    return VINF_SUCCESS;
     1057}
     1058
     1059#endif /* IN_RING3 */
    17881060
    17891061static DECLCALLBACK(int) vrbProcGetParameter(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     
    17981070    }
    17991071
    1800     *pResp = pThis->paNodes[CODEC_NID(cmd)].node.au32F00_param[cmd & CODEC_VERB_8BIT_DATA];
     1072    *pResp = pThis->aNodes[CODEC_NID(cmd)].node.au32F00_param[cmd & CODEC_VERB_8BIT_DATA];
    18011073    return VINF_SUCCESS;
    18021074}
     
    18081080
    18091081    if (hdaCodecIsAdcMuxNode(pThis, CODEC_NID(cmd)))
    1810         *pResp = pThis->paNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
     1082        *pResp = pThis->aNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
    18111083    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
    1812         *pResp = pThis->paNodes[CODEC_NID(cmd)].digout.u32F01_param;
     1084        *pResp = pThis->aNodes[CODEC_NID(cmd)].digout.u32F01_param;
    18131085    else if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    1814         *pResp = pThis->paNodes[CODEC_NID(cmd)].port.u32F01_param;
     1086        *pResp = pThis->aNodes[CODEC_NID(cmd)].port.u32F01_param;
    18151087    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    1816         *pResp = pThis->paNodes[CODEC_NID(cmd)].adc.u32F01_param;
     1088        *pResp = pThis->aNodes[CODEC_NID(cmd)].adc.u32F01_param;
    18171089    else if (hdaCodecIsAdcVolNode(pThis, CODEC_NID(cmd)))
    1818         *pResp = pThis->paNodes[CODEC_NID(cmd)].adcvol.u32F01_param;
     1090        *pResp = pThis->aNodes[CODEC_NID(cmd)].adcvol.u32F01_param;
    18191091    else
    18201092        LogRel2(("HDA: Warning: Unhandled get connection select control command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    18301102    uint32_t *pu32Reg = NULL;
    18311103    if (hdaCodecIsAdcMuxNode(pThis, CODEC_NID(cmd)))
    1832         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
     1104        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
    18331105    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
    1834         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digout.u32F01_param;
     1106        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digout.u32F01_param;
    18351107    else if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    1836         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].port.u32F01_param;
     1108        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].port.u32F01_param;
    18371109    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    1838         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adc.u32F01_param;
     1110        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].adc.u32F01_param;
    18391111    else if (hdaCodecIsAdcVolNode(pThis, CODEC_NID(cmd)))
    1840         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adcvol.u32F01_param;
     1112        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].adcvol.u32F01_param;
    18411113    else
    18421114        LogRel2(("HDA: Warning: Unhandled set connection select control command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    18541126
    18551127    if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    1856         *pResp = pThis->paNodes[CODEC_NID(cmd)].port.u32F07_param;
     1128        *pResp = pThis->aNodes[CODEC_NID(cmd)].port.u32F07_param;
    18571129    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
    1858         *pResp = pThis->paNodes[CODEC_NID(cmd)].digout.u32F07_param;
     1130        *pResp = pThis->aNodes[CODEC_NID(cmd)].digout.u32F07_param;
    18591131    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    1860         *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F07_param;
     1132        *pResp = pThis->aNodes[CODEC_NID(cmd)].digin.u32F07_param;
    18611133    else if (hdaCodecIsCdNode(pThis, CODEC_NID(cmd)))
    1862         *pResp = pThis->paNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
     1134        *pResp = pThis->aNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
    18631135    else if (hdaCodecIsPcbeepNode(pThis, CODEC_NID(cmd)))
    1864         *pResp = pThis->paNodes[CODEC_NID(cmd)].pcbeep.u32F07_param;
     1136        *pResp = pThis->aNodes[CODEC_NID(cmd)].pcbeep.u32F07_param;
    18651137    else if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
    1866         *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F07_param;
     1138        *pResp = pThis->aNodes[CODEC_NID(cmd)].reserved.u32F07_param;
    18671139    else
    18681140        LogRel2(("HDA: Warning: Unhandled get pin control command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    18781150    uint32_t *pu32Reg = NULL;
    18791151    if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    1880         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].port.u32F07_param;
     1152        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].port.u32F07_param;
    18811153    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    1882         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F07_param;
     1154        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digin.u32F07_param;
    18831155    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
    1884         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digout.u32F07_param;
     1156        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digout.u32F07_param;
    18851157    else if (hdaCodecIsCdNode(pThis, CODEC_NID(cmd)))
    1886         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
     1158        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
    18871159    else if (hdaCodecIsPcbeepNode(pThis, CODEC_NID(cmd)))
    1888         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].pcbeep.u32F07_param;
     1160        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].pcbeep.u32F07_param;
    18891161    else if (   hdaCodecIsReservedNode(pThis, CODEC_NID(cmd))
    18901162             && CODEC_NID(cmd) == 0x1b)
    1891         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F07_param;
     1163        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].reserved.u32F07_param;
    18921164    else
    18931165        LogRel2(("HDA: Warning: Unhandled set pin control command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    19051177
    19061178    if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    1907         *pResp = pThis->paNodes[CODEC_NID(cmd)].port.u32F08_param;
     1179        *pResp = pThis->aNodes[CODEC_NID(cmd)].port.u32F08_param;
    19081180    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    1909         *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param;
     1181        *pResp = pThis->aNodes[CODEC_NID(cmd)].digin.u32F08_param;
    19101182    else if ((cmd) == STAC9220_NID_AFG)
    1911         *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F08_param;
     1183        *pResp = pThis->aNodes[CODEC_NID(cmd)].afg.u32F08_param;
    19121184    else if (hdaCodecIsVolKnobNode(pThis, CODEC_NID(cmd)))
    1913         *pResp = pThis->paNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
     1185        *pResp = pThis->aNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
    19141186    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
    1915         *pResp = pThis->paNodes[CODEC_NID(cmd)].digout.u32F08_param;
     1187        *pResp = pThis->aNodes[CODEC_NID(cmd)].digout.u32F08_param;
    19161188    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    1917         *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param;
     1189        *pResp = pThis->aNodes[CODEC_NID(cmd)].digin.u32F08_param;
    19181190    else
    19191191        LogRel2(("HDA: Warning: Unhandled get unsolicited enabled command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    19291201    uint32_t *pu32Reg = NULL;
    19301202    if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    1931         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].port.u32F08_param;
     1203        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].port.u32F08_param;
    19321204    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    1933         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param;
     1205        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digin.u32F08_param;
    19341206    else if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    1935         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F08_param;
     1207        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].afg.u32F08_param;
    19361208    else if (hdaCodecIsVolKnobNode(pThis, CODEC_NID(cmd)))
    1937         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
     1209        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
    19381210    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    1939         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param;
     1211        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digin.u32F08_param;
    19401212    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
    1941         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digout.u32F08_param;
     1213        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digout.u32F08_param;
    19421214    else
    19431215        LogRel2(("HDA: Warning: Unhandled set unsolicited enabled command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    19551227
    19561228    if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    1957         *pResp = pThis->paNodes[CODEC_NID(cmd)].port.u32F09_param;
     1229        *pResp = pThis->aNodes[CODEC_NID(cmd)].port.u32F09_param;
    19581230    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    1959         *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F09_param;
     1231        *pResp = pThis->aNodes[CODEC_NID(cmd)].digin.u32F09_param;
    19601232    else
    19611233    {
     
    19741246    uint32_t *pu32Reg = NULL;
    19751247    if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    1976         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].port.u32F09_param;
     1248        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].port.u32F09_param;
    19771249    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    1978         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F09_param;
     1250        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digin.u32F09_param;
    19791251    else
    19801252        LogRel2(("HDA: Warning: Unhandled set pin sense command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    19961268        return VINF_SUCCESS;
    19971269    }
    1998     *pResp = pThis->paNodes[CODEC_NID(cmd)].node.au32F02_param[cmd & CODEC_VERB_8BIT_DATA];
     1270    *pResp = pThis->aNodes[CODEC_NID(cmd)].node.au32F02_param[cmd & CODEC_VERB_8BIT_DATA];
    19991271    return VINF_SUCCESS;
    20001272}
     
    20061278
    20071279    if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    2008         *pResp = pThis->paNodes[CODEC_NID(cmd)].adc.u32F03_param;
     1280        *pResp = pThis->aNodes[CODEC_NID(cmd)].adc.u32F03_param;
    20091281
    20101282    return VINF_SUCCESS;
     
    20171289
    20181290    if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    2019         hdaCodecSetRegisterU8(&pThis->paNodes[CODEC_NID(cmd)].adc.u32F03_param, cmd, 0);
     1291        hdaCodecSetRegisterU8(&pThis->aNodes[CODEC_NID(cmd)].adc.u32F03_param, cmd, 0);
    20201292    return VINF_SUCCESS;
    20211293}
     
    20271299
    20281300    if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    2029         *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifout.u32F0d_param;
     1301        *pResp = pThis->aNodes[CODEC_NID(cmd)].spdifout.u32F0d_param;
    20301302    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    2031         *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifin.u32F0d_param;
     1303        *pResp = pThis->aNodes[CODEC_NID(cmd)].spdifin.u32F0d_param;
    20321304
    20331305    return VINF_SUCCESS;
     
    20391311
    20401312    if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    2041         hdaCodecSetRegisterU8(&pThis->paNodes[CODEC_NID(cmd)].spdifout.u32F0d_param, cmd, u8Offset);
     1313        hdaCodecSetRegisterU8(&pThis->aNodes[CODEC_NID(cmd)].spdifout.u32F0d_param, cmd, u8Offset);
    20421314    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    2043         hdaCodecSetRegisterU8(&pThis->paNodes[CODEC_NID(cmd)].spdifin.u32F0d_param, cmd, u8Offset);
     1315        hdaCodecSetRegisterU8(&pThis->aNodes[CODEC_NID(cmd)].spdifin.u32F0d_param, cmd, u8Offset);
    20441316    return VINF_SUCCESS;
    20451317}
     
    20681340    }
    20691341    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    2070         *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F20_param;
     1342        *pResp = pThis->aNodes[CODEC_NID(cmd)].afg.u32F20_param;
    20711343    else
    20721344        *pResp = 0;
     
    20851357    uint32_t *pu32Reg;
    20861358    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    2087         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F20_param;
     1359        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].afg.u32F20_param;
    20881360    else
    20891361        AssertFailedReturn(VINF_SUCCESS);
     
    21231395{
    21241396    Assert(CODEC_CAD(cmd) == pThis->id);
    2125     Assert(CODEC_NID(cmd) == STAC9220_NID_AFG);
    2126 
    2127     if (   CODEC_NID(cmd) == STAC9220_NID_AFG
    2128         && pThis->pfnReset)
    2129     {
    2130         pThis->pfnReset(pThis);
    2131     }
     1397
     1398    if (pThis->enmType == CODEC_TYPE_STAC9220)
     1399    {
     1400        Assert(CODEC_NID(cmd) == STAC9220_NID_AFG);
     1401
     1402        if (CODEC_NID(cmd) == STAC9220_NID_AFG)
     1403            stac9220Reset(pThis);
     1404    }
     1405    else
     1406        AssertFailedReturn(VERR_NOT_IMPLEMENTED);
    21321407
    21331408    *pResp = 0;
     
    21411416
    21421417    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    2143         *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F05_param;
     1418        *pResp = pThis->aNodes[CODEC_NID(cmd)].afg.u32F05_param;
    21441419    else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    2145         *pResp = pThis->paNodes[CODEC_NID(cmd)].dac.u32F05_param;
     1420        *pResp = pThis->aNodes[CODEC_NID(cmd)].dac.u32F05_param;
    21461421    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    2147         *pResp = pThis->paNodes[CODEC_NID(cmd)].adc.u32F05_param;
     1422        *pResp = pThis->aNodes[CODEC_NID(cmd)].adc.u32F05_param;
    21481423    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    2149         *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F05_param;
     1424        *pResp = pThis->aNodes[CODEC_NID(cmd)].digin.u32F05_param;
    21501425    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
    2151         *pResp = pThis->paNodes[CODEC_NID(cmd)].digout.u32F05_param;
     1426        *pResp = pThis->aNodes[CODEC_NID(cmd)].digout.u32F05_param;
    21521427    else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    2153         *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifout.u32F05_param;
     1428        *pResp = pThis->aNodes[CODEC_NID(cmd)].spdifout.u32F05_param;
    21541429    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    2155         *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifin.u32F05_param;
     1430        *pResp = pThis->aNodes[CODEC_NID(cmd)].spdifin.u32F05_param;
    21561431    else if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
    2157         *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F05_param;
     1432        *pResp = pThis->aNodes[CODEC_NID(cmd)].reserved.u32F05_param;
    21581433    else
    21591434        LogRel2(("HDA: Warning: Unhandled get power state command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    21721447    uint32_t *pu32Reg = NULL;
    21731448    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    2174         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F05_param;
     1449        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].afg.u32F05_param;
    21751450    else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    2176         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].dac.u32F05_param;
     1451        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].dac.u32F05_param;
    21771452    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    2178         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F05_param;
     1453        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digin.u32F05_param;
    21791454    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
    2180         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digout.u32F05_param;
     1455        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digout.u32F05_param;
    21811456    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    2182         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adc.u32F05_param;
     1457        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].adc.u32F05_param;
    21831458    else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    2184         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].spdifout.u32F05_param;
     1459        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].spdifout.u32F05_param;
    21851460    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    2186         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].spdifin.u32F05_param;
     1461        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].spdifin.u32F05_param;
    21871462    else if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
    2188         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F05_param;
     1463        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].reserved.u32F05_param;
    21891464    else
    21901465    {
     
    22051480             CODEC_NID(cmd), uPwrCmd, fReset, fStopOk, fError, uPwrAct, uPwrSet));
    22061481    LogFunc(("AFG: Act=D%RU8, Set=D%RU8\n",
    2207             CODEC_F05_ACT(pThis->paNodes[STAC9220_NID_AFG].afg.u32F05_param),
    2208             CODEC_F05_SET(pThis->paNodes[STAC9220_NID_AFG].afg.u32F05_param)));
     1482            CODEC_F05_ACT(pThis->aNodes[STAC9220_NID_AFG].afg.u32F05_param),
     1483            CODEC_F05_SET(pThis->aNodes[STAC9220_NID_AFG].afg.u32F05_param)));
    22091484#endif
    22101485
     
    22121487        *pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0, uPwrCmd /* PS-Act */, uPwrCmd /* PS-Set */);
    22131488
    2214     const uint8_t uAFGPwrAct = CODEC_F05_ACT(pThis->paNodes[STAC9220_NID_AFG].afg.u32F05_param);
     1489    const uint8_t uAFGPwrAct = CODEC_F05_ACT(pThis->aNodes[STAC9220_NID_AFG].afg.u32F05_param);
    22151490    if (uAFGPwrAct == CODEC_F05_D0) /* Only propagate power state if AFG is on (D0). */
    22161491    {
     
    22231498            while (*(++pu8NodeIndex)) \
    22241499            { \
    2225                 pThis->paNodes[*pu8NodeIndex]._aMember.u32F05_param = \
     1500                pThis->aNodes[*pu8NodeIndex]._aMember.u32F05_param = \
    22261501                    CODEC_MAKE_F05(fReset, fStopOk, 0, uAFGPwrAct, uPwrCmd); \
    22271502                LogFunc(("\t[NID0x%02x]: Act=D%RU8, Set=D%RU8\n", *pu8NodeIndex, \
    2228                          CODEC_F05_ACT(pThis->paNodes[*pu8NodeIndex]._aMember.u32F05_param), \
    2229                          CODEC_F05_SET(pThis->paNodes[*pu8NodeIndex]._aMember.u32F05_param))); \
     1503                         CODEC_F05_ACT(pThis->aNodes[*pu8NodeIndex]._aMember.u32F05_param), \
     1504                         CODEC_F05_SET(pThis->aNodes[*pu8NodeIndex]._aMember.u32F05_param))); \
    22301505            } \
    22311506        }
     
    22801555    uint32_t *pu32Reg;
    22811556    if (CODEC_NID(cmd) == 1 /* AFG */)
    2282         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F05_param;
     1557        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].afg.u32F05_param;
    22831558    else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    2284         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].dac.u32F05_param;
     1559        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].dac.u32F05_param;
    22851560    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    2286         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F05_param;
     1561        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digin.u32F05_param;
    22871562    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    2288         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adc.u32F05_param;
     1563        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].adc.u32F05_param;
    22891564    else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    2290         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].spdifout.u32F05_param;
     1565        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].spdifout.u32F05_param;
    22911566    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    2292         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].spdifin.u32F05_param;
     1567        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].spdifin.u32F05_param;
    22931568    else if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
    2294         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F05_param;
     1569        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].reserved.u32F05_param;
    22951570    else
    22961571        AssertFailedReturn(VINF_SUCCESS);
     
    23051580         */
    23061581        *pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0,
    2307                                   CODEC_F05_ACT(pThis->paNodes[1].afg.u32F05_param),
     1582                                  CODEC_F05_ACT(pThis->aNodes[1].afg.u32F05_param),
    23081583                                  CODEC_F05_SET(cmd));
    23091584    }
     
    23111586    /* Propagate next power state only if AFG is on or verb modifies AFG power state */
    23121587    if (   CODEC_NID(cmd) == 1 /* AFG */
    2313         || !CODEC_F05_ACT(pThis->paNodes[1].afg.u32F05_param))
     1588        || !CODEC_F05_ACT(pThis->aNodes[1].afg.u32F05_param))
    23141589    {
    23151590        *pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0, CODEC_F05_SET(cmd), CODEC_F05_SET(cmd));
     
    23201595            const uint8_t *pu8NodeIndex = &pThis->au8Dacs[0];
    23211596            while (*(++pu8NodeIndex))
    2322                 codecPropogatePowerState(&pThis->paNodes[*pu8NodeIndex].dac.u32F05_param);
     1597                codecPropogatePowerState(&pThis->aNodes[*pu8NodeIndex].dac.u32F05_param);
    23231598
    23241599            pu8NodeIndex = &pThis->au8Adcs[0];
    23251600            while (*(++pu8NodeIndex))
    2326                 codecPropogatePowerState(&pThis->paNodes[*pu8NodeIndex].adc.u32F05_param);
     1601                codecPropogatePowerState(&pThis->aNodes[*pu8NodeIndex].adc.u32F05_param);
    23271602
    23281603            pu8NodeIndex = &pThis->au8DigInPins[0];
    23291604            while (*(++pu8NodeIndex))
    2330                 codecPropogatePowerState(&pThis->paNodes[*pu8NodeIndex].digin.u32F05_param);
     1605                codecPropogatePowerState(&pThis->aNodes[*pu8NodeIndex].digin.u32F05_param);
    23311606        }
    23321607    }
     
    23411616
    23421617    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    2343         *pResp = pThis->paNodes[CODEC_NID(cmd)].dac.u32F06_param;
     1618        *pResp = pThis->aNodes[CODEC_NID(cmd)].dac.u32F06_param;
    23441619    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    2345         *pResp = pThis->paNodes[CODEC_NID(cmd)].adc.u32F06_param;
     1620        *pResp = pThis->aNodes[CODEC_NID(cmd)].adc.u32F06_param;
    23461621    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    2347         *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
     1622        *pResp = pThis->aNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
    23481623    else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    2349         *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
     1624        *pResp = pThis->aNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
    23501625    else if (CODEC_NID(cmd) == STAC9221_NID_I2S_OUT)
    2351         *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F06_param;
     1626        *pResp = pThis->aNodes[CODEC_NID(cmd)].reserved.u32F06_param;
    23521627    else
    23531628        LogRel2(("HDA: Warning: Unhandled get stream ID command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    23591634}
    23601635
     1636#ifdef IN_RING3
     1637
    23611638/* 706 */
    2362 static DECLCALLBACK(int) vrbProcSetStreamId(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     1639static DECLCALLBACK(int) vrbProcR3SetStreamId(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *pResp)
    23631640{
    23641641    *pResp = 0;
     
    23771654    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    23781655    {
    2379         pu32Addr = &pThis->paNodes[CODEC_NID(cmd)].dac.u32F06_param;
     1656        pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].dac.u32F06_param;
    23801657        enmDir = PDMAUDIODIR_OUT;
    23811658    }
    23821659    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    23831660    {
    2384         pu32Addr = &pThis->paNodes[CODEC_NID(cmd)].adc.u32F06_param;
     1661        pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].adc.u32F06_param;
    23851662        enmDir = PDMAUDIODIR_IN;
    23861663    }
    23871664    else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    23881665    {
    2389         pu32Addr = &pThis->paNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
     1666        pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
    23901667        enmDir = PDMAUDIODIR_OUT;
    23911668    }
    23921669    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    23931670    {
    2394         pu32Addr = &pThis->paNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
     1671        pu32Addr = &pThis->aNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
    23951672        enmDir = PDMAUDIODIR_IN;
    23961673    }
     
    24041681    if (enmDir != PDMAUDIODIR_UNKNOWN)
    24051682    {
    2406         pThis->paNodes[CODEC_NID(cmd)].node.uSD      = uSD;
    2407         pThis->paNodes[CODEC_NID(cmd)].node.uChannel = uChannel;
     1683        pThis->aNodes[CODEC_NID(cmd)].node.uSD      = uSD;
     1684        pThis->aNodes[CODEC_NID(cmd)].node.uChannel = uChannel;
    24081685
    24091686        if (enmDir == PDMAUDIODIR_OUT)
     
    24121689
    24131690            /* Propagate to the controller. */
    2414             pThis->pfnCbMixerControl(pThis->pDevIns, PDMAUDIOMIXERCTL_FRONT,      uSD, uChannel);
     1691            pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_FRONT,      uSD, uChannel);
    24151692#ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    2416             pThis->pfnCbMixerControl(pThis->pDevIns, PDMAUDIOMIXERCTL_CENTER_LFE, uSD, uChannel);
    2417             pThis->pfnCbMixerControl(pThis->pDevIns, PDMAUDIOMIXERCTL_REAR,       uSD, uChannel);
     1693            pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_CENTER_LFE, uSD, uChannel);
     1694            pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_REAR,       uSD, uChannel);
    24181695#endif
    24191696        }
    24201697        else if (enmDir == PDMAUDIODIR_IN)
    24211698        {
    2422             pThis->pfnCbMixerControl(pThis->pDevIns, PDMAUDIOMIXERCTL_LINE_IN,    uSD, uChannel);
     1699            pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_LINE_IN,    uSD, uChannel);
    24231700#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    2424             pThis->pfnCbMixerControl(pThis->pDevIns, PDMAUDIOMIXERCTL_MIC_IN,     uSD, uChannel);
     1701            pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_MIC_IN,     uSD, uChannel);
    24251702#endif
    24261703        }
     
    24331710}
    24341711
     1712#endif /* IN_RING3 */
     1713
    24351714/* A0 */
    24361715static DECLCALLBACK(int) vrbProcGetConverterFormat(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     
    24391718
    24401719    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    2441         *pResp = pThis->paNodes[CODEC_NID(cmd)].dac.u32A_param;
     1720        *pResp = pThis->aNodes[CODEC_NID(cmd)].dac.u32A_param;
    24421721    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    2443         *pResp = pThis->paNodes[CODEC_NID(cmd)].adc.u32A_param;
     1722        *pResp = pThis->aNodes[CODEC_NID(cmd)].adc.u32A_param;
    24441723    else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    2445         *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifout.u32A_param;
     1724        *pResp = pThis->aNodes[CODEC_NID(cmd)].spdifout.u32A_param;
    24461725    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    2447         *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifin.u32A_param;
     1726        *pResp = pThis->aNodes[CODEC_NID(cmd)].spdifin.u32A_param;
    24481727    else if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
    2449         *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32A_param;
     1728        *pResp = pThis->aNodes[CODEC_NID(cmd)].reserved.u32A_param;
    24501729    else
    24511730        LogRel2(("HDA: Warning: Unhandled get converter format command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    24601739
    24611740    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    2462         hdaCodecSetRegisterU16(&pThis->paNodes[CODEC_NID(cmd)].dac.u32A_param, cmd, 0);
     1741        hdaCodecSetRegisterU16(&pThis->aNodes[CODEC_NID(cmd)].dac.u32A_param, cmd, 0);
    24631742    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    2464         hdaCodecSetRegisterU16(&pThis->paNodes[CODEC_NID(cmd)].adc.u32A_param, cmd, 0);
     1743        hdaCodecSetRegisterU16(&pThis->aNodes[CODEC_NID(cmd)].adc.u32A_param, cmd, 0);
    24651744    else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    2466         hdaCodecSetRegisterU16(&pThis->paNodes[CODEC_NID(cmd)].spdifout.u32A_param, cmd, 0);
     1745        hdaCodecSetRegisterU16(&pThis->aNodes[CODEC_NID(cmd)].spdifout.u32A_param, cmd, 0);
    24671746    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    2468         hdaCodecSetRegisterU16(&pThis->paNodes[CODEC_NID(cmd)].spdifin.u32A_param, cmd, 0);
     1747        hdaCodecSetRegisterU16(&pThis->aNodes[CODEC_NID(cmd)].spdifin.u32A_param, cmd, 0);
    24691748    else
    24701749        LogRel2(("HDA: Warning: Unhandled set converter format command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    24791758
    24801759    if (hdaCodecIsAdcVolNode(pThis, CODEC_NID(cmd)))
    2481         *pResp = pThis->paNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
     1760        *pResp = pThis->aNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
    24821761    else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    2483         *pResp = pThis->paNodes[CODEC_NID(cmd)].dac.u32F0c_param;
     1762        *pResp = pThis->aNodes[CODEC_NID(cmd)].dac.u32F0c_param;
    24841763    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    2485         *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F0c_param;
     1764        *pResp = pThis->aNodes[CODEC_NID(cmd)].digin.u32F0c_param;
    24861765    else
    24871766        LogRel2(("HDA: Warning: Unhandled get EAPD/BTL enabled command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    24971776    uint32_t *pu32Reg = NULL;
    24981777    if (hdaCodecIsAdcVolNode(pThis, CODEC_NID(cmd)))
    2499         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
     1778        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
    25001779    else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    2501         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].dac.u32F0c_param;
     1780        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].dac.u32F0c_param;
    25021781    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    2503         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F0c_param;
     1782        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digin.u32F0c_param;
    25041783    else
    25051784        LogRel2(("HDA: Warning: Unhandled set EAPD/BTL enabled command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    25171796
    25181797    if (hdaCodecIsVolKnobNode(pThis, CODEC_NID(cmd)))
    2519         *pResp = pThis->paNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
     1798        *pResp = pThis->aNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
    25201799    else
    25211800        LogRel2(("HDA: Warning: Unhandled get volume knob control command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    25311810    uint32_t *pu32Reg = NULL;
    25321811    if (hdaCodecIsVolKnobNode(pThis, CODEC_NID(cmd)))
    2533         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
     1812        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
    25341813    else
    25351814        LogRel2(("HDA: Warning: Unhandled set volume knob control command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    25801859    /* Note: this is true for ALC885. */
    25811860    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    2582         *pResp = pThis->paNodes[1].afg.u32F17_param;
     1861        *pResp = pThis->aNodes[1].afg.u32F17_param;
    25831862    else
    25841863        LogRel2(("HDA: Warning: Unhandled get GPIO direction command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    25941873    uint32_t *pu32Reg = NULL;
    25951874    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    2596         pu32Reg = &pThis->paNodes[1].afg.u32F17_param;
     1875        pu32Reg = &pThis->aNodes[1].afg.u32F17_param;
    25971876    else
    25981877        LogRel2(("HDA: Warning: Unhandled set GPIO direction command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    26101889
    26111890    if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    2612         *pResp = pThis->paNodes[CODEC_NID(cmd)].port.u32F1c_param;
     1891        *pResp = pThis->aNodes[CODEC_NID(cmd)].port.u32F1c_param;
    26131892    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
    2614         *pResp = pThis->paNodes[CODEC_NID(cmd)].digout.u32F1c_param;
     1893        *pResp = pThis->aNodes[CODEC_NID(cmd)].digout.u32F1c_param;
    26151894    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    2616         *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F1c_param;
     1895        *pResp = pThis->aNodes[CODEC_NID(cmd)].digin.u32F1c_param;
    26171896    else if (hdaCodecIsPcbeepNode(pThis, CODEC_NID(cmd)))
    2618         *pResp = pThis->paNodes[CODEC_NID(cmd)].pcbeep.u32F1c_param;
     1897        *pResp = pThis->aNodes[CODEC_NID(cmd)].pcbeep.u32F1c_param;
    26191898    else if (hdaCodecIsCdNode(pThis, CODEC_NID(cmd)))
    2620         *pResp = pThis->paNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
     1899        *pResp = pThis->aNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
    26211900    else if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
    2622         *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
     1901        *pResp = pThis->aNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
    26231902    else
    26241903        LogRel2(("HDA: Warning: Unhandled get config command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    26311910    uint32_t *pu32Reg = NULL;
    26321911    if (hdaCodecIsPortNode(pThis, CODEC_NID(cmd)))
    2633         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].port.u32F1c_param;
     1912        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].port.u32F1c_param;
    26341913    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    2635         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F1c_param;
     1914        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digin.u32F1c_param;
    26361915    else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd)))
    2637         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digout.u32F1c_param;
     1916        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].digout.u32F1c_param;
    26381917    else if (hdaCodecIsCdNode(pThis, CODEC_NID(cmd)))
    2639         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
     1918        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
    26401919    else if (hdaCodecIsPcbeepNode(pThis, CODEC_NID(cmd)))
    2641         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].pcbeep.u32F1c_param;
     1920        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].pcbeep.u32F1c_param;
    26421921    else if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
    2643         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
     1922        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
    26441923    else
    26451924        LogRel2(("HDA: Warning: Unhandled set config command (%RU8) for NID0x%02x: 0x%x\n", u8Offset, CODEC_NID(cmd), cmd));
     
    26851964
    26861965    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    2687         *pResp = pThis->paNodes[CODEC_NID(cmd)].dac.u32F04_param;
     1966        *pResp = pThis->aNodes[CODEC_NID(cmd)].dac.u32F04_param;
    26881967    else
    26891968        LogRel2(("HDA: Warning: Unhandled get SDI select command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    26991978    uint32_t *pu32Reg = NULL;
    27001979    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    2701         pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].dac.u32F04_param;
     1980        pu32Reg = &pThis->aNodes[CODEC_NID(cmd)].dac.u32F04_param;
    27021981    else
    27031982        LogRel2(("HDA: Warning: Unhandled set SDI select command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     
    27091988}
    27101989
     1990#ifdef IN_RING3
     1991
    27111992/**
    2712  * HDA codec verb map.
     1993 * HDA codec verb map for ring-3.
     1994 */
     1995static const CODECVERBR3 g_aCodecVerbsR3[] =
     1996{
     1997   /* Verb        Verb mask            Callback                        Name
     1998    * ---------- --------------------- ----------------------------------------------------------
     1999    */
     2000   { 0x00070600, CODEC_VERB_8BIT_CMD , vrbProcR3SetStreamId          , "SetStreamId           " },
     2001   { 0x00030000, CODEC_VERB_16BIT_CMD, vrbProcR3SetAmplifier         , "SetAmplifier          " }
     2002};
     2003
     2004#endif /* IN_RING3 */
     2005
     2006/**
     2007 * HDA codec verb map for ring-0.
    27132008 * @todo Any reason not to use binary search here?
    27142009 *      bird: because you'd need to sort the entries first...
    27152010 */
    2716 static const CODECVERB g_aCodecVerbs[] =
     2011static const CODECVERBR0 g_aCodecVerbsR0[] =
    27172012{
    27182013    /* Verb        Verb mask            Callback                        Name
     
    27232018    { 0x00070100, CODEC_VERB_8BIT_CMD , vrbProcSetConSelectCtrl       , "SetConSelectCtrl      " },
    27242019    { 0x000F0600, CODEC_VERB_8BIT_CMD , vrbProcGetStreamId            , "GetStreamId           " },
    2725     { 0x00070600, CODEC_VERB_8BIT_CMD , vrbProcSetStreamId            , "SetStreamId           " },
    27262020    { 0x000F0700, CODEC_VERB_8BIT_CMD , vrbProcGetPinCtrl             , "GetPinCtrl            " },
    27272021    { 0x00070700, CODEC_VERB_8BIT_CMD , vrbProcSetPinCtrl             , "SetPinCtrl            " },
     
    27622056    { 0x00020000, CODEC_VERB_16BIT_CMD, vrbProcSetConverterFormat     , "SetConverterFormat    " },
    27632057    { 0x000B0000, CODEC_VERB_16BIT_CMD, vrbProcGetAmplifier           , "GetAmplifier          " },
    2764     { 0x00030000, CODEC_VERB_16BIT_CMD, vrbProcSetAmplifier           , "SetAmplifier          " },
    27652058    { 0x000F0400, CODEC_VERB_8BIT_CMD , vrbProcGetSDISelect           , "GetSDISelect          " },
    27662059    { 0x00070400, CODEC_VERB_8BIT_CMD , vrbProcSetSDISelect           , "SetSDISelect          " }
     
    27682061};
    27692062
     2063#if defined(IN_RING3) && defined(DEBUG)
    27702064
    27712065/**
     
    29542248        for (uint8_t i = 0; i < pInfo->pThis->cTotalNodes; i++)
    29552249        {
    2956             const PCODECNODE pSubNode = &pInfo->pThis->paNodes[i];
     2250            const PCODECNODE pSubNode = &pInfo->pThis->aNodes[i];
    29572251            if (pSubNode->node.uID == pNode->node.uID)
    29582252                continue;
     
    29742268}
    29752269
    2976 static DECLCALLBACK(void) codecDbgListNodes(PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)
    2977 {
    2978     RT_NOREF(pszArgs);
     2270static DECLCALLBACK(void) codecR3DbgListNodes(PHDACODEC pThis, PHDACODECR3 pThisCC, PCDBGFINFOHLP pHlp, const char *pszArgs)
     2271{
     2272    RT_NOREF(pThisCC, pszArgs);
     2273
    29792274    pHlp->pfnPrintf(pHlp, "HDA LINK / INPUTS\n");
    29802275
     
    29892284        for (uint8_t i = 0; i < pThis->cTotalNodes; i++)
    29902285        {
    2991             PCODECNODE pNode = &pThis->paNodes[i];
     2286            PCODECNODE pNode = &pThis->aNodes[i];
    29922287
    29932288            /* Start with all nodes which have connection entries set. */
     
    29982293}
    29992294
    3000 #ifdef DEBUG
    3001 
    3002 static DECLCALLBACK(void) codecDbgSelector(PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)
    3003 {
    3004     RT_NOREF(pThis, pHlp, pszArgs);
    3005 }
    3006 
    3007 #endif /* DEBUG */
    3008 
    3009 static DECLCALLBACK(int) codecLookup(PHDACODEC pThis, uint32_t cmd, uint64_t *puResp)
    3010 {
    3011     AssertPtrReturn(pThis,  VERR_INVALID_POINTER);
     2295static DECLCALLBACK(void) codecR3DbgSelector(PHDACODEC pThis, PHDACODECR3 pThisCC, PCDBGFINFOHLP pHlp, const char *pszArgs)
     2296{
     2297    RT_NOREF(pThis, pThisCC, pHlp, pszArgs);
     2298}
     2299
     2300#endif /* IN_RING3 && DEBUG */
     2301
     2302static DECLCALLBACK(int) codecR3Lookup(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *puResp)
     2303{
     2304    AssertPtrReturn(pThisCC,  VERR_INVALID_POINTER);
    30122305    AssertPtrReturn(puResp, VERR_INVALID_POINTER);
    3013     STAM_COUNTER_INC(&pThis->StatLookups);
     2306
     2307    STAM_COUNTER_INC(&pThisCC->StatLookupsR3);
    30142308
    30152309    if (CODEC_CAD(cmd) != pThis->id)
     
    30292323
    30302324    /** @todo r=andy Implement a binary search here. */
    3031     for (size_t i = 0; i < pThis->cVerbs; i++)
    3032     {
    3033         if ((CODEC_VERBDATA(cmd) & pThis->paVerbs[i].mask) == pThis->paVerbs[i].verb)
    3034         {
    3035             int rc2 = pThis->paVerbs[i].pfn(pThis, cmd, puResp);
     2325    for (size_t i = 0; i < pThisCC->cVerbs; i++)
     2326    {
     2327        PCODECVERBR3 pVerb = &pThisCC->aVerbs[i];
     2328
     2329        if ((CODEC_VERBDATA(cmd) & pVerb->mask) == pThisCC->aVerbs[i].verb)
     2330        {
     2331            AssertPtrReturn(pVerb->pfn, VERR_NOT_IMPLEMENTED); /* Paranoia. */
     2332
     2333            int rc2 = pVerb->pfn(pThis, pThisCC, cmd, puResp);
    30362334            AssertRC(rc2);
    30372335            Log3Func(("[NID0x%02x] (0x%x) %s: 0x%x -> 0x%x\n",
    3038                       CODEC_NID(cmd), pThis->paVerbs[i].verb, pThis->paVerbs[i].pszName, CODEC_VERB_PAYLOAD8(cmd), *puResp));
     2336                      CODEC_NID(cmd), pVerb->verb, pVerb->pszName, CODEC_VERB_PAYLOAD8(cmd), *puResp));
    30392337            return rc2;
    30402338        }
     
    30462344}
    30472345
     2346static DECLCALLBACK(int) codecR0Lookup(PHDACODEC pThis, PHDACODECR0 pThisCC, uint32_t cmd, uint64_t *puResp)
     2347{
     2348    AssertPtrReturn(pThis,  VERR_INVALID_POINTER);
     2349    AssertPtrReturn(puResp, VERR_INVALID_POINTER);
     2350
     2351    STAM_COUNTER_INC(&pThisCC->StatLookupsR0);
     2352
     2353    if (CODEC_CAD(cmd) != pThis->id)
     2354    {
     2355        *puResp = 0;
     2356        AssertMsgFailed(("Unknown codec address 0x%x\n", CODEC_CAD(cmd)));
     2357        return VERR_INVALID_PARAMETER;
     2358    }
     2359
     2360    if (   CODEC_VERBDATA(cmd) == 0
     2361        || CODEC_NID(cmd) >= pThis->cTotalNodes)
     2362    {
     2363        *puResp = 0;
     2364        AssertMsgFailed(("[NID0x%02x] Unknown / invalid node or data (0x%x)\n", CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
     2365        return VERR_INVALID_PARAMETER;
     2366    }
     2367
     2368    /** @todo r=andy Implement a binary search here. */
     2369    for (size_t i = 0; i < pThisCC->cVerbs; i++)
     2370    {
     2371        PCODECVERBR0 pVerb = &pThisCC->aVerbs[i];
     2372
     2373        if ((CODEC_VERBDATA(cmd) & pVerb->mask) == pThisCC->aVerbs[i].verb)
     2374        {
     2375            AssertPtrReturn(pVerb->pfn, VERR_NOT_IMPLEMENTED); /* Paranoia. */
     2376
     2377            int rc2 = pVerb->pfn(pThis, cmd, puResp);
     2378            AssertRC(rc2);
     2379            Log3Func(("[NID0x%02x] (0x%x) %s: 0x%x -> 0x%x\n",
     2380                      CODEC_NID(cmd), pVerb->verb, pVerb->pszName, CODEC_VERB_PAYLOAD8(cmd), *puResp));
     2381            return rc2;
     2382        }
     2383    }
     2384
     2385    *puResp = 0;
     2386    LogFunc(("[NID0x%02x] Callback for %x not found\n", CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
     2387    return VERR_NOT_FOUND;
     2388}
     2389
    30482390/*
    30492391 * APIs exposed to DevHDA.
    30502392 */
    30512393
    3052 int hdaCodecAddStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg)
    3053 {
    3054     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     2394#ifdef IN_RING3
     2395
     2396int hdaR3CodecAddStream(PHDACODECR3 pThisCC, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg)
     2397{
     2398    AssertPtrReturn(pThisCC, VERR_INVALID_POINTER);
    30552399    AssertPtrReturn(pCfg,  VERR_INVALID_POINTER);
    30562400
     
    30742418
    30752419        default:
    3076             AssertMsgFailed(("Mixer control %d not implemented\n", enmMixerCtl));
     2420            AssertMsgFailed(("Mixer control %#x not implemented\n", enmMixerCtl));
    30772421            rc = VERR_NOT_IMPLEMENTED;
    30782422            break;
     
    30802424
    30812425    if (RT_SUCCESS(rc))
    3082         rc = pThis->pfnCbMixerAddStream(pThis->pDevIns, enmMixerCtl, pCfg);
     2426        rc = pThisCC->pfnCbMixerAddStream(pThisCC->pDevIns, enmMixerCtl, pCfg);
    30832427
    30842428    LogFlowFuncLeaveRC(rc);
     
    30862430}
    30872431
    3088 int hdaCodecRemoveStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl)
    3089 {
    3090     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    3091 
    3092     int rc = pThis->pfnCbMixerRemoveStream(pThis->pDevIns, enmMixerCtl);
     2432int hdaR3CodecRemoveStream(PHDACODECR3 pThisCC, PDMAUDIOMIXERCTL enmMixerCtl)
     2433{
     2434    AssertPtrReturn(pThisCC, VERR_INVALID_POINTER);
     2435
     2436    int rc = pThisCC->pfnCbMixerRemoveStream(pThisCC->pDevIns, enmMixerCtl);
    30932437
    30942438    LogFlowFuncLeaveRC(rc);
     
    31032447    pHlp->pfnSSMPutU32(pSSM, pThis->cTotalNodes);
    31042448    for (unsigned idxNode = 0; idxNode < pThis->cTotalNodes; ++idxNode)
    3105         pHlp->pfnSSMPutStructEx(pSSM, &pThis->paNodes[idxNode].SavedState, sizeof(pThis->paNodes[idxNode].SavedState),
     2449        pHlp->pfnSSMPutStructEx(pSSM, &pThis->aNodes[idxNode].SavedState, sizeof(pThis->aNodes[idxNode].SavedState),
    31062450                                0 /*fFlags*/, g_aCodecNodeFields, NULL /*pvUser*/);
    31072451    return VINF_SUCCESS;
    31082452}
    31092453
    3110 int hdaCodecLoadState(PPDMDEVINS pDevIns, PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion)
     2454int hdaR3CodecLoadState(PPDMDEVINS pDevIns, PHDACODEC pThis, PHDACODECR3 pThisCC, PSSMHANDLE pSSM, uint32_t uVersion)
    31112455{
    31122456    PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
     
    31422486    for (unsigned idxNode = 0; idxNode < pThis->cTotalNodes; ++idxNode)
    31432487    {
    3144         uint8_t idOld = pThis->paNodes[idxNode].SavedState.Core.uID;
    3145         int rc = pHlp->pfnSSMGetStructEx(pSSM, &pThis->paNodes[idxNode].SavedState, sizeof(pThis->paNodes[idxNode].SavedState),
     2488        uint8_t idOld = pThis->aNodes[idxNode].SavedState.Core.uID;
     2489        int rc = pHlp->pfnSSMGetStructEx(pSSM, &pThis->aNodes[idxNode].SavedState, sizeof(pThis->aNodes[idxNode].SavedState),
    31462490                                         fFlags, pFields, NULL);
    31472491        AssertRCReturn(rc, rc);
    3148         AssertLogRelMsgReturn(idOld == pThis->paNodes[idxNode].SavedState.Core.uID,
    3149                               ("loaded %#x, expected %#x\n", pThis->paNodes[idxNode].SavedState.Core.uID, idOld),
     2492        AssertLogRelMsgReturn(idOld == pThis->aNodes[idxNode].SavedState.Core.uID,
     2493                              ("loaded %#x, expected %#x\n", pThis->aNodes[idxNode].SavedState.Core.uID, idOld),
    31502494                              VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
    31512495    }
     
    31572501    if (hdaCodecIsDacNode(pThis, pThis->u8DacLineOut))
    31582502    {
    3159         pNode = &pThis->paNodes[pThis->u8DacLineOut];
    3160         hdaCodecToAudVolume(pThis, pNode, &pNode->dac.B_params, PDMAUDIOMIXERCTL_FRONT);
     2503        pNode = &pThis->aNodes[pThis->u8DacLineOut];
     2504        hdaR3CodecToAudVolume(pThisCC, pNode, &pNode->dac.B_params, PDMAUDIOMIXERCTL_FRONT);
    31612505    }
    31622506    else if (hdaCodecIsSpdifOutNode(pThis, pThis->u8DacLineOut))
    31632507    {
    3164         pNode = &pThis->paNodes[pThis->u8DacLineOut];
    3165         hdaCodecToAudVolume(pThis, pNode, &pNode->spdifout.B_params, PDMAUDIOMIXERCTL_FRONT);
    3166     }
    3167 
    3168     pNode = &pThis->paNodes[pThis->u8AdcVolsLineIn];
    3169     hdaCodecToAudVolume(pThis, pNode, &pNode->adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
     2508        pNode = &pThis->aNodes[pThis->u8DacLineOut];
     2509        hdaR3CodecToAudVolume(pThisCC, pNode, &pNode->spdifout.B_params, PDMAUDIOMIXERCTL_FRONT);
     2510    }
     2511
     2512    pNode = &pThis->aNodes[pThis->u8AdcVolsLineIn];
     2513    hdaR3CodecToAudVolume(pThisCC, pNode, &pNode->adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
    31702514
    31712515    LogFlowFuncLeaveRC(VINF_SUCCESS);
     
    31742518
    31752519/**
    3176  * Powers off the codec.
     2520 * Powers off the codec (ring-3).
    31772521 *
    31782522 * @param   pThis           Codec to power off.
    31792523 */
    3180 void hdaCodecPowerOff(PHDACODEC pThis)
    3181 {
    3182     if (!pThis)
     2524void hdaR3CodecPowerOff(PHDACODECR3 pThisCC)
     2525{
     2526    if (!pThisCC)
    31832527        return;
    31842528
     
    31872531    LogRel2(("HDA: Powering off codec ...\n"));
    31882532
    3189     int rc2 = hdaCodecRemoveStream(pThis, PDMAUDIOMIXERCTL_FRONT);
     2533    int rc2 = hdaR3CodecRemoveStream(pThisCC, PDMAUDIOMIXERCTL_FRONT);
    31902534    AssertRC(rc2);
    31912535#ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    3192     rc2 = hdaCodecRemoveStream(pThis, PDMAUDIOMIXERCTL_CENTER_LFE);
     2536    rc2 = hdaR3CodecRemoveStream(pThisCC, PDMAUDIOMIXERCTL_CENTER_LFE);
    31932537    AssertRC(rc2);
    3194     rc2 = hdaCodecRemoveStream(pThis, PDMAUDIOMIXERCTL_REAR);
     2538    rc2 = hdaR3CodecRemoveStream(pThisCC, PDMAUDIOMIXERCTL_REAR);
    31952539    AssertRC(rc2);
    31962540#endif
    31972541
    31982542#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    3199     rc2 = hdaCodecRemoveStream(pThis, PDMAUDIOMIXERCTL_MIC_IN);
     2543    rc2 = hdaR3CodecRemoveStream(pThisCC, PDMAUDIOMIXERCTL_MIC_IN);
    32002544    AssertRC(rc2);
    32012545#endif
    3202     rc2 = hdaCodecRemoveStream(pThis, PDMAUDIOMIXERCTL_LINE_IN);
     2546    rc2 = hdaR3CodecRemoveStream(pThisCC, PDMAUDIOMIXERCTL_LINE_IN);
    32032547    AssertRC(rc2);
    32042548}
    32052549
    3206 void hdaCodecDestruct(PHDACODEC pThis)
    3207 {
    3208     if (!pThis)
    3209         return;
    3210 
    3211     LogFlowFuncEnter();
    3212 
    3213     if (pThis->paNodes)
    3214     {
    3215         RTMemFree(pThis->paNodes);
    3216         pThis->paNodes = NULL;
    3217     }
    3218 }
    3219 
    3220 int hdaCodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis,
    3221                       uint16_t uLUN, PCFGMNODE pCfg)
     2550/**
     2551 * Constructs a codec (ring-3).
     2552 *
     2553 * @returns VBox status code.
     2554 * @param   pDevIns             Associated device instance.
     2555 * @param   pThis               Shared codec data beteen r0/r3.
     2556 * @param   pThisCC             Context-specific codec data (ring-3).
     2557 * @param   uLUN                Device LUN to assign.
     2558 * @param   pCfg                CFGM node to use for configuration.
     2559 */
     2560int hdaR3CodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, PHDACODECR3 pThisCC,
     2561                        uint16_t uLUN, PCFGMNODE pCfg)
    32222562{
    32232563    AssertPtrReturn(pDevIns, VERR_INVALID_POINTER);
    32242564    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
     2565    AssertPtrReturn(pThisCC, VERR_INVALID_POINTER);
    32252566    AssertPtrReturn(pCfg,    VERR_INVALID_POINTER);
    32262567
    32272568    pThis->id      = uLUN;
    3228     pThis->paVerbs = &g_aCodecVerbs[0];
    3229     pThis->cVerbs  = RT_ELEMENTS(g_aCodecVerbs);
     2569    pThis->enmType = CODEC_TYPE_STAC9220; /** @todo Make this dynamic. */
     2570
     2571    int rc;
     2572
     2573    switch (pThis->enmType)
     2574    {
     2575        case CODEC_TYPE_STAC9220:
     2576        {
     2577            rc = stac9220Construct(pThis);
     2578            AssertRCReturn(rc, rc);
     2579            break;
     2580        }
     2581
     2582        default:
     2583            AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     2584            break;
     2585    }
     2586
     2587    memcpy(&pThisCC->aVerbs, &g_aCodecVerbsR3, sizeof(CODECVERBR3) * RT_ELEMENTS(g_aCodecVerbsR3));
     2588    pThisCC->cVerbs = RT_ELEMENTS(g_aCodecVerbsR3);
    32302589
    32312590#ifdef DEBUG
    3232     pThis->pfnDbgSelector  = codecDbgSelector;
     2591    pThisCC->pfnDbgSelector  = codecR3DbgSelector;
     2592    pThisCC->pfnDbgListNodes = codecR3DbgListNodes;
    32332593#endif
    3234     pThis->pfnDbgListNodes = codecDbgListNodes;
    3235     pThis->pfnLookup       = codecLookup;
    3236 
    3237     int rc = stac9220Construct(pThis);
    3238     AssertRCReturn(rc, rc);
    3239 
    3240     /* Common root node initializers. */
    3241     pThis->paNodes[STAC9220_NID_ROOT].root.node.au32F00_param[0] = CODEC_MAKE_F00_00(pThis->u16VendorId, pThis->u16DeviceId);
    3242     pThis->paNodes[STAC9220_NID_ROOT].root.node.au32F00_param[4] = CODEC_MAKE_F00_04(0x1, 0x1);
    3243 
    3244     /* Common AFG node initializers. */
    3245     pThis->paNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0x4] = CODEC_MAKE_F00_04(0x2, pThis->cTotalNodes - 2);
    3246     pThis->paNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0x5] = CODEC_MAKE_F00_05(1, CODEC_F00_05_AFG);
    3247     pThis->paNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0xA] = CODEC_F00_0A_44_1KHZ | CODEC_F00_0A_16_BIT;
    3248     pThis->paNodes[STAC9220_NID_AFG].afg.u32F20_param = CODEC_MAKE_F20(pThis->u16VendorId, pThis->u8BSKU, pThis->u8AssemblyId);
     2594    pThisCC->pfnLookup       = codecR3Lookup;
    32492595
    32502596    /*
    32512597     * Set initial volume.
    32522598     */
    3253     PCODECNODE pNode = &pThis->paNodes[pThis->u8DacLineOut];
    3254     hdaCodecToAudVolume(pThis, pNode, &pNode->dac.B_params, PDMAUDIOMIXERCTL_FRONT);
    3255 
    3256     pNode = &pThis->paNodes[pThis->u8AdcVolsLineIn];
    3257     hdaCodecToAudVolume(pThis, pNode, &pNode->adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
     2599    PCODECNODE pNode = &pThis->aNodes[pThis->u8DacLineOut];
     2600    rc = hdaR3CodecToAudVolume(pThisCC, pNode, &pNode->dac.B_params, PDMAUDIOMIXERCTL_FRONT);
     2601    AssertRCReturn(rc, rc);
     2602
     2603    pNode = &pThis->aNodes[pThis->u8AdcVolsLineIn];
     2604    rc = hdaR3CodecToAudVolume(pThisCC, pNode, &pNode->adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
     2605    AssertRCReturn(rc, rc);
     2606
    32582607#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    32592608# error "Implement mic-in support!"
     
    32642613     */
    32652614#ifdef VBOX_WITH_STATISTICS
    3266     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatLookups, STAMTYPE_COUNTER, "Codec/Lookups", STAMUNIT_OCCURENCES, "Number of codecLookup calls");
     2615    PDMDevHlpSTAMRegister(pDevIns, &pThisCC->StatLookupsR3, STAMTYPE_COUNTER, "Codec/LookupsR3", STAMUNIT_OCCURENCES, "Number of R3 codecLookup calls");
    32672616#endif
    32682617
    3269     LogFlowFuncLeaveRC(rc);
    32702618    return rc;
    32712619}
    32722620
     2621#else /* RING0 */
     2622
     2623/**
     2624 * Constructs a codec (ring-0).
     2625 *
     2626 * @returns VBox status code.
     2627 * @param   pDevIns             Associated device instance.
     2628 * @param   pThis               Shared codec data beteen r0/r3.
     2629 * @param   pThisCC             Context-specific codec data (ring-0).
     2630 */
     2631int hdaR0CodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, PHDACODECR0 pThisCC)
     2632{
     2633    AssertPtrReturn(pDevIns, VERR_INVALID_POINTER);
     2634    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
     2635    AssertPtrReturn(pThisCC, VERR_INVALID_POINTER);
     2636
     2637    memcpy(&pThisCC->aVerbs, &g_aCodecVerbsR0, sizeof(CODECVERBR0) * RT_ELEMENTS(g_aCodecVerbsR0));
     2638    pThisCC->cVerbs = RT_ELEMENTS(g_aCodecVerbsR0);
     2639
     2640    pThisCC->pfnLookup = codecR0Lookup;
     2641
     2642    /* Note: Everything else is done in the R3 part. */
     2643
     2644    /*
     2645     * Statistics
     2646     */
     2647#ifdef VBOX_WITH_STATISTICS
     2648    /** @todo */
     2649#endif
     2650
     2651    return VINF_SUCCESS;
     2652}
     2653
     2654#endif /* IN_RING3 */
     2655
     2656/**
     2657 * Destructs a codec.
     2658 *
     2659 * @param   pThis           Codec to destruct.
     2660 */
     2661void hdaCodecDestruct(PHDACODEC pThis)
     2662{
     2663    if (!pThis)
     2664        return;
     2665
     2666    /* Nothing to do here atm. */
     2667
     2668    LogFlowFuncEnter();
     2669}
     2670
     2671/**
     2672 * Resets a codec.
     2673 *
     2674 * @param   pThis           Codec to reset.
     2675 */
     2676void hdaCodecReset(PHDACODEC pThis)
     2677{
     2678    switch (pThis->enmType)
     2679    {
     2680        case CODEC_TYPE_STAC9220:
     2681            stac9220Reset(pThis);
     2682            break;
     2683
     2684        default:
     2685            AssertFailed();
     2686            break;
     2687    }
     2688}
     2689
  • trunk/src/VBox/Devices/Audio/HDACodec.h

    r85121 r87799  
    3030/** Pointer to a ring-3 HDA device state.  */
    3131typedef struct HDASTATER3 *PHDASTATER3;
    32 /** The ICH HDA (Intel) codec state. */
     32/** The ICH HDA (Intel) common codec state. */
    3333typedef struct HDACODEC *PHDACODEC;
     34/** The ICH HDA (Intel) ring-0 state. */
     35typedef struct HDACODECR0 *PHDACODECR0;
     36/** The ICH HDA (Intel) ring-3 state. */
     37typedef struct HDACODECR3 *PHDACODECR3;
    3438/** The HDA host driver backend. */
    3539typedef struct HDADRIVER *PHDADRIVER;
    3640
    3741/**
     42 * Enumeration specifying the codec type to use.
     43 */
     44typedef enum CODEC_TYPE
     45{
     46    /** Invalid, do not use. */
     47    CODEC_TYPE_INVALID = 0,
     48    /** SigmaTel 9220 (922x). */
     49    CODEC_TYPE_STAC9220,
     50    /** Hack to blow the type up to 32-bit. */
     51    CODEC_TYPE__32BIT_HACK = 0x7fffffff
     52} CODEC_TYPE;
     53
     54/**
    3855 * Verb processor method.
    3956 */
    40 typedef DECLCALLBACKTYPE(int, FNHDACODECVERBPROCESSOR,(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp));
    41 typedef FNHDACODECVERBPROCESSOR *PFNHDACODECVERBPROCESSOR;
     57typedef DECLCALLBACKTYPE(int, FNHDACODECVERBPROCESSORR0,(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp));
     58typedef FNHDACODECVERBPROCESSORR0 *PFNHDACODECVERBPROCESSORR0;
     59typedef DECLCALLBACKTYPE(int, FNHDACODECVERBPROCESSORR3,(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *pResp));
     60typedef FNHDACODECVERBPROCESSORR3 *PFNHDACODECVERBPROCESSORR3;
     61
     62/* PRM 5.3.1 */
     63/** Codec address mask. */
     64#define CODEC_CAD_MASK                                     0xF0000000
     65/** Codec address shift. */
     66#define CODEC_CAD_SHIFT                                    28
     67#define CODEC_DIRECT_MASK                                  RT_BIT(27)
     68/** Node ID mask. */
     69#define CODEC_NID_MASK                                     0x07F00000
     70/** Node ID shift. */
     71#define CODEC_NID_SHIFT                                    20
     72#define CODEC_VERBDATA_MASK                                0x000FFFFF
     73#define CODEC_VERB_4BIT_CMD                                0x000FFFF0
     74#define CODEC_VERB_4BIT_DATA                               0x0000000F
     75#define CODEC_VERB_8BIT_CMD                                0x000FFF00
     76#define CODEC_VERB_8BIT_DATA                               0x000000FF
     77#define CODEC_VERB_16BIT_CMD                               0x000F0000
     78#define CODEC_VERB_16BIT_DATA                              0x0000FFFF
     79
     80#define CODEC_CAD(cmd)                                     (((cmd) & CODEC_CAD_MASK) >> CODEC_CAD_SHIFT)
     81#define CODEC_DIRECT(cmd)                                  ((cmd) & CODEC_DIRECT_MASK)
     82#define CODEC_NID(cmd)                                     ((((cmd) & CODEC_NID_MASK)) >> CODEC_NID_SHIFT)
     83#define CODEC_VERBDATA(cmd)                                ((cmd) & CODEC_VERBDATA_MASK)
     84#define CODEC_VERB_CMD(cmd, mask, x)                       (((cmd) & (mask)) >> (x))
     85#define CODEC_VERB_CMD4(cmd)                               (CODEC_VERB_CMD((cmd), CODEC_VERB_4BIT_CMD, 4))
     86#define CODEC_VERB_CMD8(cmd)                               (CODEC_VERB_CMD((cmd), CODEC_VERB_8BIT_CMD, 8))
     87#define CODEC_VERB_CMD16(cmd)                              (CODEC_VERB_CMD((cmd), CODEC_VERB_16BIT_CMD, 16))
     88#define CODEC_VERB_PAYLOAD4(cmd)                           ((cmd) & CODEC_VERB_4BIT_DATA)
     89#define CODEC_VERB_PAYLOAD8(cmd)                           ((cmd) & CODEC_VERB_8BIT_DATA)
     90#define CODEC_VERB_PAYLOAD16(cmd)                          ((cmd) & CODEC_VERB_16BIT_DATA)
     91
     92#define CODEC_VERB_GET_AMP_DIRECTION                       RT_BIT(15)
     93#define CODEC_VERB_GET_AMP_SIDE                            RT_BIT(13)
     94#define CODEC_VERB_GET_AMP_INDEX                           0x7
     95
     96/* HDA spec 7.3.3.7 NoteA */
     97#define CODEC_GET_AMP_DIRECTION(cmd)                       (((cmd) & CODEC_VERB_GET_AMP_DIRECTION) >> 15)
     98#define CODEC_GET_AMP_SIDE(cmd)                            (((cmd) & CODEC_VERB_GET_AMP_SIDE) >> 13)
     99#define CODEC_GET_AMP_INDEX(cmd)                           (CODEC_GET_AMP_DIRECTION(cmd) ? 0 : ((cmd) & CODEC_VERB_GET_AMP_INDEX))
     100
     101/* HDA spec 7.3.3.7 NoteC */
     102#define CODEC_VERB_SET_AMP_OUT_DIRECTION                   RT_BIT(15)
     103#define CODEC_VERB_SET_AMP_IN_DIRECTION                    RT_BIT(14)
     104#define CODEC_VERB_SET_AMP_LEFT_SIDE                       RT_BIT(13)
     105#define CODEC_VERB_SET_AMP_RIGHT_SIDE                      RT_BIT(12)
     106#define CODEC_VERB_SET_AMP_INDEX                           (0x7 << 8)
     107#define CODEC_VERB_SET_AMP_MUTE                            RT_BIT(7)
     108/** Note: 7-bit value [6:0]. */
     109#define CODEC_VERB_SET_AMP_GAIN                            0x7F
     110
     111#define CODEC_SET_AMP_IS_OUT_DIRECTION(cmd)                (((cmd) & CODEC_VERB_SET_AMP_OUT_DIRECTION) != 0)
     112#define CODEC_SET_AMP_IS_IN_DIRECTION(cmd)                 (((cmd) & CODEC_VERB_SET_AMP_IN_DIRECTION) != 0)
     113#define CODEC_SET_AMP_IS_LEFT_SIDE(cmd)                    (((cmd) & CODEC_VERB_SET_AMP_LEFT_SIDE) != 0)
     114#define CODEC_SET_AMP_IS_RIGHT_SIDE(cmd)                   (((cmd) & CODEC_VERB_SET_AMP_RIGHT_SIDE) != 0)
     115#define CODEC_SET_AMP_INDEX(cmd)                           (((cmd) & CODEC_VERB_SET_AMP_INDEX) >> 7)
     116#define CODEC_SET_AMP_MUTE(cmd)                            ((cmd) & CODEC_VERB_SET_AMP_MUTE)
     117#define CODEC_SET_AMP_GAIN(cmd)                            ((cmd) & CODEC_VERB_SET_AMP_GAIN)
     118
     119/* HDA spec 7.3.3.1 defines layout of configuration registers/verbs (0xF00) */
     120/* VendorID (7.3.4.1) */
     121#define CODEC_MAKE_F00_00(vendorID, deviceID)              (((vendorID) << 16) | (deviceID))
     122#define CODEC_F00_00_VENDORID(f00_00)                      (((f00_00) >> 16) & 0xFFFF)
     123#define CODEC_F00_00_DEVICEID(f00_00)                      ((f00_00) & 0xFFFF)
     124
     125/** RevisionID (7.3.4.2). */
     126#define CODEC_MAKE_F00_02(majRev, minRev, venFix, venProg, stepFix, stepProg) \
     127    (  (((majRev)   & 0xF) << 20) \
     128     | (((minRev)   & 0xF) << 16) \
     129     | (((venFix)   & 0xF) << 12) \
     130     | (((venProg)  & 0xF) << 8)  \
     131     | (((stepFix)  & 0xF) << 4)  \
     132     |  ((stepProg) & 0xF))
     133
     134/** Subordinate node count (7.3.4.3). */
     135#define CODEC_MAKE_F00_04(startNodeNumber, totalNodeNumber) ((((startNodeNumber) & 0xFF) << 16)|((totalNodeNumber) & 0xFF))
     136#define CODEC_F00_04_TO_START_NODE_NUMBER(f00_04)          (((f00_04) >> 16) & 0xFF)
     137#define CODEC_F00_04_TO_NODE_COUNT(f00_04)                 ((f00_04) & 0xFF)
     138/*
     139 * Function Group Type  (7.3.4.4)
     140 * 0 & [0x3-0x7f] are reserved types
     141 * [0x80 - 0xff] are vendor defined function groups
     142 */
     143#define CODEC_MAKE_F00_05(UnSol, NodeType)                 (((UnSol) << 8)|(NodeType))
     144#define CODEC_F00_05_UNSOL                                 RT_BIT(8)
     145#define CODEC_F00_05_AFG                                   (0x1)
     146#define CODEC_F00_05_MFG                                   (0x2)
     147#define CODEC_F00_05_IS_UNSOL(f00_05)                      RT_BOOL((f00_05) & RT_BIT(8))
     148#define CODEC_F00_05_GROUP(f00_05)                         ((f00_05) & 0xff)
     149/* Audio Function Group capabilities (7.3.4.5). */
     150#define CODEC_MAKE_F00_08(BeepGen, InputDelay, OutputDelay) ((((BeepGen) & 0x1) << 16)| (((InputDelay) & 0xF) << 8) | ((OutputDelay) & 0xF))
     151#define CODEC_F00_08_BEEP_GEN(f00_08)                      ((f00_08) & RT_BIT(16)
     152
     153/* Converter Stream, Channel (7.3.3.11). */
     154#define CODEC_F00_06_GET_STREAM_ID(cmd)                    (((cmd) >> 4) & 0x0F)
     155#define CODEC_F00_06_GET_CHANNEL_ID(cmd)                   (((cmd) & 0x0F))
     156
     157/* Widget Capabilities (7.3.4.6). */
     158#define CODEC_MAKE_F00_09(type, delay, chan_ext) \
     159    ( (((type)     & 0xF) << 20)            \
     160    | (((delay)    & 0xF) << 16)           \
     161    | (((chan_ext) & 0xF) << 13))
     162/* note: types 0x8-0xe are reserved */
     163#define CODEC_F00_09_TYPE_AUDIO_OUTPUT                     (0x0)
     164#define CODEC_F00_09_TYPE_AUDIO_INPUT                      (0x1)
     165#define CODEC_F00_09_TYPE_AUDIO_MIXER                      (0x2)
     166#define CODEC_F00_09_TYPE_AUDIO_SELECTOR                   (0x3)
     167#define CODEC_F00_09_TYPE_PIN_COMPLEX                      (0x4)
     168#define CODEC_F00_09_TYPE_POWER_WIDGET                     (0x5)
     169#define CODEC_F00_09_TYPE_VOLUME_KNOB                      (0x6)
     170#define CODEC_F00_09_TYPE_BEEP_GEN                         (0x7)
     171#define CODEC_F00_09_TYPE_VENDOR_DEFINED                   (0xF)
     172
     173#define CODEC_F00_09_CAP_CP                                RT_BIT(12)
     174#define CODEC_F00_09_CAP_L_R_SWAP                          RT_BIT(11)
     175#define CODEC_F00_09_CAP_POWER_CTRL                        RT_BIT(10)
     176#define CODEC_F00_09_CAP_DIGITAL                           RT_BIT(9)
     177#define CODEC_F00_09_CAP_CONNECTION_LIST                   RT_BIT(8)
     178#define CODEC_F00_09_CAP_UNSOL                             RT_BIT(7)
     179#define CODEC_F00_09_CAP_PROC_WIDGET                       RT_BIT(6)
     180#define CODEC_F00_09_CAP_STRIPE                            RT_BIT(5)
     181#define CODEC_F00_09_CAP_FMT_OVERRIDE                      RT_BIT(4)
     182#define CODEC_F00_09_CAP_AMP_FMT_OVERRIDE                  RT_BIT(3)
     183#define CODEC_F00_09_CAP_OUT_AMP_PRESENT                   RT_BIT(2)
     184#define CODEC_F00_09_CAP_IN_AMP_PRESENT                    RT_BIT(1)
     185#define CODEC_F00_09_CAP_STEREO                            RT_BIT(0)
     186
     187#define CODEC_F00_09_TYPE(f00_09)                          (((f00_09) >> 20) & 0xF)
     188
     189#define CODEC_F00_09_IS_CAP_CP(f00_09)                     RT_BOOL((f00_09) & RT_BIT(12))
     190#define CODEC_F00_09_IS_CAP_L_R_SWAP(f00_09)               RT_BOOL((f00_09) & RT_BIT(11))
     191#define CODEC_F00_09_IS_CAP_POWER_CTRL(f00_09)             RT_BOOL((f00_09) & RT_BIT(10))
     192#define CODEC_F00_09_IS_CAP_DIGITAL(f00_09)                RT_BOOL((f00_09) & RT_BIT(9))
     193#define CODEC_F00_09_IS_CAP_CONNECTION_LIST(f00_09)        RT_BOOL((f00_09) & RT_BIT(8))
     194#define CODEC_F00_09_IS_CAP_UNSOL(f00_09)                  RT_BOOL((f00_09) & RT_BIT(7))
     195#define CODEC_F00_09_IS_CAP_PROC_WIDGET(f00_09)            RT_BOOL((f00_09) & RT_BIT(6))
     196#define CODEC_F00_09_IS_CAP_STRIPE(f00_09)                 RT_BOOL((f00_09) & RT_BIT(5))
     197#define CODEC_F00_09_IS_CAP_FMT_OVERRIDE(f00_09)           RT_BOOL((f00_09) & RT_BIT(4))
     198#define CODEC_F00_09_IS_CAP_AMP_OVERRIDE(f00_09)           RT_BOOL((f00_09) & RT_BIT(3))
     199#define CODEC_F00_09_IS_CAP_OUT_AMP_PRESENT(f00_09)        RT_BOOL((f00_09) & RT_BIT(2))
     200#define CODEC_F00_09_IS_CAP_IN_AMP_PRESENT(f00_09)         RT_BOOL((f00_09) & RT_BIT(1))
     201#define CODEC_F00_09_IS_CAP_LSB(f00_09)                    RT_BOOL((f00_09) & RT_BIT(0))
     202
     203/* Supported PCM size, rates (7.3.4.7) */
     204#define CODEC_F00_0A_32_BIT                                RT_BIT(19)
     205#define CODEC_F00_0A_24_BIT                                RT_BIT(18)
     206#define CODEC_F00_0A_16_BIT                                RT_BIT(17)
     207#define CODEC_F00_0A_8_BIT                                 RT_BIT(16)
     208
     209#define CODEC_F00_0A_48KHZ_MULT_8X                         RT_BIT(11)
     210#define CODEC_F00_0A_48KHZ_MULT_4X                         RT_BIT(10)
     211#define CODEC_F00_0A_44_1KHZ_MULT_4X                       RT_BIT(9)
     212#define CODEC_F00_0A_48KHZ_MULT_2X                         RT_BIT(8)
     213#define CODEC_F00_0A_44_1KHZ_MULT_2X                       RT_BIT(7)
     214#define CODEC_F00_0A_48KHZ                                 RT_BIT(6)
     215#define CODEC_F00_0A_44_1KHZ                               RT_BIT(5)
     216/* 2/3 * 48kHz */
     217#define CODEC_F00_0A_48KHZ_2_3X                            RT_BIT(4)
     218/* 1/2 * 44.1kHz */
     219#define CODEC_F00_0A_44_1KHZ_1_2X                          RT_BIT(3)
     220/* 1/3 * 48kHz */
     221#define CODEC_F00_0A_48KHZ_1_3X                            RT_BIT(2)
     222/* 1/4 * 44.1kHz */
     223#define CODEC_F00_0A_44_1KHZ_1_4X                          RT_BIT(1)
     224/* 1/6 * 48kHz */
     225#define CODEC_F00_0A_48KHZ_1_6X                            RT_BIT(0)
     226
     227/* Supported streams formats (7.3.4.8) */
     228#define CODEC_F00_0B_AC3                                   RT_BIT(2)
     229#define CODEC_F00_0B_FLOAT32                               RT_BIT(1)
     230#define CODEC_F00_0B_PCM                                   RT_BIT(0)
     231
     232/* Pin Capabilities (7.3.4.9)*/
     233#define CODEC_MAKE_F00_0C(vref_ctrl) (((vref_ctrl) & 0xFF) << 8)
     234#define CODEC_F00_0C_CAP_HBR                               RT_BIT(27)
     235#define CODEC_F00_0C_CAP_DP                                RT_BIT(24)
     236#define CODEC_F00_0C_CAP_EAPD                              RT_BIT(16)
     237#define CODEC_F00_0C_CAP_HDMI                              RT_BIT(7)
     238#define CODEC_F00_0C_CAP_BALANCED_IO                       RT_BIT(6)
     239#define CODEC_F00_0C_CAP_INPUT                             RT_BIT(5)
     240#define CODEC_F00_0C_CAP_OUTPUT                            RT_BIT(4)
     241#define CODEC_F00_0C_CAP_HEADPHONE_AMP                     RT_BIT(3)
     242#define CODEC_F00_0C_CAP_PRESENCE_DETECT                   RT_BIT(2)
     243#define CODEC_F00_0C_CAP_TRIGGER_REQUIRED                  RT_BIT(1)
     244#define CODEC_F00_0C_CAP_IMPENDANCE_SENSE                  RT_BIT(0)
     245
     246#define CODEC_F00_0C_IS_CAP_HBR(f00_0c)                    ((f00_0c) & RT_BIT(27))
     247#define CODEC_F00_0C_IS_CAP_DP(f00_0c)                     ((f00_0c) & RT_BIT(24))
     248#define CODEC_F00_0C_IS_CAP_EAPD(f00_0c)                   ((f00_0c) & RT_BIT(16))
     249#define CODEC_F00_0C_IS_CAP_HDMI(f00_0c)                   ((f00_0c) & RT_BIT(7))
     250#define CODEC_F00_0C_IS_CAP_BALANCED_IO(f00_0c)            ((f00_0c) & RT_BIT(6))
     251#define CODEC_F00_0C_IS_CAP_INPUT(f00_0c)                  ((f00_0c) & RT_BIT(5))
     252#define CODEC_F00_0C_IS_CAP_OUTPUT(f00_0c)                 ((f00_0c) & RT_BIT(4))
     253#define CODEC_F00_0C_IS_CAP_HP(f00_0c)                     ((f00_0c) & RT_BIT(3))
     254#define CODEC_F00_0C_IS_CAP_PRESENCE_DETECT(f00_0c)        ((f00_0c) & RT_BIT(2))
     255#define CODEC_F00_0C_IS_CAP_TRIGGER_REQUIRED(f00_0c)       ((f00_0c) & RT_BIT(1))
     256#define CODEC_F00_0C_IS_CAP_IMPENDANCE_SENSE(f00_0c)       ((f00_0c) & RT_BIT(0))
     257
     258/* Input Amplifier capabilities (7.3.4.10). */
     259#define CODEC_MAKE_F00_0D(mute_cap, step_size, num_steps, offset) \
     260        (  (((mute_cap)  & UINT32_C(0x1))  << 31) \
     261         | (((step_size) & UINT32_C(0xFF)) << 16) \
     262         | (((num_steps) & UINT32_C(0xFF)) << 8) \
     263         |  ((offset)    & UINT32_C(0xFF)))
     264
     265#define CODEC_F00_0D_CAP_MUTE                              RT_BIT(7)
     266
     267#define CODEC_F00_0D_IS_CAP_MUTE(f00_0d)                   ( ( f00_0d) & RT_BIT(31))
     268#define CODEC_F00_0D_STEP_SIZE(f00_0d)                     ((( f00_0d) & (0x7F << 16)) >> 16)
     269#define CODEC_F00_0D_NUM_STEPS(f00_0d)                     ((((f00_0d) & (0x7F << 8)) >> 8) + 1)
     270#define CODEC_F00_0D_OFFSET(f00_0d)                        (  (f00_0d) & 0x7F)
     271
     272/** Indicates that the amplifier can be muted. */
     273#define CODEC_AMP_CAP_MUTE                                 0x1
     274/** The amplifier's maximum number of steps. We want
     275 *  a ~90dB dynamic range, so 64 steps with 1.25dB each
     276 *  should do the trick.
     277 *
     278 *  As we want to map our range to [0..128] values we can avoid
     279 *  multiplication and simply doing a shift later.
     280 *
     281 *  Produces -96dB to +0dB.
     282 *  "0" indicates a step of 0.25dB, "127" indicates a step of 32dB.
     283 */
     284#define CODEC_AMP_NUM_STEPS                                0x7F
     285/** The initial gain offset (and when doing a node reset). */
     286#define CODEC_AMP_OFF_INITIAL                              0x7F
     287/** The amplifier's gain step size. */
     288#define CODEC_AMP_STEP_SIZE                                0x2
     289
     290/* Output Amplifier capabilities (7.3.4.10) */
     291#define CODEC_MAKE_F00_12                                  CODEC_MAKE_F00_0D
     292
     293#define CODEC_F00_12_IS_CAP_MUTE(f00_12)                   CODEC_F00_0D_IS_CAP_MUTE(f00_12)
     294#define CODEC_F00_12_STEP_SIZE(f00_12)                     CODEC_F00_0D_STEP_SIZE(f00_12)
     295#define CODEC_F00_12_NUM_STEPS(f00_12)                     CODEC_F00_0D_NUM_STEPS(f00_12)
     296#define CODEC_F00_12_OFFSET(f00_12)                        CODEC_F00_0D_OFFSET(f00_12)
     297
     298/* Connection list lenght (7.3.4.11). */
     299#define CODEC_MAKE_F00_0E(long_form, length)    \
     300    (  (((long_form) & 0x1) << 7)               \
     301     | ((length) & 0x7F))
     302/* Indicates short-form NIDs. */
     303#define CODEC_F00_0E_LIST_NID_SHORT                        0
     304/* Indicates long-form NIDs. */
     305#define CODEC_F00_0E_LIST_NID_LONG                         1
     306#define CODEC_F00_0E_IS_LONG(f00_0e)                       RT_BOOL((f00_0e) & RT_BIT(7))
     307#define CODEC_F00_0E_COUNT(f00_0e)                         ((f00_0e) & 0x7F)
     308/* Supported Power States (7.3.4.12) */
     309#define CODEC_F00_0F_EPSS                                  RT_BIT(31)
     310#define CODEC_F00_0F_CLKSTOP                               RT_BIT(30)
     311#define CODEC_F00_0F_S3D3                                  RT_BIT(29)
     312#define CODEC_F00_0F_D3COLD                                RT_BIT(4)
     313#define CODEC_F00_0F_D3                                    RT_BIT(3)
     314#define CODEC_F00_0F_D2                                    RT_BIT(2)
     315#define CODEC_F00_0F_D1                                    RT_BIT(1)
     316#define CODEC_F00_0F_D0                                    RT_BIT(0)
     317
     318/* Processing capabilities 7.3.4.13 */
     319#define CODEC_MAKE_F00_10(num, benign)                     ((((num) & 0xFF) << 8) | ((benign) & 0x1))
     320#define CODEC_F00_10_NUM(f00_10)                           (((f00_10) & (0xFF << 8)) >> 8)
     321#define CODEC_F00_10_BENING(f00_10)                        ((f00_10) & 0x1)
     322
     323/* GPIO count (7.3.4.14). */
     324#define CODEC_MAKE_F00_11(wake, unsol, numgpi, numgpo, numgpio) \
     325    (  (((wake)   & UINT32_C(0x1))  << 31) \
     326     | (((unsol)  & UINT32_C(0x1))  << 30) \
     327     | (((numgpi) & UINT32_C(0xFF)) << 16) \
     328     | (((numgpo) & UINT32_C(0xFF)) << 8) \
     329     | ((numgpio) & UINT32_C(0xFF)))
     330
     331/* Processing States (7.3.3.4). */
     332#define CODEC_F03_OFF                                      (0)
     333#define CODEC_F03_ON                                       RT_BIT(0)
     334#define CODEC_F03_BENING                                   RT_BIT(1)
     335/* Power States (7.3.3.10). */
     336#define CODEC_MAKE_F05(reset, stopok, error, act, set) \
     337    (  (((reset)  & 0x1) << 10) \
     338     | (((stopok) & 0x1) << 9) \
     339     | (((error)  & 0x1) << 8) \
     340     | (((act)    & 0xF) << 4) \
     341     | ((set)     & 0xF))
     342#define CODEC_F05_D3COLD                                   (4)
     343#define CODEC_F05_D3                                       (3)
     344#define CODEC_F05_D2                                       (2)
     345#define CODEC_F05_D1                                       (1)
     346#define CODEC_F05_D0                                       (0)
     347
     348#define CODEC_F05_IS_RESET(value)                          (((value) & RT_BIT(10)) != 0)
     349#define CODEC_F05_IS_STOPOK(value)                         (((value) & RT_BIT(9)) != 0)
     350#define CODEC_F05_IS_ERROR(value)                          (((value) & RT_BIT(8)) != 0)
     351#define CODEC_F05_ACT(value)                               (((value) & 0xF0) >> 4)
     352#define CODEC_F05_SET(value)                               (((value) & 0xF))
     353
     354#define CODEC_F05_GE(p0, p1)                               ((p0) <= (p1))
     355#define CODEC_F05_LE(p0, p1)                               ((p0) >= (p1))
     356
     357/* Converter Stream, Channel (7.3.3.11). */
     358#define CODEC_MAKE_F06(stream, channel) \
     359    (  (((stream)  & 0xF) << 4)         \
     360     |  ((channel) & 0xF))
     361#define CODEC_F06_STREAM(value)                            ((value) & 0xF0)
     362#define CODEC_F06_CHANNEL(value)                           ((value) & 0xF)
     363
     364/* Pin Widged Control (7.3.3.13). */
     365#define CODEC_F07_VREF_HIZ                                 (0)
     366#define CODEC_F07_VREF_50                                  (0x1)
     367#define CODEC_F07_VREF_GROUND                              (0x2)
     368#define CODEC_F07_VREF_80                                  (0x4)
     369#define CODEC_F07_VREF_100                                 (0x5)
     370#define CODEC_F07_IN_ENABLE                                RT_BIT(5)
     371#define CODEC_F07_OUT_ENABLE                               RT_BIT(6)
     372#define CODEC_F07_OUT_H_ENABLE                             RT_BIT(7)
     373
     374/* Volume Knob Control (7.3.3.29). */
     375#define CODEC_F0F_IS_DIRECT                                RT_BIT(7)
     376#define CODEC_F0F_VOLUME                                   (0x7F)
     377
     378/* Unsolicited enabled (7.3.3.14). */
     379#define CODEC_MAKE_F08(enable, tag) ((((enable) & 1) << 7) | ((tag) & 0x3F))
     380
     381/* Converter formats (7.3.3.8) and (3.7.1). */
     382/* This is the same format as SDnFMT. */
     383#define CODEC_MAKE_A                                       HDA_SDFMT_MAKE
     384
     385#define CODEC_A_TYPE                                       HDA_SDFMT_TYPE
     386#define CODEC_A_TYPE_PCM                                   HDA_SDFMT_TYPE_PCM
     387#define CODEC_A_TYPE_NON_PCM                               HDA_SDFMT_TYPE_NON_PCM
     388
     389#define CODEC_A_BASE                                       HDA_SDFMT_BASE
     390#define CODEC_A_BASE_48KHZ                                 HDA_SDFMT_BASE_48KHZ
     391#define CODEC_A_BASE_44KHZ                                 HDA_SDFMT_BASE_44KHZ
     392
     393/* Pin Sense (7.3.3.15). */
     394#define CODEC_MAKE_F09_ANALOG(fPresent, impedance)  \
     395(  (((fPresent) & 0x1) << 31)                       \
     396 | (((impedance) & UINT32_C(0x7FFFFFFF))))
     397#define CODEC_F09_ANALOG_NA    UINT32_C(0x7FFFFFFF)
     398#define CODEC_MAKE_F09_DIGITAL(fPresent, fELDValid) \
     399(   (((fPresent)  & UINT32_C(0x1)) << 31)                      \
     400  | (((fELDValid) & UINT32_C(0x1)) << 30))
     401
     402#define CODEC_MAKE_F0C(lrswap, eapd, btl) ((((lrswap) & 1) << 2) | (((eapd) & 1) << 1) | ((btl) & 1))
     403#define CODEC_FOC_IS_LRSWAP(f0c)                           RT_BOOL((f0c) & RT_BIT(2))
     404#define CODEC_FOC_IS_EAPD(f0c)                             RT_BOOL((f0c) & RT_BIT(1))
     405#define CODEC_FOC_IS_BTL(f0c)                              RT_BOOL((f0c) & RT_BIT(0))
     406/* HDA spec 7.3.3.31 defines layout of configuration registers/verbs (0xF1C) */
     407/* Configuration's port connection */
     408#define CODEC_F1C_PORT_MASK                                (0x3)
     409#define CODEC_F1C_PORT_SHIFT                               (30)
     410
     411#define CODEC_F1C_PORT_COMPLEX                             (0x0)
     412#define CODEC_F1C_PORT_NO_PHYS                             (0x1)
     413#define CODEC_F1C_PORT_FIXED                               (0x2)
     414#define CODEC_F1C_BOTH                                     (0x3)
     415
     416/* Configuration default: connection */
     417#define CODEC_F1C_PORT_MASK                                (0x3)
     418#define CODEC_F1C_PORT_SHIFT                               (30)
     419
     420/* Connected to a jack (1/8", ATAPI, ...). */
     421#define CODEC_F1C_PORT_COMPLEX                             (0x0)
     422/* No physical connection. */
     423#define CODEC_F1C_PORT_NO_PHYS                             (0x1)
     424/* Fixed function device (integrated speaker, integrated mic, ...). */
     425#define CODEC_F1C_PORT_FIXED                               (0x2)
     426/* Both, a jack and an internal device are attached. */
     427#define CODEC_F1C_BOTH                                     (0x3)
     428
     429/* Configuration default: Location */
     430#define CODEC_F1C_LOCATION_MASK                            (0x3F)
     431#define CODEC_F1C_LOCATION_SHIFT                           (24)
     432
     433/* [4:5] bits of location region means chassis attachment */
     434#define CODEC_F1C_LOCATION_PRIMARY_CHASSIS                 (0)
     435#define CODEC_F1C_LOCATION_INTERNAL                        RT_BIT(4)
     436#define CODEC_F1C_LOCATION_SECONDRARY_CHASSIS              RT_BIT(5)
     437#define CODEC_F1C_LOCATION_OTHER                           RT_BIT(5)
     438
     439/* [0:3] bits of location region means geometry location attachment */
     440#define CODEC_F1C_LOCATION_NA                              (0)
     441#define CODEC_F1C_LOCATION_REAR                            (0x1)
     442#define CODEC_F1C_LOCATION_FRONT                           (0x2)
     443#define CODEC_F1C_LOCATION_LEFT                            (0x3)
     444#define CODEC_F1C_LOCATION_RIGTH                           (0x4)
     445#define CODEC_F1C_LOCATION_TOP                             (0x5)
     446#define CODEC_F1C_LOCATION_BOTTOM                          (0x6)
     447#define CODEC_F1C_LOCATION_SPECIAL_0                       (0x7)
     448#define CODEC_F1C_LOCATION_SPECIAL_1                       (0x8)
     449#define CODEC_F1C_LOCATION_SPECIAL_2                       (0x9)
     450
     451/* Configuration default: Device type */
     452#define CODEC_F1C_DEVICE_MASK                              (0xF)
     453#define CODEC_F1C_DEVICE_SHIFT                             (20)
     454#define CODEC_F1C_DEVICE_LINE_OUT                          (0)
     455#define CODEC_F1C_DEVICE_SPEAKER                           (0x1)
     456#define CODEC_F1C_DEVICE_HP                                (0x2)
     457#define CODEC_F1C_DEVICE_CD                                (0x3)
     458#define CODEC_F1C_DEVICE_SPDIF_OUT                         (0x4)
     459#define CODEC_F1C_DEVICE_DIGITAL_OTHER_OUT                 (0x5)
     460#define CODEC_F1C_DEVICE_MODEM_LINE_SIDE                   (0x6)
     461#define CODEC_F1C_DEVICE_MODEM_HANDSET_SIDE                (0x7)
     462#define CODEC_F1C_DEVICE_LINE_IN                           (0x8)
     463#define CODEC_F1C_DEVICE_AUX                               (0x9)
     464#define CODEC_F1C_DEVICE_MIC                               (0xA)
     465#define CODEC_F1C_DEVICE_PHONE                             (0xB)
     466#define CODEC_F1C_DEVICE_SPDIF_IN                          (0xC)
     467#define CODEC_F1C_DEVICE_RESERVED                          (0xE)
     468#define CODEC_F1C_DEVICE_OTHER                             (0xF)
     469
     470/* Configuration default: Connection type */
     471#define CODEC_F1C_CONNECTION_TYPE_MASK                     (0xF)
     472#define CODEC_F1C_CONNECTION_TYPE_SHIFT                    (16)
     473
     474#define CODEC_F1C_CONNECTION_TYPE_UNKNOWN                  (0)
     475#define CODEC_F1C_CONNECTION_TYPE_1_8INCHES                (0x1)
     476#define CODEC_F1C_CONNECTION_TYPE_1_4INCHES                (0x2)
     477#define CODEC_F1C_CONNECTION_TYPE_ATAPI                    (0x3)
     478#define CODEC_F1C_CONNECTION_TYPE_RCA                      (0x4)
     479#define CODEC_F1C_CONNECTION_TYPE_OPTICAL                  (0x5)
     480#define CODEC_F1C_CONNECTION_TYPE_OTHER_DIGITAL            (0x6)
     481#define CODEC_F1C_CONNECTION_TYPE_ANALOG                   (0x7)
     482#define CODEC_F1C_CONNECTION_TYPE_DIN                      (0x8)
     483#define CODEC_F1C_CONNECTION_TYPE_XLR                      (0x9)
     484#define CODEC_F1C_CONNECTION_TYPE_RJ_11                    (0xA)
     485#define CODEC_F1C_CONNECTION_TYPE_COMBO                    (0xB)
     486#define CODEC_F1C_CONNECTION_TYPE_OTHER                    (0xF)
     487
     488/* Configuration's color */
     489#define CODEC_F1C_COLOR_MASK                               (0xF)
     490#define CODEC_F1C_COLOR_SHIFT                              (12)
     491#define CODEC_F1C_COLOR_UNKNOWN                            (0)
     492#define CODEC_F1C_COLOR_BLACK                              (0x1)
     493#define CODEC_F1C_COLOR_GREY                               (0x2)
     494#define CODEC_F1C_COLOR_BLUE                               (0x3)
     495#define CODEC_F1C_COLOR_GREEN                              (0x4)
     496#define CODEC_F1C_COLOR_RED                                (0x5)
     497#define CODEC_F1C_COLOR_ORANGE                             (0x6)
     498#define CODEC_F1C_COLOR_YELLOW                             (0x7)
     499#define CODEC_F1C_COLOR_PURPLE                             (0x8)
     500#define CODEC_F1C_COLOR_PINK                               (0x9)
     501#define CODEC_F1C_COLOR_RESERVED_0                         (0xA)
     502#define CODEC_F1C_COLOR_RESERVED_1                         (0xB)
     503#define CODEC_F1C_COLOR_RESERVED_2                         (0xC)
     504#define CODEC_F1C_COLOR_RESERVED_3                         (0xD)
     505#define CODEC_F1C_COLOR_WHITE                              (0xE)
     506#define CODEC_F1C_COLOR_OTHER                              (0xF)
     507
     508/* Configuration's misc */
     509#define CODEC_F1C_MISC_MASK                                (0xF)
     510#define CODEC_F1C_MISC_SHIFT                               (8)
     511#define CODEC_F1C_MISC_NONE                                0
     512#define CODEC_F1C_MISC_JACK_NO_PRESENCE_DETECT             RT_BIT(0)
     513#define CODEC_F1C_MISC_RESERVED_0                          RT_BIT(1)
     514#define CODEC_F1C_MISC_RESERVED_1                          RT_BIT(2)
     515#define CODEC_F1C_MISC_RESERVED_2                          RT_BIT(3)
     516
     517/* Configuration default: Association */
     518#define CODEC_F1C_ASSOCIATION_MASK                         (0xF)
     519#define CODEC_F1C_ASSOCIATION_SHIFT                        (4)
     520
     521/** Reserved; don't use. */
     522#define CODEC_F1C_ASSOCIATION_INVALID                      0x0
     523#define CODEC_F1C_ASSOCIATION_GROUP_0                      0x1
     524#define CODEC_F1C_ASSOCIATION_GROUP_1                      0x2
     525#define CODEC_F1C_ASSOCIATION_GROUP_2                      0x3
     526#define CODEC_F1C_ASSOCIATION_GROUP_3                      0x4
     527#define CODEC_F1C_ASSOCIATION_GROUP_4                      0x5
     528#define CODEC_F1C_ASSOCIATION_GROUP_5                      0x6
     529#define CODEC_F1C_ASSOCIATION_GROUP_6                      0x7
     530#define CODEC_F1C_ASSOCIATION_GROUP_7                      0x8
     531/* Note: Windows OSes will treat group 15 (0xF) as single PIN devices.
     532 *       The sequence number associated with that group then will be ignored. */
     533#define CODEC_F1C_ASSOCIATION_GROUP_15                     0xF
     534
     535/* Configuration default: Association Sequence. */
     536#define CODEC_F1C_SEQ_MASK                                 (0xF)
     537#define CODEC_F1C_SEQ_SHIFT                                (0)
     538
     539/* Implementation identification (7.3.3.30). */
     540#define CODEC_MAKE_F20(bmid, bsku, aid)     \
     541    (  (((bmid) & 0xFFFF) << 16)            \
     542     | (((bsku) & 0xFF) << 8)               \
     543     | (((aid) & 0xFF))                     \
     544    )
     545
     546/* Macro definition helping in filling the configuration registers. */
     547#define CODEC_MAKE_F1C(port_connectivity, location, device, connection_type, color, misc, association, sequence)    \
     548    (  (((port_connectivity) & 0xF) << CODEC_F1C_PORT_SHIFT)            \
     549     | (((location)          & 0xF) << CODEC_F1C_LOCATION_SHIFT)        \
     550     | (((device)            & 0xF) << CODEC_F1C_DEVICE_SHIFT)          \
     551     | (((connection_type)   & 0xF) << CODEC_F1C_CONNECTION_TYPE_SHIFT) \
     552     | (((color)             & 0xF) << CODEC_F1C_COLOR_SHIFT)           \
     553     | (((misc)              & 0xF) << CODEC_F1C_MISC_SHIFT)            \
     554     | (((association)       & 0xF) << CODEC_F1C_ASSOCIATION_SHIFT)     \
     555     | (((sequence)          & 0xF)))
     556
     557
     558/*********************************************************************************************************************************
     559*   Structures and Typedefs                                                                                                      *
     560*********************************************************************************************************************************/
     561/** The F00 parameter length (in dwords). */
     562#define CODECNODE_F00_PARAM_LENGTH  20
     563/** The F02 parameter length (in dwords). */
     564#define CODECNODE_F02_PARAM_LENGTH  16
    42565
    43566/* PRM 5.3.1 */
    44567#define CODEC_RESPONSE_UNSOLICITED RT_BIT_64(34)
    45568
    46 typedef struct CODECVERB
     569/**
     570 * Structure for maintaining a codec verb implementation (ring-0).
     571 */
     572typedef struct CODECVERBR0
    47573{
    48574    /** Verb. */
    49     uint32_t                 verb;
     575    uint32_t                   verb;
    50576    /** Verb mask. */
    51     uint32_t                 mask;
     577    uint32_t                   mask;
    52578    /** Function pointer for implementation callback. */
    53     PFNHDACODECVERBPROCESSOR pfn;
     579    PFNHDACODECVERBPROCESSORR0 pfn;
    54580    /** Friendly name, for debugging. */
    55     const char              *pszName;
    56 } CODECVERB;
    57 
    58 union CODECNODE;
    59 typedef union CODECNODE CODECNODE, *PCODECNODE;
     581    const char                *pszName;
     582} CODECVERBR0;
     583/** Ponter to a  codec verb implementation (ring-0). */
     584typedef CODECVERBR0 *PCODECVERBR0;
    60585
    61586/**
    62  * HDA codec state.
     587 * Structure for maintaining a codec verb implementation (ring-3).
     588 */
     589typedef struct CODECVERBR3
     590{
     591    /** Verb. */
     592    uint32_t                   verb;
     593    /** Verb mask. */
     594    uint32_t                   mask;
     595    /** Function pointer for implementation callback. */
     596    PFNHDACODECVERBPROCESSORR3 pfn;
     597    /** Friendly name, for debugging. */
     598    const char                *pszName;
     599} CODECVERBR3;
     600/** Ponter to a  codec verb implementation (ring-3). */
     601typedef CODECVERBR3 *PCODECVERBR3;
     602
     603#define AMPLIFIER_SIZE 60
     604
     605typedef uint32_t AMPLIFIER[AMPLIFIER_SIZE];
     606
     607/**
     608 * Common (or core) codec node structure.
     609 */
     610typedef struct CODECCOMMONNODE
     611{
     612    /** The node's ID. */
     613    uint8_t         uID;
     614    /** The node's name. */
     615    /** The SDn ID this node is assigned to.
     616     *  0 means not assigned, 1 is SDn0. */
     617    uint8_t         uSD;
     618    /** The SDn's channel to use.
     619     *  Only valid if a valid SDn ID is set. */
     620    uint8_t         uChannel;
     621    /* PRM 5.3.6 */
     622    uint32_t        au32F00_param[CODECNODE_F00_PARAM_LENGTH];
     623    uint32_t        au32F02_param[CODECNODE_F02_PARAM_LENGTH];
     624} CODECCOMMONNODE;
     625typedef CODECCOMMONNODE *PCODECCOMMONNODE;
     626AssertCompile(CODECNODE_F00_PARAM_LENGTH == 20);  /* saved state */
     627AssertCompile(CODECNODE_F02_PARAM_LENGTH == 16); /* saved state */
     628
     629/**
     630 * Compile time assertion on the expected node size.
     631 */
     632#define AssertNodeSize(a_Node, a_cParams) \
     633    AssertCompile((a_cParams) <= (60 + 6)); /* the max size - saved state */ \
     634    AssertCompile(   sizeof(a_Node) - sizeof(CODECCOMMONNODE)  \
     635                  == ((a_cParams) * sizeof(uint32_t)) )
     636
     637typedef struct ROOTCODECNODE
     638{
     639    CODECCOMMONNODE node;
     640} ROOTCODECNODE, *PROOTCODECNODE;
     641AssertNodeSize(ROOTCODECNODE, 0);
     642
     643typedef struct DACNODE
     644{
     645    CODECCOMMONNODE node;
     646    uint32_t    u32F0d_param;
     647    uint32_t    u32F04_param;
     648    uint32_t    u32F05_param;
     649    uint32_t    u32F06_param;
     650    uint32_t    u32F0c_param;
     651
     652    uint32_t    u32A_param;
     653    AMPLIFIER   B_params;
     654
     655} DACNODE, *PDACNODE;
     656AssertNodeSize(DACNODE, 6 + 60);
     657
     658typedef struct ADCNODE
     659{
     660    CODECCOMMONNODE node;
     661    uint32_t    u32F01_param;
     662    uint32_t    u32F03_param;
     663    uint32_t    u32F05_param;
     664    uint32_t    u32F06_param;
     665    uint32_t    u32F09_param;
     666
     667    uint32_t    u32A_param;
     668    AMPLIFIER   B_params;
     669} ADCNODE, *PADCNODE;
     670AssertNodeSize(DACNODE, 6 + 60);
     671
     672typedef struct SPDIFOUTNODE
     673{
     674    CODECCOMMONNODE node;
     675    uint32_t    u32F05_param;
     676    uint32_t    u32F06_param;
     677    uint32_t    u32F09_param;
     678    uint32_t    u32F0d_param;
     679
     680    uint32_t    u32A_param;
     681    AMPLIFIER   B_params;
     682} SPDIFOUTNODE, *PSPDIFOUTNODE;
     683AssertNodeSize(SPDIFOUTNODE, 5 + 60);
     684
     685typedef struct SPDIFINNODE
     686{
     687    CODECCOMMONNODE node;
     688    uint32_t    u32F05_param;
     689    uint32_t    u32F06_param;
     690    uint32_t    u32F09_param;
     691    uint32_t    u32F0d_param;
     692
     693    uint32_t    u32A_param;
     694    AMPLIFIER   B_params;
     695} SPDIFINNODE, *PSPDIFINNODE;
     696AssertNodeSize(SPDIFINNODE, 5 + 60);
     697
     698typedef struct AFGCODECNODE
     699{
     700    CODECCOMMONNODE node;
     701    uint32_t  u32F05_param;
     702    uint32_t  u32F08_param;
     703    uint32_t  u32F17_param;
     704    uint32_t  u32F20_param;
     705} AFGCODECNODE, *PAFGCODECNODE;
     706AssertNodeSize(AFGCODECNODE, 4);
     707
     708typedef struct PORTNODE
     709{
     710    CODECCOMMONNODE node;
     711    uint32_t u32F01_param;
     712    uint32_t u32F07_param;
     713    uint32_t u32F08_param;
     714    uint32_t u32F09_param;
     715    uint32_t u32F1c_param;
     716    AMPLIFIER   B_params;
     717} PORTNODE, *PPORTNODE;
     718AssertNodeSize(PORTNODE, 5 + 60);
     719
     720typedef struct DIGOUTNODE
     721{
     722    CODECCOMMONNODE node;
     723    uint32_t u32F01_param;
     724    uint32_t u32F05_param;
     725    uint32_t u32F07_param;
     726    uint32_t u32F08_param;
     727    uint32_t u32F09_param;
     728    uint32_t u32F1c_param;
     729} DIGOUTNODE, *PDIGOUTNODE;
     730AssertNodeSize(DIGOUTNODE, 6);
     731
     732typedef struct DIGINNODE
     733{
     734    CODECCOMMONNODE node;
     735    uint32_t u32F05_param;
     736    uint32_t u32F07_param;
     737    uint32_t u32F08_param;
     738    uint32_t u32F09_param;
     739    uint32_t u32F0c_param;
     740    uint32_t u32F1c_param;
     741    uint32_t u32F1e_param;
     742} DIGINNODE, *PDIGINNODE;
     743AssertNodeSize(DIGINNODE, 7);
     744
     745typedef struct ADCMUXNODE
     746{
     747    CODECCOMMONNODE node;
     748    uint32_t    u32F01_param;
     749
     750    uint32_t    u32A_param;
     751    AMPLIFIER   B_params;
     752} ADCMUXNODE, *PADCMUXNODE;
     753AssertNodeSize(ADCMUXNODE, 2 + 60);
     754
     755typedef struct PCBEEPNODE
     756{
     757    CODECCOMMONNODE node;
     758    uint32_t    u32F07_param;
     759    uint32_t    u32F0a_param;
     760
     761    uint32_t    u32A_param;
     762    AMPLIFIER   B_params;
     763    uint32_t    u32F1c_param;
     764} PCBEEPNODE, *PPCBEEPNODE;
     765AssertNodeSize(PCBEEPNODE, 3 + 60 + 1);
     766
     767typedef struct CDNODE
     768{
     769    CODECCOMMONNODE node;
     770    uint32_t u32F07_param;
     771    uint32_t u32F1c_param;
     772} CDNODE, *PCDNODE;
     773AssertNodeSize(CDNODE, 2);
     774
     775typedef struct VOLUMEKNOBNODE
     776{
     777    CODECCOMMONNODE node;
     778    uint32_t    u32F08_param;
     779    uint32_t    u32F0f_param;
     780} VOLUMEKNOBNODE, *PVOLUMEKNOBNODE;
     781AssertNodeSize(VOLUMEKNOBNODE, 2);
     782
     783typedef struct ADCVOLNODE
     784{
     785    CODECCOMMONNODE node;
     786    uint32_t    u32F0c_param;
     787    uint32_t    u32F01_param;
     788    uint32_t    u32A_params;
     789    AMPLIFIER   B_params;
     790} ADCVOLNODE, *PADCVOLNODE;
     791AssertNodeSize(ADCVOLNODE, 3 + 60);
     792
     793typedef struct RESNODE
     794{
     795    CODECCOMMONNODE node;
     796    uint32_t    u32F05_param;
     797    uint32_t    u32F06_param;
     798    uint32_t    u32F07_param;
     799    uint32_t    u32F1c_param;
     800
     801    uint32_t    u32A_param;
     802} RESNODE, *PRESNODE;
     803AssertNodeSize(RESNODE, 5);
     804
     805/**
     806 * Used for the saved state.
     807 */
     808typedef struct CODECSAVEDSTATENODE
     809{
     810    CODECCOMMONNODE Core;
     811    uint32_t        au32Params[60 + 6];
     812} CODECSAVEDSTATENODE;
     813AssertNodeSize(CODECSAVEDSTATENODE, 60 + 6);
     814
     815typedef union CODECNODE
     816{
     817    CODECCOMMONNODE node;
     818    ROOTCODECNODE   root;
     819    AFGCODECNODE    afg;
     820    DACNODE         dac;
     821    ADCNODE         adc;
     822    SPDIFOUTNODE    spdifout;
     823    SPDIFINNODE     spdifin;
     824    PORTNODE        port;
     825    DIGOUTNODE      digout;
     826    DIGINNODE       digin;
     827    ADCMUXNODE      adcmux;
     828    PCBEEPNODE      pcbeep;
     829    CDNODE          cdnode;
     830    VOLUMEKNOBNODE  volumeKnob;
     831    ADCVOLNODE      adcvol;
     832    RESNODE         reserved;
     833    CODECSAVEDSTATENODE SavedState;
     834} CODECNODE, *PCODECNODE;
     835AssertNodeSize(CODECNODE, 60 + 6);
     836
     837#define CODEC_VERBS_MAX     64
     838#define CODEC_NODES_MAX     32
     839
     840/**
     841 * HDA codec state (shared).
    63842 */
    64843typedef struct HDACODEC
    65844{
    66     uint16_t                id;
    67     uint16_t                u16VendorId;
    68     uint16_t                u16DeviceId;
    69     uint8_t                 u8BSKU;
    70     uint8_t                 u8AssemblyId;
    71 
    72     /** List of assigned HDA drivers to this codec.
    73      * A driver only can be assigned to one codec at a time. */
    74     RTLISTANCHOR            lstDrv;
    75 
    76     CODECVERB const        *paVerbs;
     845    /** Codec implementation type. */
     846    CODEC_TYPE enmType;
     847    /** Codec ID. */
     848    uint16_t   id;
     849    uint16_t   u16VendorId;
     850    uint16_t   u16DeviceId;
     851    uint8_t    u8BSKU;
     852    uint8_t    u8AssemblyId;
     853
     854    CODECNODE  aNodes[CODEC_NODES_MAX];
     855    size_t     cNodes;
     856
     857    bool       fInReset;
     858    uint8_t    abPadding1[3];
     859
     860    uint8_t    cTotalNodes;
     861    uint8_t    u8AdcVolsLineIn;
     862    uint8_t    u8DacLineOut;
     863    uint8_t    bPadding2;
     864
     865    uint8_t    au8Ports[CODEC_NODES_MAX];
     866    uint8_t    au8Dacs[CODEC_NODES_MAX];
     867    uint8_t    au8AdcVols[CODEC_NODES_MAX];
     868    uint8_t    au8Adcs[CODEC_NODES_MAX];
     869    uint8_t    au8AdcMuxs[CODEC_NODES_MAX];
     870    uint8_t    au8Pcbeeps[CODEC_NODES_MAX];
     871    uint8_t    au8SpdifIns[CODEC_NODES_MAX];
     872    uint8_t    au8SpdifOuts[CODEC_NODES_MAX];
     873    uint8_t    au8DigInPins[CODEC_NODES_MAX];
     874    uint8_t    au8DigOutPins[CODEC_NODES_MAX];
     875    uint8_t    au8Cds[CODEC_NODES_MAX];
     876    uint8_t    au8VolKnobs[CODEC_NODES_MAX];
     877    uint8_t    au8Reserveds[CODEC_NODES_MAX];
     878} HDACODEC;
     879
     880/**
     881 * HDA codec state (ring-0).
     882 */
     883typedef struct HDACODECR0
     884{
     885    CODECVERBR0             aVerbs[CODEC_VERBS_MAX];
    77886    size_t                  cVerbs;
    78 
    79     PCODECNODE              paNodes;
    80 
    81     bool                    fInReset;
    82     uint8_t                 abPadding1[3];
    83 
    84     const uint8_t           cTotalNodes;
    85     const uint8_t           u8AdcVolsLineIn;
    86     const uint8_t           u8DacLineOut;
    87     uint8_t                 bPadding2;
    88     const uint8_t          *au8Ports;
    89     const uint8_t          *au8Dacs;
    90     const uint8_t          *au8AdcVols;
    91     const uint8_t          *au8Adcs;
    92     const uint8_t          *au8AdcMuxs;
    93     const uint8_t          *au8Pcbeeps;
    94     const uint8_t          *au8SpdifIns;
    95     const uint8_t          *au8SpdifOuts;
    96     const uint8_t          *au8DigInPins;
    97     const uint8_t          *au8DigOutPins;
    98     const uint8_t          *au8Cds;
    99     const uint8_t          *au8VolKnobs;
    100     const uint8_t          *au8Reserveds;
    101887
    102888    /** @name Public codec functions.
    103889     *  @{  */
    104     DECLR3CALLBACKMEMBER(int,  pfnLookup, (PHDACODEC pThis, uint32_t uVerb, uint64_t *puResp));
    105     DECLR3CALLBACKMEMBER(void, pfnReset, (PHDACODEC pThis));
    106     DECLR3CALLBACKMEMBER(int,  pfnNodeReset, (PHDACODEC pThis, uint8_t, PCODECNODE));
    107     DECLR3CALLBACKMEMBER(void, pfnDbgListNodes, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs));
    108     DECLR3CALLBACKMEMBER(void, pfnDbgSelector, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs));
     890    DECLCALLBACKMEMBER(void, pfnReset, (PHDACODEC pThis, PHDACODECR0 pThisCC));
     891    DECLCALLBACKMEMBER(int,  pfnNodeReset, (PHDACODEC pThis, uint8_t nID, PCODECNODE pNode));
     892    DECLCALLBACKMEMBER(int,  pfnLookup, (PHDACODEC pThis, PHDACODECR0 pThisCC, uint32_t uVerb, uint64_t *puResp));
     893    /** @} */
     894
     895#ifdef VBOX_WITH_STATISTICS
     896    STAMCOUNTER StatLookupsR0;
     897#endif
     898
     899} HDACODECR0;
     900
     901int hdaR0CodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, PHDACODECR0 pThisCC);
     902
     903/**
     904 * HDA codec state (ring-3).
     905 */
     906typedef struct HDACODECR3
     907{
     908    CODECVERBR3             aVerbs[CODEC_VERBS_MAX];
     909    size_t                  cVerbs;
     910
     911    /** @name Public codec functions.
     912     *  @{  */
     913    DECLCALLBACKMEMBER(int,  pfnLookup, (PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t uVerb, uint64_t *puResp));
     914    DECLCALLBACKMEMBER(void, pfnDbgListNodes, (PHDACODEC pThis, PHDACODECR3 pThisCC, PCDBGFINFOHLP pHlp, const char *pszArgs));
     915    DECLCALLBACKMEMBER(void, pfnDbgSelector, (PHDACODEC pThis, PHDACODECR3 pThisCC, PCDBGFINFOHLP pHlp, const char *pszArgs));
    109916    /** @} */
    110917
     
    160967
    161968#ifdef VBOX_WITH_STATISTICS
    162     STAMCOUNTER             StatLookups;
     969    STAMCOUNTER StatLookupsR0;
     970    STAMCOUNTER StatLookupsR3;
    163971#endif
    164 } HDACODEC;
    165 
    166 int hdaCodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, uint16_t uLUN, PCFGMNODE pCfg);
     972
     973} HDACODECR3;
     974
     975int hdaR3CodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, PHDACODECR3 pThisCC, uint16_t uLUN, PCFGMNODE pCfg);
     976void hdaR3CodecPowerOff(PHDACODECR3 pThisCC);
     977int hdaR3CodecLoadState(PPDMDEVINS pDevIns, PHDACODEC pThis, PHDACODECR3 pThisCC, PSSMHANDLE pSSM, uint32_t uVersion);
     978int hdaR3CodecAddStream(PHDACODECR3 pThisCC, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg);
     979int hdaR3CodecRemoveStream(PHDACODECR3 pThisCC, PDMAUDIOMIXERCTL enmMixerCtl);
     980
     981int hdaCodecSaveState(PPDMDEVINS pDevIns, PHDACODEC pThis, PSSMHANDLE pSSM);
    167982void hdaCodecDestruct(PHDACODEC pThis);
    168 void hdaCodecPowerOff(PHDACODEC pThis);
    169 int hdaCodecSaveState(PPDMDEVINS pDevIns, PHDACODEC pThis, PSSMHANDLE pSSM);
    170 int hdaCodecLoadState(PPDMDEVINS pDevIns, PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion);
    171 int hdaCodecAddStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg);
    172 int hdaCodecRemoveStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl);
     983void hdaCodecReset(PHDACODEC pThis);
    173984
    174985/** @name DevHDA saved state versions
Note: See TracChangeset for help on using the changeset viewer.

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