VirtualBox

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


Ignore:
Timestamp:
Aug 18, 2010 1:06:15 PM (14 years ago)
Author:
vboxsync
Message:

Audio/HDA: Input streams support.

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

Legend:

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

    r31605 r31760  
    123123
    124124static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode);
    125 static int codecToAudVolume(struct CODECState *pState);
     125static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt);
    126126
    127127static inline void codecSetRegister(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset, uint32_t mask)
     
    249249        }
    250250        if (CODEC_NID(cmd) == 2)
    251             codecToAudVolume(pState);
     251            codecToAudVolume(pAmplifier, AUD_MIXER_VOLUME);
     252        if (CODEC_NID(cmd) == 0x17) /* Microphone */
     253            codecToAudVolume(pAmplifier, AUD_MIXER_PCM);
    252254    }
    253255    return VINF_SUCCESS;
     
    10101012            pNode->node.au32F00_param[0xC] = RT_BIT(5)|RT_BIT(2);
    10111013            pNode->port.u32F07_param = RT_BIT(5);
    1012             pNode->port.u32F09_param = 0;
     1014            pNode->port.u32F09_param = RT_BIT(31);
    10131015            if (!pState->fInReset)
    1014                 pNode->port.u32F1c_param = RT_MAKE_U32_FROM_U8(0x51, 0x30, 0x81, 0x01);
     1016                pNode->port.u32F1c_param = (0x2 << 30) /* built-in */ | (0xA << 20) /* mic. */
     1017                    | (0x1 << 16) | (0x30 << 8) | 0x51;
    10151018            break;
    10161019        case 0xF:
     
    11111114}
    11121115
    1113 static int codecToAudVolume(struct CODECState *pState)
    1114 {
    1115     PCODECNODE pNode = &pState->pNodes[2];
    1116     int mute = AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) & RT_BIT(7);
    1117     mute |= AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_RIGHT, 0) & RT_BIT(7);
     1116static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt)
     1117{
     1118    uint32_t dir = AMPLIFIER_OUT;
     1119    switch (mt)
     1120    {
     1121        case AUD_MIXER_VOLUME:
     1122            dir = AMPLIFIER_OUT;
     1123            break;
     1124        case AUD_MIXER_PCM:
     1125        case AUD_MIXER_LINE_IN:
     1126            dir = AMPLIFIER_IN;
     1127            break;
     1128    }
     1129    int mute = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & RT_BIT(7);
     1130    mute |= AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & RT_BIT(7);
    11181131    mute >>=7;
    11191132    mute &= 0x1;
    1120     uint8_t lVol = AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) & 0x7f;
    1121     uint8_t rVol = AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_RIGHT, 0) & 0x7f;
    1122     AUD_set_volume(AUD_MIXER_VOLUME, &mute, &lVol, &rVol);
     1133    uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & 0x7f;
     1134    uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & 0x7f;
     1135    AUD_set_volume(mt, &mute, &lVol, &rVol);
    11231136    return VINF_SUCCESS;
    11241137}
     
    12491262    if (!pState->voice_po)
    12501263        LogRel (("HDAcodec: WARNING: Unable to open PCM OUT!\n"));
    1251     codecToAudVolume(pState);
     1264    codecToAudVolume(&pState->pNodes[2].dac.B_params, AUD_MIXER_VOLUME);
     1265    codecToAudVolume(&pState->pNodes[0x17].adcvol.B_params, AUD_MIXER_PCM);
    12521266    return VINF_SUCCESS;
    12531267}
  • trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp

    r31741 r31760  
    337337/* Predicates */
    338338
     339typedef struct HDABDLEDESC
     340{
     341    uint64_t    u64BdleCviAddr;
     342    uint32_t    u32BdleMaxCvi;
     343    uint32_t    u32BdleCvi;
     344    uint32_t    u32BdleCviLen;
     345    uint32_t    u32BdleCviPos;
     346    bool        fBdleCviIoc;
     347} HDABDLEDESC, *PHDABDLEDESC;
    339348
    340349typedef struct INTELHDLinkState
     
    350359    RTGCPHYS    addrMMReg;
    351360    uint32_t     au32Regs[113];
    352     /* Current BD index  */
    353     uint32_t    u32Cvi;
    354     uint64_t    u64CviAddr;
    355     /* Length of current BD entry */
    356     uint32_t    u32CviLen;
    357     uint32_t    u32CviPos;
    358     uint32_t    u32Cbp;
     361    HDABDLEDESC  stInBdle;
     362    HDABDLEDESC  stOutBdle;
     363    HDABDLEDESC  stMicBdle;
    359364    /* Interrupt on completition */
    360365    bool        fCviIoc;
     
    423428DECLCALLBACK(int)hdaRegWriteU8(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t pu32Value);
    424429static int hdaLookup(INTELHDLinkState* pState, uint32_t u32Offset);
    425 static void fetch_bd(INTELHDLinkState *pState);
     430static void fetch_bd(INTELHDLinkState *pState, PHDABDLEDESC pBdle, uint64_t u64BaseDMA);
    426431
    427432/* see 302349 p 6.2*/
     
    574579static int hdaProcessInterrupt(INTELHDLinkState* pState)
    575580{
     581#define IS_INTERRUPT_OCCURED_AND_ENABLED(pState, num)                       \
     582        (   INTCTL_SX((pState), num)                                        \
     583         && (SDSTS(pState, num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS)))
    576584    bool fIrq = false;
    577585    if(   INTCTL_CIE(pState)
     
    582590        fIrq = true;
    583591    }
    584     if (   INTCTL_SX(pState, 4)
    585         && SDSTS(pState, 4) && HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))
     592    if (   IS_INTERRUPT_OCCURED_AND_ENABLED(pState, 0)
     593        || IS_INTERRUPT_OCCURED_AND_ENABLED(pState, 4))
    586594    {
    587595        fIrq = true;
     
    967975    {
    968976        Log(("hda: DMA(%x) switched on\n", offset));
    969         AUD_set_active_in(pState->Codec.voice_pi, 1);
    970         AUD_set_active_in(pState->Codec.voice_mc, 1);
     977        if (offset == 0x80)
     978        {
     979            AUD_set_active_in(pState->Codec.voice_pi, 1);
     980            //AUD_set_active_in(pState->Codec.voice_mc, 1);
     981        }
    971982        if (offset == 0x100)
    972983        {
    973             fetch_bd(pState);
    974             AUD_set_active_out(pState->Codec.voice_po, 1);
     984            uint64_t u64BaseDMA = SDBDPL(pState, 4);
     985            u64BaseDMA |= (((uint64_t)SDBDPU(pState, 4)) << 32);
     986            if (u64BaseDMA)
     987            {
     988                //fetch_bd(pState, u64BaseDMA);
     989                AUD_set_active_out(pState->Codec.voice_po, 1);
     990            }
    975991            //SDSTS(pState, 4) |= (1<<5);
    976992        }
     
    979995    {
    980996        Log(("hda: DMA(%x) switched off\n", offset));
    981         AUD_set_active_in(pState->Codec.voice_pi, 0);
    982         AUD_set_active_in(pState->Codec.voice_mc, 0);
     997        if (offset == 0x80)
     998        {
     999            AUD_set_active_in(pState->Codec.voice_pi, 0);
     1000            //AUD_set_active_in(pState->Codec.voice_mc, 0);
     1001        }
    9831002        if (offset == 0x100)
    9841003        {
     
    11221141}
    11231142
    1124 static void dump_bd(INTELHDLinkState *pState)
     1143static void dump_bd(INTELHDLinkState *pState, PHDABDLEDESC pBdle, uint64_t u64BaseDMA)
    11251144{
    11261145    uint64_t addr;
     
    11311150    uint32_t i;
    11321151    uint32_t sum = 0;
    1133     for (i = 0; i <= SDLVI(pState, 4); ++i)
    1134     {
    1135         PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), SDBDPL(pState, 4) + i*16, bdle, 16);
     1152    Assert(pBdle && pBdle->u32BdleMaxCvi);
     1153    for (i = 0; i <= pBdle->u32BdleMaxCvi; ++i)
     1154    {
     1155        PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), u64BaseDMA + i*16, bdle, 16);
    11361156        addr = *(uint64_t *)bdle;
    11371157        len = *(uint32_t *)&bdle[8];
    11381158        ioc = *(uint32_t *)&bdle[12];
    1139         Log(("hda: %s bdle[%d] a:%x, len:%x, ios:%d\n",  (i == pState->u32Cvi? "[C]": "   "), i, addr, len, ioc));
     1159        Log(("hda: %s bdle[%d] a:%x, len:%x, ios:%d\n",  (i == pBdle->u32BdleCvi? "[C]": "   "), i, addr, len, ioc));
    11401160        sum += len;
    11411161    }
     
    11441164    {
    11451165        PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pState->u64DPBase + i*8, &counter, 4);
    1146         Log(("hda: %s stream[%d] counter=%x\n", (i) == SDCTL_NUM(pState, 4)? "[C]": "   ", i , counter));
    1147     }
    1148 }
    1149 static void fetch_bd(INTELHDLinkState *pState)
    1150 {
    1151     dump_bd(pState);
     1166        Log(("hda: %s stream[%d] counter=%x\n", i == SDCTL_NUM(pState, 4) || i == SDCTL_NUM(pState, 0)? "[C]": "   ",
     1167             i , counter));
     1168    }
     1169}
     1170static void fetch_bd(INTELHDLinkState *pState, PHDABDLEDESC pBdle, uint64_t u64BaseDMA)
     1171{
    11521172    uint8_t  bdle[16];
    1153     PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), SDBDPL(pState, 4) + pState->u32Cvi*16, bdle, 16);
    1154     pState->u64CviAddr = *(uint64_t *)bdle;
    1155     pState->u32CviLen = *(uint32_t *)&bdle[8];
    1156     pState->fCviIoc = (*(uint32_t *)&bdle[12]) & 0x1;
    1157 }
    1158 
     1173    Assert((u64BaseDMA && pBdle && pBdle->u32BdleMaxCvi));
     1174    PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), u64BaseDMA + pBdle->u32BdleCvi*16, bdle, 16);
     1175    pBdle->u64BdleCviAddr = *(uint64_t *)bdle;
     1176    pBdle->u32BdleCviLen = *(uint32_t *)&bdle[8];
     1177    pBdle->fBdleCviIoc = (*(uint32_t *)&bdle[12]) & 0x1;
     1178    dump_bd(pState, pBdle, u64BaseDMA);
     1179}
     1180
     1181static uint32_t read_audio(INTELHDLinkState *pState, int avail, bool *fStop)
     1182{
     1183    uint8_t tmpbuf[4096];
     1184    uint32_t temp;
     1185    uint32_t u32Rest = 0;
     1186    uint32_t cbRead = 0;
     1187    uint32_t to_copy = 0;
     1188    /* todo: add input line detection */
     1189    PHDABDLEDESC pBdle = &pState->stInBdle;
     1190    SWVoiceIn *voice = pState->Codec.voice_pi;
     1191    u32Rest = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos;
     1192    temp = audio_MIN(u32Rest, (uint32_t)avail);
     1193    if (!temp)
     1194    {
     1195        *fStop = true;
     1196        return cbRead;
     1197    }
     1198    while (temp)
     1199    {
     1200        int copied;
     1201        to_copy = audio_MIN(temp, 4096U);
     1202        copied = AUD_read (voice, tmpbuf, to_copy);
     1203        Log (("hda: read_audio max=%x to_copy=%x copied=%x\n",
     1204              avail, to_copy, copied));
     1205        if (!copied)
     1206        {
     1207            *fStop = true;
     1208            break;
     1209        }
     1210        PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, tmpbuf, copied);
     1211        temp    -= copied;
     1212        cbRead += copied;
     1213        pBdle->u32BdleCviPos += copied;
     1214    }
     1215    return cbRead;
     1216}
    11591217static uint32_t write_audio(INTELHDLinkState *pState, int avail, bool *fStop)
    11601218{
     
    11641222    uint32_t written = 0;
    11651223    int to_copy = 0;
    1166     u32Rest = pState->u32CviLen - pState->u32CviPos;
     1224    PHDABDLEDESC pBdle = &pState->stOutBdle;
     1225    u32Rest = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos;
    11671226    temp = audio_MIN(u32Rest, (uint32_t)avail);
    11681227    if (!temp)
     
    11751234        int copied;
    11761235        to_copy = audio_MIN(temp, 4096U);
    1177         PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pState->u64CviAddr + pState->u32CviPos, tmpbuf, to_copy);
     1236        PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, tmpbuf, to_copy);
    11781237        copied = AUD_write (pState->Codec.voice_po, tmpbuf, to_copy);
    11791238        Log (("hda: write_audio max=%x to_copy=%x copied=%x\n",
     
    11871246        temp    -= copied;
    11881247        written += copied;
    1189         pState->u32CviPos += copied;
     1248        pBdle->u32BdleCviPos += copied;
    11901249    }
    11911250    return written;
     
    12011260{
    12021261    bool fStop = false;
     1262    uint64_t u64BaseDMA = 0;
     1263    PHDABDLEDESC pBdle = NULL;
    12031264    INTELHDLinkState *pState = (INTELHDLinkState *)pCodecState->pHDAState;
    1204     switch(src)
     1265    uint32_t u32Counter;
     1266    uint32_t nBytes;
     1267    uint32_t u32Ctl;
     1268    uint32_t *pu32Sts;
     1269    uint8_t  u8Strm;
     1270    uint32_t *pu32Lpib;
     1271    uint32_t u32Lcbl;
     1272    switch (src)
    12051273    {
    12061274        case PO_INDEX:
    12071275        {
    1208             uint32_t written;
    1209             uint32_t u32Counter;
    1210             if (   !(SDCTL(pState, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN))
    1211                 || avail == 0)
    1212                 return;
    1213             SDCTL(pState, 4) |= ((pState->Codec.pNodes[2].dac.u32F06_param & (0xf << 4)) >> 4) << 20;
    1214             //fetch_bd(pState);
    1215             while(   avail
    1216                   && !fStop)
     1276            u8Strm = 4;
     1277            u32Ctl = SDCTL(pState, 4);
     1278            u64BaseDMA = SDBDPL(pState, 4);
     1279            u64BaseDMA |= (((uint64_t)SDBDPU(pState, 4)) << 32);
     1280            pu32Lpib = &SDLPIB(pState, 4);
     1281            pu32Sts = &SDSTS(pState, 4);
     1282            u32Lcbl = SDLCBL(pState, 4);
     1283            pBdle = &pState->stOutBdle;
     1284            pBdle->u32BdleMaxCvi = SDLVI(pState, 4);
     1285            break;
     1286        }
     1287        case PI_INDEX:
     1288        {
     1289            u8Strm = 0;
     1290            u32Ctl = SDCTL(pState, 0);
     1291            pu32Lpib = &SDLPIB(pState, 0);
     1292            pu32Sts = &SDSTS(pState, 0);
     1293            u32Lcbl = SDLCBL(pState, 0);
     1294            u64BaseDMA = SDBDPL(pState, 0);
     1295            u64BaseDMA |= (((uint64_t)SDBDPU(pState, 0)) << 32);
     1296            pBdle = &pState->stInBdle;
     1297            pBdle->u32BdleMaxCvi = SDLVI(pState, 0);
     1298            break;
     1299        }
     1300        default:
     1301            return;
     1302    }
     1303    if (   !(u32Ctl & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN))
     1304        || !avail
     1305        || !u64BaseDMA)
     1306        return;
     1307    fetch_bd(pState, pBdle, u64BaseDMA);
     1308    while(   avail
     1309          && !fStop)
     1310    {
     1311        PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), (pState->u64DPBase & ~0x1) + u8Strm*8, &u32Counter, 4);
     1312        switch (src)
     1313        {
     1314            case PO_INDEX:
     1315                nBytes = write_audio(pState, avail, &fStop);
     1316                break;
     1317            case PI_INDEX:
     1318                nBytes = read_audio(pState, avail, &fStop);
     1319                break;
     1320            default:
     1321                AssertMsgFailed(("Unsupported"));
     1322        }
     1323        if (   fStop
     1324            && pBdle->u32BdleCviLen != pBdle->u32BdleCviPos)
     1325            break;
     1326        *pu32Lpib += nBytes;
     1327        avail -= nBytes;
     1328        u32Counter += nBytes;
     1329        PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), (pState->u64DPBase & ~0x1) + u8Strm*8, &u32Counter, 4);
     1330        if (   pBdle->u32BdleCviPos == pBdle->u32BdleCviLen
     1331            || *pu32Lpib == u32Lcbl)
     1332        {
     1333            if (   u32Ctl & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE)
     1334                && (   (   pBdle->u32BdleCviPos == pBdle->u32BdleCviLen
     1335                        && pBdle->fBdleCviIoc )
     1336                    || *pu32Lpib == u32Lcbl))
    12171337            {
    1218                 PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), (pState->u64DPBase & ~0x1) + 4*8, &u32Counter, 4);
    1219                 written = write_audio(pState, avail, &fStop);
    1220                 if (   fStop
    1221                     && pState->u32CviLen != pState->u32CviPos)
    1222                     break;
    1223                 SDLPIB(pState, 4) += written; /* bytes ? */
    1224                 avail -= written;
    1225                 u32Counter += written;
    1226                 PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), (pState->u64DPBase & ~0x1) + 4*8, &u32Counter, 4);
    1227                 if (   pState->u32CviPos == pState->u32CviLen
    1228                     || SDLPIB(pState, 4) == SDLCBL(pState, 4))
     1338                *pu32Sts |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS);
     1339                hdaProcessInterrupt(pState);
     1340                if (*pu32Lpib == u32Lcbl)
    12291341                {
    1230                     if (   SDCTL(pState, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE)
    1231                         && (   (   pState->u32CviPos == pState->u32CviLen
    1232                                 && pState->fCviIoc )
    1233                             || SDLPIB(pState, 4) == SDLCBL(pState, 4)))
    1234                     {
    1235                         SDSTS(pState,4) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS);
    1236                         hdaProcessInterrupt(pState);
    1237                         if (SDLPIB(pState, 4) == SDLCBL(pState, 4))
    1238                         {
    1239                             SDLPIB(pState, 4) = 0;
    1240                             u32Counter = 0;
    1241                             PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), (pState->u64DPBase & ~0x1)  + 4*8, &u32Counter, 4);
    1242                         }
    1243                     }
    1244                     if (pState->u32CviPos == pState->u32CviLen)
    1245                     {
    1246                         pState->u32CviPos = 0;
    1247                         pState->u32Cvi++;
    1248                         if (pState->u32Cvi == SDLVI(pState, 4) + 1)
    1249                             pState->u32Cvi = 0;
    1250                     }
    1251                     fStop = false;
    1252                     fetch_bd(pState);
     1342                    *pu32Lpib = 0;
     1343                    u32Counter = 0;
     1344                    PDMDevHlpPhysWrite(ICH6_HDASTATE_2_DEVINS(pState), (pState->u64DPBase & ~0x1)  + u8Strm*8, &u32Counter, 4);
    12531345                }
    12541346            }
     1347            if (pBdle->u32BdleCviPos == pBdle->u32BdleCviLen)
     1348            {
     1349                pBdle->u32BdleCviPos = 0;
     1350                pBdle->u32BdleCvi++;
     1351                if (pBdle->u32BdleCvi == pBdle->u32BdleMaxCvi + 1)
     1352                    pBdle->u32BdleCvi = 0;
     1353            }
     1354            fStop = false;
     1355            fetch_bd(pState, pBdle, u64BaseDMA);
    12551356        }
    1256         break;
    1257         AssertMsgFailed(("Unexpected index: %x\n", src));
    1258         default:
    1259             break;
    12601357    }
    12611358}
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