Changeset 31760 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Aug 18, 2010 1:06:15 PM (14 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevCodec.cpp
r31605 r31760 123 123 124 124 static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode); 125 static int codecToAudVolume( struct CODECState *pState);125 static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt); 126 126 127 127 static inline void codecSetRegister(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset, uint32_t mask) … … 249 249 } 250 250 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); 252 254 } 253 255 return VINF_SUCCESS; … … 1010 1012 pNode->node.au32F00_param[0xC] = RT_BIT(5)|RT_BIT(2); 1011 1013 pNode->port.u32F07_param = RT_BIT(5); 1012 pNode->port.u32F09_param = 0;1014 pNode->port.u32F09_param = RT_BIT(31); 1013 1015 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; 1015 1018 break; 1016 1019 case 0xF: … … 1111 1114 } 1112 1115 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); 1116 static 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); 1118 1131 mute >>=7; 1119 1132 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); 1123 1136 return VINF_SUCCESS; 1124 1137 } … … 1249 1262 if (!pState->voice_po) 1250 1263 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); 1252 1266 return VINF_SUCCESS; 1253 1267 } -
trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
r31741 r31760 337 337 /* Predicates */ 338 338 339 typedef 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; 339 348 340 349 typedef struct INTELHDLinkState … … 350 359 RTGCPHYS addrMMReg; 351 360 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; 359 364 /* Interrupt on completition */ 360 365 bool fCviIoc; … … 423 428 DECLCALLBACK(int)hdaRegWriteU8(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t pu32Value); 424 429 static int hdaLookup(INTELHDLinkState* pState, uint32_t u32Offset); 425 static void fetch_bd(INTELHDLinkState *pState );430 static void fetch_bd(INTELHDLinkState *pState, PHDABDLEDESC pBdle, uint64_t u64BaseDMA); 426 431 427 432 /* see 302349 p 6.2*/ … … 574 579 static int hdaProcessInterrupt(INTELHDLinkState* pState) 575 580 { 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))) 576 584 bool fIrq = false; 577 585 if( INTCTL_CIE(pState) … … 582 590 fIrq = true; 583 591 } 584 if ( I NTCTL_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)) 586 594 { 587 595 fIrq = true; … … 967 975 { 968 976 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 } 971 982 if (offset == 0x100) 972 983 { 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 } 975 991 //SDSTS(pState, 4) |= (1<<5); 976 992 } … … 979 995 { 980 996 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 } 983 1002 if (offset == 0x100) 984 1003 { … … 1122 1141 } 1123 1142 1124 static void dump_bd(INTELHDLinkState *pState )1143 static void dump_bd(INTELHDLinkState *pState, PHDABDLEDESC pBdle, uint64_t u64BaseDMA) 1125 1144 { 1126 1145 uint64_t addr; … … 1131 1150 uint32_t i; 1132 1151 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); 1136 1156 addr = *(uint64_t *)bdle; 1137 1157 len = *(uint32_t *)&bdle[8]; 1138 1158 ioc = *(uint32_t *)&bdle[12]; 1139 Log(("hda: %s bdle[%d] a:%x, len:%x, ios:%d\n", (i == p State->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)); 1140 1160 sum += len; 1141 1161 } … … 1144 1164 { 1145 1165 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 } 1170 static void fetch_bd(INTELHDLinkState *pState, PHDABDLEDESC pBdle, uint64_t u64BaseDMA) 1171 { 1152 1172 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 1181 static 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 } 1159 1217 static uint32_t write_audio(INTELHDLinkState *pState, int avail, bool *fStop) 1160 1218 { … … 1164 1222 uint32_t written = 0; 1165 1223 int to_copy = 0; 1166 u32Rest = pState->u32CviLen - pState->u32CviPos; 1224 PHDABDLEDESC pBdle = &pState->stOutBdle; 1225 u32Rest = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos; 1167 1226 temp = audio_MIN(u32Rest, (uint32_t)avail); 1168 1227 if (!temp) … … 1175 1234 int copied; 1176 1235 to_copy = audio_MIN(temp, 4096U); 1177 PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), p State->u64CviAddr + pState->u32CviPos, tmpbuf, to_copy);1236 PDMDevHlpPhysRead(ICH6_HDASTATE_2_DEVINS(pState), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, tmpbuf, to_copy); 1178 1237 copied = AUD_write (pState->Codec.voice_po, tmpbuf, to_copy); 1179 1238 Log (("hda: write_audio max=%x to_copy=%x copied=%x\n", … … 1187 1246 temp -= copied; 1188 1247 written += copied; 1189 p State->u32CviPos += copied;1248 pBdle->u32BdleCviPos += copied; 1190 1249 } 1191 1250 return written; … … 1201 1260 { 1202 1261 bool fStop = false; 1262 uint64_t u64BaseDMA = 0; 1263 PHDABDLEDESC pBdle = NULL; 1203 1264 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) 1205 1273 { 1206 1274 case PO_INDEX: 1207 1275 { 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)) 1217 1337 { 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) 1229 1341 { 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); 1253 1345 } 1254 1346 } 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); 1255 1356 } 1256 break;1257 AssertMsgFailed(("Unexpected index: %x\n", src));1258 default:1259 break;1260 1357 } 1261 1358 }
Note:
See TracChangeset
for help on using the changeset viewer.