📄 socket.c
字号:
/*++
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.
Copyright (c) 2001. Samsung Electronics, co. ltd All rights reserved.
Module Name:
socket.c
Abstract:
Rev:
2002.04.22 : add S3C2410 specific initialization codes (by Seung-han, Lim)
2001.12.21 : Bug Fixup (kwangyoon LEE, kwangyoon@samsung.com)
2001.12.12 : add S3C2400 Specific codes (kwangyoon LEE, kwangyoon@samsung.com)
Notes:
--*/
#include <windows.h>
#include <types.h>
#include <cardserv.h>
#include <sockserv.h>
#include <sockpd.h>
#include <memory.h>
//#include <pc.h>
#include "S2440.H"
#include "pd6710.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
};
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,
#ifdef FORCE_POLLING
EVENT_MASK_BATTERY_DEAD|EVENT_MASK_BATTERY_LOW|
#else
EVENT_MASK_BATTERY_DEAD|EVENT_MASK_BATTERY_LOW|EVENT_MASK_CARD_DETECT|
#endif
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
},
};
//volatile PUCHAR g_PCICIndex;
//volatile PUCHAR g_PCICData;
//CRITICAL_SECTION g_PCIC_Crit;
extern volatile PUCHAR g_PCICIndex;
extern volatile PUCHAR g_PCICData;
extern CRITICAL_SECTION g_PCIC_Crit;
extern DWORD g_Irq; // PCMCIA IRQ set in init.c
//extern volatile int BackupFlag;
//extern void PD_DataBackup();
extern void PD_DataRestore();
//
// Set the socket controller registers to initial state with no card inserted.
//
VOID InitSocketNoCard(UINT32 uSocket, BOOL bUserMode)
{
UCHAR tmp;
UINT32 status;
UINT32 i;
UINT32 first, last;
PDCARD_WINDOW_STATE WinState;
DEBUGMSG (1,(TEXT("++InitSocketNoCard #%x\n\r"), uSocket));
//RETAILMSG(1, (TEXT("PDD:SOCKET.C:InitSocketNoCard()\r\n")));
PCICIndex(uSocket, REG_POWER_CONTROL);
PCICDataWrite(PWR_AUTO_POWER);
// PD6710 specific code to enable management interrupt(routed to -INTR)
tmp = CFG_CARD_DETECT_ENABLE;
PCICIndex(uSocket, REG_STATUS_CHANGE_INT_CONFIG);
PCICDataWrite(tmp);
// Enable Manage Interrupt
PCICIndex(0, REG_INTERRUPT_AND_GENERAL_CONTROL);
tmp = PCICDataRead();
tmp |= INT_ENABLE_MANAGE_INT;
PCICDataWrite(tmp);
//
// Disable the I/O windows
//
first = (uSocket == 0) ? SOCKET0_FIRST_IO_WINDOW : SOCKET1_FIRST_IO_WINDOW;
last = first + 2;
for (i = first; i < last; i++)
{
status = PDCardGetWindow(i, &WinState);
if (status == CERR_SUCCESS)
{
WinState.fState &= ~WIN_STATE_ENABLED;
WinState.uOffset = 0;
// set the high bit in the window index if we are in kernel-mode
PDCardSetWindow(bUserMode ? i : (i|ADP_STATE_KERNEL_MODE), &WinState);
}
}
DEBUGMSG (1,(TEXT("--InitSocketNoCard\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
{
UINT8 tmp;
PPDCARD_SOCKET_STATE pPDDState;
DEBUGMSG(1,(TEXT("+++PDCardGetSocket\r\n")));
if (uSocket >= NUM_SOCKETS)
{
return CERR_BAD_SOCKET;
}
pPDDState = &v_SockState[uSocket];
EnterCriticalSection(&g_PCIC_Crit);
pPDDState->fNotifyEvents = 0; // Start off with nothing
//
// First acknowledge any status change interrupts
//
PCICIndex(uSocket, REG_CARD_STATUS_CHANGE);
tmp = PCICDataRead();
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) REG_CARD_STATUS_CHANGE(0x%x) = 0x%x\r\n"),
uSocket, REG_CARD_STATUS_CHANGE, tmp));
//
// Figure out the socket state
//
PCICIndex(uSocket, REG_INTERFACE_STATUS);
tmp = PCICDataRead();
if ((tmp & (STS_CD1|STS_CD2)) == (STS_CD1|STS_CD2))
{
pPDDState->fNotifyEvents |= EVENT_MASK_CARD_DETECT;
} else {
InitSocketNoCard(uSocket, FALSE);
goto pcgs_exit;
}
#ifdef NOT_IMPLEMENTED
switch (tmp & (STS_BVD1|STS_BVD2))
{
case STS_BVD1:
pPDDState->fNotifyEvents |= EVENT_MASK_BATTERY_LOW;
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) BATTERY_LOW\r\n"), uSocket));
break;
case STS_BVD2:
case 0:
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) BATTERY_DEAD\r\n"), uSocket));
pPDDState->fNotifyEvents |= EVENT_MASK_BATTERY_DEAD;
break;
}
#endif NOT_IMPLEMENTED
if (tmp & STS_WRITE_PROTECT)
{
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) WRITE_PROTECT\r\n"), uSocket));
pPDDState->fNotifyEvents |= EVENT_MASK_WRITE_PROTECT;
}
if (tmp & STS_CARD_READY)
{
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) CARD_READY\r\n"), uSocket));
pPDDState->fNotifyEvents |= EVENT_MASK_CARD_READY;
}
DEBUGMSG(1,(TEXT("---PDCardGetSocket\r\n")));
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
{
UINT8 tmp, intctl;
PPDCARD_SOCKET_STATE pPDDState;
STATUS ret;
int t;
DEBUGMSG(1, (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);
PCICIndex(uSocket, REG_INTERFACE_STATUS);
tmp = PCICDataRead();
if ((tmp & (STS_CD1|STS_CD2)) != (STS_CD1|STS_CD2))
{
DEBUGMSG(ZONE_PDD, (TEXT("PDCardSetSocket(%d) No card inserted\r\n"), uSocket));
InitSocketNoCard(uSocket, FALSE);
goto pcss_exit;
}
pPDDState = &v_SockState[uSocket];
//
// Set the status change interrupt sources
//
#if 1
tmp = (UCHAR)(g_Irq << 4); // CFG_MANAGEMENT_IRQ_BIT* bits will be set
#else
tmp =0;
#endif
if (pState->fInterruptEvents & EVENT_MASK_CARD_DETECT)
{
tmp |= CFG_CARD_DETECT_ENABLE;
}
if (pState->fInterruptEvents & EVENT_MASK_BATTERY_DEAD)
{
tmp |= CFG_BATTERY_DEAD_ENABLE;
}
if (pState->fInterruptEvents & EVENT_MASK_BATTERY_LOW)
{
tmp |= CFG_BATTERY_WARNING_ENABLE;
}
if (pState->fIREQRouting & SOCK_IREQ_ENABLE)
{
// tmp |= CFG_READY_ENABLE;
}
PCICIndex(uSocket, REG_STATUS_CHANGE_INT_CONFIG);
PCICDataWrite(tmp);
DEBUGMSG(ZONE_PDD, (TEXT("PDCardSetSocket(%d) REG_STATUS_CHANGE_INT_CONFIG(0x%x) = 0x%x\r\n"),
uSocket, REG_STATUS_CHANGE_INT_CONFIG, tmp));
#if 1
// PD6710 specific code to enable management interrupt(routed to -INTR)
PCICIndex(0, REG_INTERRUPT_AND_GENERAL_CONTROL);
tmp = PCICDataRead();
tmp |= INT_ENABLE_MANAGE_INT;
PCICDataWrite(tmp);
#endif
//
// Enable or disable IREQ interrupts
//
PCICIndex(uSocket, REG_INTERRUPT_AND_GENERAL_CONTROL);
tmp = PCICDataRead();
tmp &= (UCHAR)~g_Irq; // Turn off INT_IRQ_BIT* bits
if (pState->fIREQRouting & SOCK_IREQ_ENABLE)
{
DEBUGMSG(1, (TEXT("Enable IREQ interrupts #%x\r\n"), g_Irq));
tmp |= ((UCHAR)g_Irq)|INT_CARD_NOT_RESET; // Turn on INT_IRQ_BIT* bits
} else {
tmp |= INT_CARD_NOT_RESET;
}
PCICDataWrite(tmp);
DEBUGMSG(1, (TEXT("PDCardSetSocket voltage = %d\r\n"),
v_PowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel));
// ignore Vpp
if ((pState->fVcc & SOCK_VCC_LEVEL_MASK) != (pPDDState->fVcc & SOCK_VCC_LEVEL_MASK))
{
//
// Set socket power as requested.
//
switch (v_PowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel)
{
case 0:
PCICIndex(uSocket, REG_POWER_CONTROL);
PCICDataWrite(0);
goto pcss_exit; // this is what it used to do so I won't change it
case 33:
PCICIndex(uSocket, 0x16);//REG_MISC_CONTROL_1);
PCICDataWrite(0x02); // enable 3.3V
DEBUGMSG(1, (TEXT("set to 3.3V\r\n")));
break;
case 50:
PCICIndex(uSocket, 0x16);//REG_MISC_CONTROL_1);
if (PCICDataRead() & 0x01) // i.e., if we detect a 5V card:
{
PCICDataWrite(0x00); // disable 3.3V (i.e., use 5V)
DEBUGMSG(1, (TEXT("set to 5V\r\n")));
}
else
{
// this is a 3.3V ONLY card and mustn't be powered at 5V
// so ignore the command; we'd assert here save that card
// services will attempt to apply 5V to read the CIS.
PCICDataWrite(0x02); // enable 3.3V
DEBUGMSG(1, (TEXT("set to 3.3V[5V]\r\n")));
}
break;
default:
ASSERT(0); // this ought to have been caught above
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -