⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcmsock.cpp

📁 Ep93XX TionProV2 BSP
💻 CPP
字号:
//**********************************************************************
//                                                                      
// Filename: pcmsock.cpp
//                                                                      
// Description: MAINSTONEII PCMCIA Socket Services Object for PCMCIA(16-bit)
//              Interface.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to 
// use this source code. For a copy of the EULA, please see the 
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved
//                                                                      
//**********************************************************************

#include <windows.h>
#include <types.h>
#include <socksv2.h>
#include <cardsv2.h>
#include <memory.h>
#include <ceddk.h>
#include <hwdefs.h>

#define  ZONE_SOCKET ZONE_PDD
#include "pdsocket.h"

//--------------------Pcmcia Socket Implementation--------------------------------------------

const SS_SOCKET_INFO CPcmciaCardSocket::ms_SocketInitInfo =
{
    SOCK_CAP_IO_MEMORY_CARD | SOCK_CAP_ONLY_SYSINTR,
    SOCK_CAP_PWRCYCLE | SOCK_CAP_ONLY_SYSINTR | 
    SOCK_CAP_CD |
    SOCK_CAP_BVD1 |
    SOCK_CAP_BVD2,    // Socket Interrupt Capability Set follow bitmap.
    SOCK_CAP_PWRCYCLE | 
    SOCK_CAP_CD |
    SOCK_CAP_BVD1 |
    SOCK_CAP_BVD2,    // Socket status report capability
    SOCK_CAP_PWRCYCLE | 
    SOCK_CAP_CD |
    SOCK_CAP_BVD1 |
    SOCK_CAP_BVD2,                // Socket status indicate capability
    0,                // Number of power entry this socket have.
    0,                // Number of Window supported in this Socket.
    Isa,              // PCCARD Bus Type is ISA/built-in.
    ( DWORD ) -1,     // CardBus Card Number.
    { - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
};




const SS_SOCKET_STATE CPcmciaCardSocket::ms_SocketInitState = 
{
    SOCK_EVENT_PWRCYCLE |
    SOCK_EVENT_CD |
    SOCK_EVENT_BVD1 |
    SOCK_EVENT_BVD2, // Initial EventMask
    0, // Event Changed.
    0, // Event Status
    CFG_IFACE_MEMORY,  //default interface type
    0,  // Interrupt Enable.
    0,  // Vcc
    0,  // Vpp1
    0   // Vpp2
};


void CPcmciaCardSocket::SocketEventHandle( DWORD dwStatesChange, DWORD dwStates )
{
    SS_SOCKET_STATE sSockState;

    Lock();
    CardGetSocket( &sSockState );

    sSockState.dwEventChanged |= dwStatesChange;
    sSockState.dwEventStatus  |= dwStates;
    sSockState.dwEventChanged &= ~( SOCK_EVENT_CD );
    m_SockState.dwEventChanged = sSockState.dwEventChanged;

    Unlock();

    m_pBridge->CallBackToCardService(m_pBridge->GetSocketNumber(), GetSocketHandle(), &sSockState);
}

CPcmciaCardSocket::CPcmciaCardSocket(CPcmciaBusBridge* pBridge, UINT16 nSlotNumber) 
					:CPCMCIASocketBase<CEp93xxMemoryWindow<CPcmciaCardSocket>
					,CEp93xxIOWindow<CPcmciaCardSocket>
					,CEp93xxWindowBridgeContainer<CPcmciaBusBridge>
					,CPcmciaBusBridge>( pBridge )
{
    DWORD dwPowerOption = 0;

    DEBUGMSG(ZONE_SOCKET, (TEXT("+CPcmciaCardSocket::CPcmciaCardSocket\r\n")));

    m_pBridge          = pBridge;
    m_SockState        = ms_SocketInitState;
    m_PcmciaSocketInfo = ms_SocketInitInfo;

    for( DWORD dwIndex = 0; dwIndex < IRQ_ROUTINGTABLE_SIZE; dwIndex++ )
    {
        m_PcmciaSocketInfo.bArrayIrqRouting[dwIndex] = (BYTE) pBridge->GetFunctionIrq();
    }

    m_PcmciaSocketInfo.dwNumOfPowerEntry = NUM_POWER_ENTRIES;
    m_PcmciaSocketInfo.dwNumOfWindows    = pBridge->GetMemWindowCount() + 
                                           pBridge->GetIoWindowCount();
    m_PcmciaSocketInfo.dwBusNumber       = 0;
    m_bResuming                          = FALSE;

/*    if(pBridge->GetRegPowerOption(&dwPowerOption))
    {
        m_SockState.dwInteruptStatus |= ((dwPowerOption & REG_POWER_KEEP_DRIVER) !=
                                          0 ?
                                          SOCK_INT_STATUS_CHG_WAKE :
                                          0 );
        m_SockState.dwInteruptStatus |= ((dwPowerOption & REG_POWER_KEEP_POWER) !=
                                          0 ?
                                          (SOCK_INT_STATUS_CHG_WAKE |
                                           SOCK_INT_FUNC_IRQ_WAKE) :
                                          0);
    }
	*/
    if((m_SockState.dwInteruptStatus & SOCK_INT_STATUS_CHG_WAKE) != 0)
    {
        m_pBridge->SetupWakeupSource((m_SockState.dwInteruptStatus & SOCK_INT_STATUS_CHG_WAKE) !=
                                      0 );
    }

    // Map device registers.
    // 
    if (!MapDeviceRegisters(pBridge))
    {
        RETAILMSG(TRUE, (TEXT("ERROR: CPcmciaCardSocket: MapDeviceRegisters failed.\r\n")));
        return;
    }

    // Get a unique socket index value to be used as the socket handle.
    m_dwSocketIndex = 0;
    while(m_dwSocketIndex == 0)
    {
        m_dwSocketIndex = ( DWORD )
                          InterlockedIncrement( ( LONG * ) &m_dwSocketLastIndex ); 
        //Make sure it does not already exist.
        CPcmciaCardSocket* pSocket = GetSocket( ( HANDLE ) m_dwSocketIndex );
        if( pSocket != NULL )
        {
            // Duplicated, retry.
            m_dwSocketIndex = 0;
            pSocket->DeRef();
        }
    }


    DEBUGMSG(ZONE_SOCKET, (TEXT("-CPcmciaCardSocket::CPcmciaCardSocket\r\n")));
}


CPcmciaCardSocket::~CPcmciaCardSocket()
{

    DEBUGMSG(ZONE_SOCKET, (TEXT("+CPcmciaCardSocket::Deinitialize()\r\n")));

    Lock();
    m_pBridge->SetupWakeupSource(FALSE );
    BOOL bInitWindow = CardDeInitWindow();
    DEBUGCHK( bInitWindow );
    Unlock();

    DEBUGMSG(ZONE_SOCKET, (TEXT("-CPcmciaCardSocket::Deinitialize()\r\n")));
}


BOOL CPcmciaCardSocket::MapDeviceRegisters(CPcmciaBusBridge* pBridge)
{
    return(TRUE);
}


//
// GetSocket - return Socket state
// [In/Out] pBuf - pointer to SS_SOCKET_STATE struct
// [In/Out] pnBuf - pointer to size of struct pointed to by pBuf
// return CERR_SUCCESS on success, CERR_UNSUPPORTED_SERVICE if size is anomolous
//
STATUS CPcmciaCardSocket::CardGetSocket( PSS_SOCKET_STATE pState )
{
    UINT16 statusReg        = 0;
    DWORD dwLastEventStatus = 0;
	ULONG ulGPIOF;

    DEBUGMSG( ZONE_SOCKET, ( TEXT( "+CPcmciaCardSocket::GetSocket()\r\n" ) ) );
    Lock();

    if( pState )
    {
        m_SockState.dwEventStatus = 0;

        //
        // Determine the slot status.
        //
        BOOL bCardDetectStatus = FALSE;
        BOOL bIRQReadyStatus   = FALSE;
        BOOL bBvd1Status       = FALSE;
        BOOL bBvd2Status       = FALSE;


		ulGPIOF=*GPIO_PFDR;

		*GPIO_FINTTYPE2   = ~ulGPIOF & ( GPIOF_PCMCIA_CD1 | GPIOF_PCMCIA_CD2 | GPIOF_PCMCIA_BVD1 | GPIOF_PCMCIA_BVD2);

		bCardDetectStatus = ( ulGPIOF & (GPIOF_PCMCIA_CD1 | GPIOF_PCMCIA_CD2) ) == (GPIOF_PCMCIA_CD1 | GPIOF_PCMCIA_CD2) ? false: true;

		if( bCardDetectStatus )
		{
			bBvd1Status       = ulGPIOF & GPIOF_PCMCIA_BVD1 ;
			bBvd2Status       = ulGPIOF & GPIOF_PCMCIA_BVD2 ;
			bIRQReadyStatus   = ulGPIOF & GPIOF_PCMCIA_IRQ;
		}

        m_SockState.dwEventStatus  |= (bCardDetectStatus ?
                                       SOCK_EVENT_CD :
                                       0 );
        m_SockState.dwEventStatus  |= (bBvd1Status ?
                                       SOCK_EVENT_BVD1 :
                                       0 );
        m_SockState.dwEventStatus  |= (bBvd2Status ?
                                       SOCK_EVENT_BVD2 :
                                       0 );
        m_SockState.dwEventStatus  |= (bIRQReadyStatus ?
                                       SOCK_EVENT_READY :
                                       0 );

        m_SockState.dwEventChanged |= (m_SockState.dwEventStatus ^ dwLastEventStatus);
        dwLastEventStatus           = m_SockState.dwEventStatus;

        *pState = m_SockState;

        DEBUGMSG( ZONE_SOCKET,
                  ( TEXT( "-CPcmciaCardSocket::GetSocket(): dwEventMask: %x dwEventChanged: %x dwEventStatus: %x\r\n" ),
                    pState->dwEventMask,
                    pState->dwEventChanged,
                    pState->dwEventStatus ) );
    }

    Unlock();
    return CERR_SUCCESS;
}


void CPcmciaCardSocket::PowerMgrCallback( BOOL bPowerOff )
{
    SS_SOCKET_STATE sSocketState = m_SockState;
    sSocketState.dwEventChanged  = SOCK_EVENT_SUSPEND_RESUME;
    sSocketState.dwEventStatus   = (bPowerOff ?
                                   SOCK_EVENT_CD :
                                   (SOCK_EVENT_CD |
                                   SOCK_EVENT_SUSPEND_RESUME ) );
    m_pBridge->CallBackToCardService(m_pBridge->GetSocketNumber(),
                                     GetSocketHandle(),
                                     &sSocketState );
}


void CPcmciaCardSocket::PowerMgr( BOOL bPowerDown )
{
}


BOOL CPcmciaCardSocket::Resuming() // This routine can not call sleep because it could endup yeild to other thread.
{
    return(FALSE);
}

//
// PDCardSetSocket
//
// @func    STATUS | PDCardSetSocket | Set the socket state of the specified socket.
// @rdesc   Returns one of the CERR_* return codes in cardserv.h.
//
// @comm    This function sets the specified socket's state and adjusts the socket
//          controller appropriately.
//          PDCardGetSocketState will usually be called first and adjustments will
//          be made to the PDCARD_SOCKET_STATE structure before PDCardSetSocketState
//          is called.  This avoids duplicated socket state on different layers and
//          it avoids unintentionally setting socket parameters.
//
// @xref <f PDCardGetSocketState>
//
STATUS CPcmciaCardSocket::CardSetSocket(PSS_SOCKET_STATE pState)
{
    STATUS retValue = CERR_SUCCESS;

    if(m_pBridge && pState)
    {
        Lock();

        // Indicate to the memory controller that a card is present in the socket.
        //
        m_SockState.dwEventMask     = pState->dwEventMask;
        m_SockState.dwEventChanged &= ~pState->dwEventChanged;

        //
        // Check the power settings for the socket.

          DEBUGMSG( ZONE_PDD,( TEXT( "PDCardSetSocket  vol %x\r\n" ),pState->fVcc ) );

        //
        if( ( pState->dwEventStatus & SOCK_EVENT_EJECT ) != 0 ||
            ( pState->dwEventStatus & SOCK_EVENT_INSERT ) != 0 )
        {
            // Ask for ejection of the card.
            DEBUGMSG( ZONE_PDD,
                      ( TEXT( "PDCardSetSocket  PCMSocket. Gernerate Artificial Eject\r\n" ) ) );
            // We have to force 
            m_pBridge->ForceEjectEvent(m_pBridge->GetSlotNumber());
        }
        else
        if ((pState->fVcc  != m_SockState.fVcc) ||
            (pState->uVpp1 != m_SockState.uVpp1)||
            (pState->uVpp2 != m_SockState.uVpp2))
        {
            // We don't support changing Vpp.
            if (pState->uVpp1 != pState->uVpp2 ||
                m_SockState.uVpp1 != pState->uVpp1 ||
                m_SockState.uVpp2 != pState->uVpp2)
            {
                Unlock();
                return(CERR_BAD_VPP);
            }
    
            if ((pState->fVcc & SOCK_VCC_LEVEL_MASK ) >= NUM_POWER_ENTRIES ||
               !(m_rgPowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].fSupply & PWR_SUPPLY_VCC))
            {
                Unlock();
                return (CERR_BAD_VCC);
            }
            else
            {
				RETAILMSG(TRUE, (TEXT("****** set Voltage to %d********\r\n"), m_rgPowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel));

				m_pBridge->PowerPCCardWrite(  m_rgPowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel,0);

				if( m_rgPowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel )
				{
					Sleep(100 );

					m_pBridge-> SocketdRestCard( );
				}
				m_SockState.fVcc  = pState->fVcc;
				m_SockState.uVpp1 = pState->uVpp1;
				m_SockState.uVpp2 = pState->uVpp2;
            }
        }

	   Unlock();
    }

    return (STATUS)retValue;
}


