Example #1
0
//------------------------------------------------------------------------------
//
//  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;
        }
Example #2
0
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;
}
Example #3
0
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 );
}
Example #4
0
//--------------------------------------------------------------------------
//
//  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;
}