//------------------------------------------------------------------------------ // // Function: ReadGeneralPurposeLines // // Reads the general purpose lines // DWORD ReadGeneralPurposeLines( Device_t *pDevice, UINT16 channels, DWORD *prgResults, DWORD count ) { DEBUGMSG(ZONE_FUNCTION, ( L"ADC: +ReadGeneralPurposeLines(0x%08x, 0x%08x, 0x%08x, 0x%08x)\r\n", pDevice, channels, prgResults, count )); UINT8 val; UINT8 counter; UINT16 rgGPRegisters[16]; UINT16 *pGPRegisters = rgGPRegisters; DWORD dwReadCount = 0; // waits for conversion complete val = 0; counter = 0; while (counter++ < 0xFF) { TWLReadRegs(pDevice->hTWL, TWL_CTRL_SW1, &val, 1); if (val & TWL_MADC_CTRL_SW_EOC_SW1) { break; } StallExecution(10); } // read to results of the general purpose lines if (TWLReadRegs(pDevice->hTWL, TWL_GPCH0_LSB, rgGPRegisters, sizeof(rgGPRegisters)) == FALSE) { DEBUGMSG(ZONE_ERROR, (L"ADC: !ERROR - ReadGeneralPurposeLines: " L"Failed writing start conversion\r\n" )); goto cleanUp; } // copy raw results into return buffer counter = 0; while (counter < count && channels) { if (channels & 1) { // read raw value *prgResults = *pGPRegisters >> 6; // move to next result and increment counter ++prgResults; ++counter; } pGPRegisters++; channels >>= 1; }
BOOL CPCIDisk::EndDMA( ) { BYTE bStatus = ReadBMStatus(); if ((bStatus & BM_STATUS_INTR) && (bStatus & BM_STATUS_ACTIVE)) { DEBUGMSG(ZONE_DMA, (_T( "Atapi!CPCIDisk::EndDMA> Status: active; status(0x%x)\r\n" ), bStatus)); } else if ((bStatus & BM_STATUS_INTR) && !(bStatus & BM_STATUS_ACTIVE)) { DEBUGMSG(ZONE_DMA, (_T( "Atapi!CPCIDisk::EndDMA> Status: inactive; status(0x%x)\r\n" ), bStatus)); } else if (!(bStatus & BM_STATUS_INTR)&& (bStatus & BM_STATUS_ACTIVE)) { DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T( "Atapi!CPCIDisk::EndDMA> Interrupt delayed; status(0x%x)\r\n" ), bStatus)); BOOL bCount = 0; while (TRUE) { StallExecution(100); bCount++; bStatus = ReadBMStatus(); if ((bStatus & BM_STATUS_INTR) && !(bStatus & BM_STATUS_ACTIVE)) { DEBUGMSG(ZONE_DMA, (_T( "Atapi!CPCIDisk::EndDMA> DMA complete after delay; status(0x%x)\r\n" ), bStatus)); break; } else { DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T( "Atapi!CPCIDisk::EndDMA> Interrupt still delayed; status(0x%x)\r\n" ), bStatus)); if (bCount > 10) { WriteBMCommand(0); return FALSE; } } } } else { if (bStatus & BM_STATUS_ERROR) { DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T( "Atapi!CPCIDisk::EndDMA> Error; (0x%x)\r\n" ), bStatus)); DEBUGCHK(0); return FALSE; } } WriteBMCommand(0); return TRUE; }
void CES1371::InitCodec() { USHORT usCodecRead; UCHAR i; // write the Codec reset WriteCodecRegister( AC97_RESET, 0xffff ); // read all the registers so we sync the states for ( i = AC97_RESET; i <= AC97_POWER_CONTROL; i += 2) usCodecRead = ReadCodecRegister( i ); // get the Vendor ID and revision m_ulCodecVendorID = ULONG(ReadCodecRegister( AC97_VENDOR_ID1 )) << 16; usCodecRead = ReadCodecRegister( AC97_VENDOR_ID2 ); m_ulCodecVendorID |= ULONG(usCodecRead) & 0x0000ff00; m_ulCodecRevision = ULONG(usCodecRead) & 0x000000ff; DEBUGMSG(ZONE_ERROR, (TEXT("ES1371 Codec Vendor ID: %08x '%c%c%c'\n"), m_ulCodecVendorID, (m_ulCodecVendorID >> 24) & 0xFF, (m_ulCodecVendorID >> 16) & 0xFF, (m_ulCodecVendorID >> 8) & 0xFF )); DEBUGMSG(ZONE_ERROR, (TEXT("ES1371 Codec Revision: %02x\n"), m_ulCodecRevision)); if ( !( m_ulCodecVendorID == AC97_VENDOR_CRYSTAL && m_ulCodecRevision == 0x13)) { // now power down the Analog section of the AC97 // and power it back up. This forces the Crystal // AC97 to recalibrate its analog levels. Codec_SetPowerState( AC97_PWR_ANLOFF ); //<mod:ce> KeStallExecutionProcessor (100); StallExecution(1000); // some older codecs require longer stall times Codec_SetPowerState( AC97_PWR_D0 ); } // write master volume WriteCodecRegister( AC97_MASTER_VOL_STEREO, ES1371_INITIALVOLUME ); // write the wave out volume WriteCodecRegister( AC97_PCMOUT_VOL, 0x0606 ); // write the stereo analog lines volume WriteCodecRegister( AC97_LINEIN_VOL, 0x0808 ); WriteCodecRegister( AC97_CD_VOL, 0x0808 ); WriteCodecRegister( AC97_VIDEO_VOL, 0x0808 ); WriteCodecRegister( AC97_AUX_VOL, 0x0808 ); WriteCodecRegister( AC97_LINEIN_VOL, 0x0808 ); // write the TAD volume WriteCodecRegister( AC97_PHONE_VOL, 0x0008 ); // write the pc beep volume WriteCodecRegister( AC97_PCBEEP_VOL, 0x8000 ); // turn on the mic boost but leave it muted WriteCodecRegister( AC97_MIC_VOL, 0x8048 ); // set up the record mux for mic input WriteCodecRegister( AC97_RECORD_SELECT, AC97_RECMUX_MIC ); // set up a default record gain WriteCodecRegister( AC97_RECORD_GAIN, ES1371_INITIALVOLUME ); // set the mono output to mic instead of the default mix WriteCodecRegister( AC97_GENERAL_PURPOSE, AC97_GP_MIX ); // and unmute it WriteCodecRegister( AC97_MASTER_VOL_MONO, 0x0000 ); }
//-------------------------------------------------------------------------- // // Codec_SetPowerState // Description: // The AC97 Codec has 4 power states (that are meaningful to us): // 0x0000 - normal operation // 0x1700 - fully powered down // AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR4 // 0x1300 - powered down with analog mixer active // AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4 // 0x0800 - turn off analog mixer section // AC97_PWR_PR3 // // This procedure will transition the Codec from its current // state to the specified one. // // Input: // ulNewState - the new AC97 power state // //-------------------------------------------------------------------------- ULONG CES1371::Codec_SetPowerState( ULONG ulNewState ) { USHORT usAC97_PowerReg; ULONG delay_count; // if the AC97 is asleep wake it up. since we only leave it asleep // or fully awake if it isn't awake it must be asleep if ( m_ulCodecPowerState ) { UCHAR ucMiscCtl; // wake up the AC97 using the warm reset method // from 5.2.1.2 AC97 spec a warm reset is signaled by // driving SYNC high for a minimum of one microsecond // in the absence of bit clock. Do this using the // SYNC_RES bit in byte 1 of the es1371 chip. if ( AC97_PWR_PR4 & m_ulCodecPowerState ) { ucMiscCtl = READ_PORT_UCHAR((PUCHAR)(m_pPciAddr + ES1371_bMISCCTL_OFF)); WRITE_PORT_UCHAR((PUCHAR)(m_pPciAddr + ES1371_bMISCCTL_OFF), ucMiscCtl | ES1371_MISCCTL_SYNC_RES ); // now wait around long enough to be sure 1.3 microseconds have gone by //<mod:ce> KeStallExecutionProcessor( 2 ); StallExecution(1000); // some older codecs require longer stall times WRITE_PORT_UCHAR((PUCHAR)(m_pPciAddr + ES1371_bMISCCTL_OFF), ucMiscCtl & ~ES1371_MISCCTL_SYNC_RES ); // now wait around long enough to be sure a microsecond has gone by //<mod:ce> KeStallExecutionProcessor( 1 ); StallExecution(1000); // some older codecs require longer stall times } // now the ACLink should be active. take the Codec through the steps // to bring it back up to fully awake. // read the power register to see what the current state is usAC97_PowerReg = ReadCodecRegister( AC97_POWER_CONTROL ); #ifdef DBG _DbgPrintF( DEBUGLVL_VERBOSE, ("AC97 power state 1: %x", usAC97_PowerReg)); #endif // is the analog section awake if ( !(AC97_PWR_ANL & usAC97_PowerReg ) ) WriteCodecRegister( AC97_POWER_CONTROL, usAC97_PowerReg & ~(AC97_PWR_PR2|AC97_PWR_PR3) ); Codec_WaitForPowerState( AC97_PWR_ANL ); // read the power register to see what the current state is usAC97_PowerReg = ReadCodecRegister( AC97_POWER_CONTROL ); #ifdef DBG _DbgPrintF( DEBUGLVL_VERBOSE, ("AC97 power state 2: %x", usAC97_PowerReg)); #endif // is the DAC section awake if ( !(AC97_PWR_DAC & usAC97_PowerReg ) ) WriteCodecRegister( AC97_POWER_CONTROL, usAC97_PowerReg & ~AC97_PWR_PR1 ); Codec_WaitForPowerState( AC97_PWR_DAC ); // read the power register to see what the current state is usAC97_PowerReg = ReadCodecRegister( AC97_POWER_CONTROL ); #ifdef DBG _DbgPrintF( DEBUGLVL_VERBOSE, ("AC97 power state 3: %x", usAC97_PowerReg)); #endif // is the ADC section awake if ( !(AC97_PWR_ADC & usAC97_PowerReg ) ) WriteCodecRegister( AC97_POWER_CONTROL, usAC97_PowerReg & ~AC97_PWR_PR0 ); Codec_WaitForPowerState( AC97_PWR_ADC ); // read the power register to see what the current state is usAC97_PowerReg = ReadCodecRegister( AC97_POWER_CONTROL ); #ifdef DBG _DbgPrintF( DEBUGLVL_VERBOSE, ("AC97 power state 3: %x", usAC97_PowerReg)); #endif } // now the AC97 Codec if fully awake. if it should be in a power down // mode do that now. if ( ulNewState ) { // start the process of shutting down the Codec usAC97_PowerReg = 0; // shut down the ADC section if ( AC97_PWR_PR0 & ulNewState ) { usAC97_PowerReg |= AC97_PWR_PR0; WriteCodecRegister( AC97_POWER_CONTROL, usAC97_PowerReg ); } // shut down the DAC section if ( AC97_PWR_PR1 & ulNewState ) { usAC97_PowerReg |= AC97_PWR_PR1; WriteCodecRegister( AC97_POWER_CONTROL, usAC97_PowerReg ); } // if it is called for shut off the analog section if ( AC97_PWR_PR2 & ulNewState ) { usAC97_PowerReg |= AC97_PWR_PR2; WriteCodecRegister( AC97_POWER_CONTROL, usAC97_PowerReg ); } // if it is called for shut off the analog section if ( AC97_PWR_PR3 & ulNewState ) { usAC97_PowerReg |= AC97_PWR_PR3; WriteCodecRegister( AC97_POWER_CONTROL, usAC97_PowerReg ); } if ( AC97_PWR_PR4 & ulNewState ) { // shut down the digital interface section usAC97_PowerReg |= AC97_PWR_PR4; WriteCodecRegister( AC97_POWER_CONTROL, usAC97_PowerReg ); } // poll the WIP bit of the Codec control register to make sure // it is clear before we power anything else down. for( delay_count = 0; delay_count < 0x1000UL; ++delay_count ) if( !(READ_PORT_ULONG((PULONG)(m_pPciAddr + ES1371_dCODECCTL_OFF)) & (1UL << 30)) ) break; // the AC97 Codec is now powered down } // save the new AC97 Codec power state m_ulCodecPowerState = ulNewState; return ulNewState; }