void CPcmciaCardSocket::PowerCycleEvent()
{
    m_pBridge->PowerCycleEvent(m_pBridge->GetSlotNumber());
}


//
// ResetSocket - do a PCMCIA reset
// return CERR_SUCCESS on success, CERR_UNSUPPORTED_SERVICE if size is anomolous
//
STATUS CPcmciaCardSocket::CardResetSocket()
{
	STATUS        retValue          = CERR_SUCCESS;
	BOOL          bCardDetectStatus = FALSE;

    UINT16        nSlotNumber       = 0;

    Lock();

    if( m_pBridge )
    {
		bCardDetectStatus = ( *GPIO_PFDR & (GPIOF_PCMCIA_CD1 | GPIOF_PCMCIA_CD2) ) == (GPIOF_PCMCIA_CD1 | GPIOF_PCMCIA_CD2) ? false: true;

        if ( bCardDetectStatus == TRUE)
        {
			BYTE	fVcc=50;

			/*
			ULONG ulGPIOF   = *GPIO_PFDR ;
			switch(ulGPIOF & (GPIOF_PCMCIA_VS1 | GPIOF_PCMCIA_VS2))
			{
				case 0:
				case GPIOF_PCMCIA_VS2:
					fVcc = 33;
					break;
				case (GPIOF_PCMCIA_VS1 | GPIOF_PCMCIA_VS2):
					fVcc = 50;
					break;
				case GPIOF_PCMCIA_VS1:
				default:
					fVcc = 0;
					break;
			}
			*/

			m_pBridge->PowerPCCardWrite( 0, 0 );
			Sleep(10 );
			m_pBridge->PowerPCCardWrite( fVcc, 0 );
			Sleep(310 );  //Wait for voltage climbs up

			if( m_pBridge-> SocketdRestCard( )  )
			{
				m_SockState.fVcc = fVcc == 50 ? 2:1 ;
				m_SockState.uVpp1 = 0;
				m_SockState.uVpp2 = 0;
			}
            // Notify the MDD of a power-on status change.
            SocketEventHandle(SOCK_EVENT_PWRCYCLE, SOCK_EVENT_PWRCYCLE);
        }
	}
    Unlock();
    return (retValue);

}


CPcmciaCardSocket* CreatePCMCIASocket(CPcmciaBusBridge* pBridge,
                                      UINT16 m_SlotNumber )
{
    CPcmciaCardSocket* pNewSocket = new CPcmciaCardSocket(pBridge, m_SlotNumber);
    if( pNewSocket != NULL )
    {
        if( pNewSocket->CardInitWindow( pNewSocket ) )
        {
            return pNewSocket;
        }
        else
        {
            delete pNewSocket;
        }
    }
    return NULL;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -