?? socket.c
字號:
//**********************************************************************
//
// Filename: socket.c
//
// Description: Routines to set/return the sockets paramaters.
//
// 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
// LICENSE.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2002, All Rights Reserved
//
//**********************************************************************
#include <windows.h>
#include <types.h>
#include <cardserv.h>
#include <sockserv.h>
#include <sockpd.h>
#include <memory.h>
#include <hwdefs.h>
//#define FORCE_POLLING 1
//
// CEPC PCMCIA Socket Services Socket APIs:
// PDCardInquireSocket
// PDCardGetSocket
// PDCardSetSocket
// PDCardInquireAdapter
//
#define NUM_SOCKETS 1
#define NUM_POWER_ENTRIES 4
#define VCC_DEFAULT_INDEX 2
//
// @doc DRIVERS
//
PDCARD_ADAPTER_INFO v_AdapterInfo =
{
1, // memory granularity (for production platforms, this should be 1)
0, // adapter capabilities
8, // cache line size in 32-bit words
NUM_POWER_ENTRIES
};
//
// These #defs must match how the v_PowerEntries[] table entry #defines below
// are arranged. (This simplifies the code in other areas).
//
#define VCC_0V_INDEX 0
#define VPP1_0V_INDEX 0
#define VPP2_0V_INDEX 0
#define VCC_33V_INDEX 1
#define VCC_50V_INDEX 2
#define VPP1_120V_INDEX 3
PDCARD_POWER_ENTRY v_PowerEntries[NUM_POWER_ENTRIES] =
{
{ 0, PWR_SUPPLY_VCC | PWR_SUPPLY_VPP1 | PWR_SUPPLY_VPP2 },
{ 33, PWR_SUPPLY_VCC },
{ 50, PWR_SUPPLY_VCC | PWR_SUPPLY_VPP1 | PWR_SUPPLY_VPP2 },
{ 120, PWR_SUPPLY_VPP1 | PWR_SUPPLY_VPP2 }
};
PDCARD_SOCKET_STATE v_SockState[NUM_SOCKETS] =
{
{
SOCK_CAP_IO,
EVENT_MASK_BATTERY_DEAD|EVENT_MASK_BATTERY_LOW|EVENT_MASK_CARD_DETECT|
EVENT_MASK_WRITE_PROTECT, // status change interrupt mask
0, // present socket state
0, // control and indicators
0, // interface type
0, // Vcc
0, // Vpp1
0 // Vpp2
},
};
PDCARD_ADAPTER_STATE v_AdapterState[NUM_SOCKETS] = {ADP_STATE_POWEROFF};
extern DWORD g_Irq; // PCMCIA IRQ set in init.c
//****************************************************************************
// InitSocketNoCard
//****************************************************************************
// Set the socket controller registers to initial state with no card inserted.
//
//
VOID InitSocketNoCard( void)
{
DEBUGMSG(1,(TEXT("++InitSocket")));
//
// I believe all that is needed here is to initialize the GPIO registers
// so that a card can be detected. Only GPIO F is used and GPIOF
// is exclusively used for PCMCIA so there is no need to call
// the system.
//
//
// All GPIO pins are inputs.
//
*GPIO_PFDDR = 0;
*GPIO_PFDR = 0;
//
// Temporarily disable all PCMCIA interrupts.
//
*GPIO_INTENF = 0;
//
// Acknowlege any pending edge triggered PCMCIA interrupts.
//
*GPIO_FEOI = 0xFF;
//
// We want to make the GPIOF_PCMCIA_IRQ pin level triggered.
// We don't care about any of the other bits in the register.
//
*GPIO_FINTTYPE1 = 0;
//
// We want the GPIOF_PCMCIA to be triggered high.
//
//*GPIO_FINTTYPE2 = GPIOF_PCMCIA_IRQ;
//
// We want the GPIOF_PCMCIA to be triggered low.
//
*GPIO_FINTTYPE2 = 0;
//
// Enable the interrupt.
//
*GPIO_INTENF = 0;
//
// Setup the PCMCIA controller.
//
*SMC_PCCONFIG_ATT1 = PCCONFIG_ADDRESSTIME_MASK |
PCCONFIG_HOLDTIME_MASK |
PCCONFIG_ACCESSTIME_MASK |
PCCONFIG_MW_8BIT;
*SMC_PCCONFIG_MEM1 = PCCONFIG_ADDRESSTIME_MASK |
PCCONFIG_HOLDTIME_MASK |
PCCONFIG_ACCESSTIME_MASK |
PCCONFIG_MW_8BIT;
//
// The Windows drivers never seem to set the access speed for the I/O
// windows. Since I/O has a fixed access speed we need to set it
// initially.
//
*SMC_PCCONFIG_IO1 = CalculatePcmciaTimings(0) |
PCCONFIG_MW_8BIT;
*SMC_PCCONT = PCCONT_PC1EN | PCCONT_WEN1;
DEBUGMSG (1,(TEXT("--InitSocket\n\r")));
}
//****************************************************************************
// PDCardGetSocket
//****************************************************************************
// @func STATUS | PDCardGetSocket | Get the socket state of the specified socket.
// @rdesc Returns one of the CERR_* return codes in cardserv.h.
//
// @comm This function reads the specified socket's state and returns it in
// the PDCARD_SOCKET_STATE structure.
STATUS PDCardGetSocket
(
UINT32 uSocket, // @parm Socket number (first socket is 0)
PPDCARD_SOCKET_STATE pState // @parm Pointer to PDCARD_SOCKET_STATE structure
)
{
ULONG ulGPIOF;
PPDCARD_SOCKET_STATE pPDDState;
if (uSocket >= NUM_SOCKETS)
{
return CERR_BAD_SOCKET;
}
pPDDState = &v_SockState[uSocket];
EnterCriticalSection(&g_PCIC_Crit);
//
// Start off with nothing
//
pPDDState->fNotifyEvents = 0;
//
// First acknowledge any status change interrupts
//
ulGPIOF = *GPIO_PFDR ;
DumpSocketRegisters();
//DEBUGMSG
//(
// ZONE_PDD,
// (
// TEXT("PDCardGetSocket *GPIO_PFDR = 0x%x, VIC1_STATUS =0x%08x, VICSTATUS =0x%08x\r\n"),
// ulGPIOF,
// *VIC1_IRQSTATUS,
// *VIC2_IRQSTATUS
// )
//);
//
// The first thing in code after an interrupt occuring is the MDD reads
// PDCardGetSocket to determine the interupt type. In this function we
// need to switch the direction of the interrupt for card detect and battery level.
// We only need one interrupt of each type unless the state changes.
//
*GPIO_FINTTYPE2 = ~ulGPIOF & ( GPIOF_PCMCIA_CD1 | GPIOF_PCMCIA_CD2 | GPIOF_PCMCIA_BVD1 | GPIOF_PCMCIA_BVD2);
//
// Check out the card detect pins.
//
if (( ulGPIOF & ( GPIOF_PCMCIA_CD1 | GPIOF_PCMCIA_CD2 )) ==
( GPIOF_PCMCIA_CD1 | GPIOF_PCMCIA_CD2 ))
{
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) ~CARD_DETECT\r\n"), uSocket));
// InitSocketNoCard();
goto pcgs_exit;
}
else
{
pPDDState->fNotifyEvents |= EVENT_MASK_CARD_DETECT;
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) CARD_DETECT\r\n"), uSocket));
}
//
// Check out the Battery voltage.
//
switch (ulGPIOF & (GPIOF_PCMCIA_BVD1 | GPIOF_PCMCIA_BVD2))
{
case GPIOF_PCMCIA_BVD1:
pPDDState->fNotifyEvents |= EVENT_MASK_BATTERY_LOW;
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) BATTERY_LOW\r\n"), uSocket));
break;
case GPIOF_PCMCIA_BVD2:
case 0:
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) BATTERY_DEAD\r\n"), uSocket));
pPDDState->fNotifyEvents |= EVENT_MASK_BATTERY_DEAD;
break;
}
//
// Check to see if the card write protect is on. This is an old
// pcmcia construct.
//
if (ulGPIOF & GPIOF_PCMCIA_WP)
{
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) WRITE_PROTECT\r\n"), uSocket));
pPDDState->fNotifyEvents |= EVENT_MASK_WRITE_PROTECT;
}
if (ulGPIOF & GPIOF_PCMCIA_IRQ)
{
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) CARD_READY\r\n"), uSocket));
pPDDState->fNotifyEvents |= EVENT_MASK_CARD_READY;
}
//
// Copy the parameters
//
pcgs_exit:
memcpy(pState, pPDDState, sizeof(PDCARD_SOCKET_STATE));
LeaveCriticalSection(&g_PCIC_Crit);
return CERR_SUCCESS;
} // PDDCardGetSocket
//****************************************************************************
// 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 PDCardSetSocket
(
UINT32 uSocket, // @parm Socket number (first socket is 0)
PPDCARD_SOCKET_STATE pState // @parm Pointer to PDCARD_SOCKET_STATE structure
)
{
ULONG ulGPIOF, ulIntEnF;
PPDCARD_SOCKET_STATE pPDDState;
STATUS ret;
UCHAR ucVcc, ucVpp1, ucVpp2;
BOOL fSetVoltage;
int t;
DEBUGMSG(ZONE_PDD, (TEXT("PDCardSetSocket(%d) entered\r\n"), uSocket));
if (uSocket >= NUM_SOCKETS)
{
ret = CERR_BAD_SOCKET;
goto pcss_fail;
}
//
// Check socket power level indexes
//
if ((pState->fVcc & SOCK_VCC_LEVEL_MASK) >= NUM_POWER_ENTRIES ||
!(v_PowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].fSupply & PWR_SUPPLY_VCC))
{
ret = CERR_BAD_VCC;
goto pcss_fail;
}
if (pState->uVpp1 >= NUM_POWER_ENTRIES || pState->uVpp2 >= NUM_POWER_ENTRIES ||
!(v_PowerEntries[pState->uVpp1].fSupply & PWR_SUPPLY_VPP1) ||
!(v_PowerEntries[pState->uVpp2].fSupply & PWR_SUPPLY_VPP2))
{
ret = CERR_BAD_VPP;
goto pcss_fail;
}
EnterCriticalSection(&g_PCIC_Crit);
//
// TODO TODO TODO We need special code to initialize window if the window
// is disabled.
//
//
// TODO TODO TODO - Set Card State.
//
ulGPIOF = *GPIO_PFDR ;
pPDDState = &v_SockState[uSocket];
//
// Set the status change interrupt sources
//
ulIntEnF = 0;
if (pState->fInterruptEvents & EVENT_MASK_CARD_DETECT)
{
ulIntEnF |= GPIOF_PCMCIA_CD1 | GPIOF_PCMCIA_CD2 ;
}
if (pState->fInterruptEvents & EVENT_MASK_BATTERY_DEAD)
{
ulIntEnF |= GPIOF_PCMCIA_BVD1;
}
if (pState->fInterruptEvents & EVENT_MASK_BATTERY_LOW)
{
ulIntEnF |= GPIOF_PCMCIA_BVD2;
}
if (pState->fIREQRouting & SOCK_IREQ_ENABLE)
{
ulIntEnF |= GPIOF_PCMCIA_IRQ;
}
*GPIO_INTENF = ulIntEnF;
DEBUGMSG
(
ZONE_PDD,
( TEXT("PDCardSetSocket *GPIO_INTENF = 0x%x\r\n"),
ulIntEnF
)
);
if (( ulGPIOF & (GPIOF_PCMCIA_CD1|GPIOF_PCMCIA_CD2)) ==
(GPIOF_PCMCIA_CD1|GPIOF_PCMCIA_CD2))
{
DEBUGMSG(ZONE_PDD,
(TEXT("PDCardSetSocket(%d) No card inserted\r\n"), uSocket));
goto pcss_exit;
}
DEBUGMSG(1,
(TEXT("PDCardSetSocket voltage = %d\r\n"),
v_PowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel));
//
// Check to see if the voltages are reasonable.
//
fSetVoltage = FALSE;
if ((pState->fVcc & SOCK_VCC_LEVEL_MASK) != (pPDDState->fVcc & SOCK_VCC_LEVEL_MASK))
{
ucVcc = v_PowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel;
fSetVoltage = TRUE;
}
if ((pState->uVpp1 & SOCK_VCC_LEVEL_MASK) != (pPDDState->uVpp1 & SOCK_VCC_LEVEL_MASK))
{
ucVpp1= v_PowerEntries[pState->uVpp1 & SOCK_VCC_LEVEL_MASK].uPowerLevel;
fSetVoltage = TRUE;
}
if ((pState->uVpp2 & SOCK_VCC_LEVEL_MASK) != (pPDDState->uVpp2 & SOCK_VCC_LEVEL_MASK))
{
ucVpp2 = v_PowerEntries[pState->uVpp1 & SOCK_VCC_LEVEL_MASK].uPowerLevel;
fSetVoltage = TRUE;
}
if(fSetVoltage)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -