📄 pcc850.c
字号:
{
dword *bcsr1 = at_bcsr1();
*bcsr1 |= PCCVCCON; /* 0 Level vcc */
*bcsr1 |= PCMCIA_HIZPP; /* High Impedence Voltage Level vpp */
/* Enable ADS PCMCIA Channel */
*bcsr1 &= ~PCCEN;
}
#elif (MPC860)
/*
{
dword *bcsr1 = at_bcsr1();
*bcsr1 |= PCMCIA_HIZ; /* 0 Level vcc */
*bcsr1 |= PCMCIA_HIZPP; /* High Impedence Voltage Level vpp */
/* Enable ADS PCMCIA Channel */
*bcsr1 &= ~PCCEN;
}
*/
#error define power down in pcmctrl_init for mpc860
#endif
/* Initialize the PCMCIA control registers.
Clear pending interrupts and disable all interrupts. */
for (i = 0; i < NSOCKET; i++)
{
pcm860_wr_gcr(i, 0);
pcmctrl_card_down(i);
}
IMMR->pcmcia_per = 0x00000000; /* disable all interrupts */
IMMR->pcmcia_pscr = PCMCIA_ALL_AMGMT|PCMCIA_ALL_AIRQ|PCMCIA_ALL_BMGMT|PCMCIA_ALL_BIRQ;
for (i = 0; i < 7; i++)
{
pcm860_wr_option_reg(i, 0);
pcm860_wr_address_reg(i, 0);
}
l = pcm860_rd_gcr(0);
l &= ~PGCRA_CASCHLVL;
l |= ((1<<(7-PCMCIA_MGMT_INTERRUPT_LEVEL))<<16);
pcm860_wr_gcr(0, l);
if (NSOCKET > 1)
{
l = pcm860_rd_gcr(1);
l &= ~PGCRB_CBSCHLVL;
l |= ((1<<(7-PCMCIA_MGMT_INTERRUPT_LEVEL))<<16);
pcm860_wr_gcr(1, l);
}
IMMR->siu_simask |= PCMCIA_MGMT_INTERRUPT_MASK|PCMCIA_IRQ_INTERRUPT_MASK;
#if (defined(ERTFS_SA))
hook_pcmcia_interrupt(MGMT_INTERRUPT);
#else
ks_hook_interrupt(MGMT_INTERRUPT, (PFVOID) 0, mgmt_isr, (RTIPINTFN_POINTER) 0, 0);
#endif
/* Enable card detect change for slot 0 and 1 */
IMMR->pcmcia_per |= (PSCR_CACD2_C|PSCR_CACD1_C);
IMMR->pcmcia_per |= (PSCR_CBCD2_C|PSCR_CBCD1_C);
pcmctrl_initted = TRUE;
ks_enable();
return(TRUE);
}
void pcmctrl_close(void) /* __fn__ */
{
}
static void pcmctrl_enable_interrupt(int socket, int irq, BOOLEAN on_off)
{
dword l;
/* Set the IRQ level in 4 steps:-
(1) Read in contents of general control register.
(2) Clear the most significant 8 bits.
(3) Set one bit of the MSB to indicate the level of the interrupt.
(4) Write the updated contents of the GCR back to the GCR. */
l = pcm860_rd_gcr(socket);
if (socket == 0)
l &= ~PGCRA_CAIREQLVL;
else
l &= ~PGCRB_CBIRQLVL;
l |= ((1<<(7-PCMCIA_IRQ_INTERRUPT_LEVEL))<<24);
pcm860_wr_gcr(socket, l);
/* Enable/disable interrupts:
(1) Read contents of PCMCIA interface enable register.
(2) If interupts are to be turned of then clear the CB_ERDY_R bit, else set it.
(3) Update the PCMCIA interface enable register. */
l = IMMR->pcmcia_per;
if ( on_off )
{
if (socket == 0)
#if (0)
l |= PER_CA_ERDY_R;
else
l |= PER_CB_ERDY_R;
#endif
l |= PER_CA_ERDY_L;
else
l |= PER_CB_ERDY_L;
}
else
{
if (socket == 0)
#if (0)
l &= ~PER_CA_ERDY_R;
else
l &= ~PER_CB_ERDY_R;
#endif
l &= ~PER_CA_ERDY_L;
else
l &= ~PER_CB_ERDY_L;
}
IMMR->pcmcia_per = l;
}
void pcmctrl_map_ata_regs(int socket, IOADDRESS ioaddr, int interrupt_number)
{
int j;
DDRIVE *pdr;
pcm860_map_window(socket, 1 /* 16 bit */, PCM8_MTYPE_IO);
if (interrupt_number >= 0)
{
for (j = 0; j < NDRIVES; j++)
{
pdr = pc_drno_to_drive_struct(j);
if (pdr && (pdr->pcmcia_slot_number == socket) && (pdr->drive_flags && DRIVE_FLAGS_PCMCIA_ATA))
{
// map_slot_to_controller[socket] = pdr->pcmcia_controller_number;
map_slot_to_controller[socket] = pdr->controller_number;
break;
}
}
pcmctrl_enable_interrupt(socket, interrupt_number, TRUE);
}
/* Apply Vpp and Vcc power */
pcmctrl_device_power_up(socket);
}
/* pcmctrl_card_is_installed(int socket, BOOLEAN apply_power) - Check if a socket has a card installed */
/* */
/* Check the pcmcia interface at logical socket 'socket' for the presence of */
/* a card. */
/* */
/* Inputs: */
/* Logical socket number */
/* */
/* Returns: */
/* TRUE - if a card is installed */
/* FALSE - if the socket is empty */
BOOLEAN pcmctrl_card_is_installed(int socket, BOOLEAN apply_power) /*__fn__*/
{
dword l;
/* Now read the interface status. Look for a card */
l = IMMR->pcmcia_pipr;
if ( (socket == 1 && (l & (PIPR_CBCD2|PIPR_CBCD1)) == 0) ||
(socket == 0 && (l & (PIPR_CACD2|PIPR_CACD1)) == 0) )
{
if (apply_power && !card_is_powered[socket])
{
if (pcmctrl_card_power_up(socket))
return(TRUE);
else
{
pcmctrl_card_down(socket);
return(FALSE);
}
}
else
return(TRUE);
}
return(FALSE);
}
/* pcmctrl_card_installed(int socket) - Check if a socket has a card */
/* and apply power installed */
/* */
/* Check the pcmcia interface at logical socket 'socket' for the presence of */
/* a card. If found apply power and return TRUE. Otherwise return FALSE. */
/* If the card is found and powered this routine must set the vriable */
/* BOOLEAN card_is_powered[socket] to TRUE. */
/* */
/* */
/* Inputs: */
/* Logical socket number */
/* */
/* Returns: */
/* TRUE - if a card is installed */
/* FALSE - if the socket is empty */
BOOLEAN pcmctrl_card_installed(int socket) /*__fn__*/
{
return(pcmctrl_card_is_installed(socket, TRUE));
}
/* pcmctrl_power_up(int socket) - Enable power to a card. */
/* */
/* This function clears the reset bit and enables power to a card. */
/* */
/* Notes: */
/* 1. The card is assumed to be in the slot (see card_is_installed(int socket)) */
/* 2. The power setting is 5.0 volts applied automatically when the card is */
/* inserted. Other power options should be added as required. */
/* Inputs: */
/* Logical socket number */
/* */
/* Returns: */
BOOLEAN pcmctrl_card_power_up(int socket) /*__fn__*/
{
dword l;
dword xx;
word i;
int is_ready;
/* Set the reset bit and card output enable */
l = pcm860_rd_gcr(socket);
if (socket == 0)
xx = (PGCRA_CAOE|PGCRA_CARESET);
else
xx = (PGCRB_CBOE|PGCRB_CBRESET);
l |= xx;
pcm860_wr_gcr(socket, l);
/* power off and settle */
pcm860_socket_vccpower(socket, 0);
pcm860_socket_vpppower(socket, -1); /* Set to HiZ */
ks_sleep((word)(1+(50 + ks_msec_p_tick())/ks_msec_p_tick()));
/* power on 3.3 or 5 volts */
/* Need to look in PIPR for 3V vs's 5v card. VS1 indicates 3.3 volt. VS2 is reserved
for a secondary voltage and is not tested here */
l = IMMR->pcmcia_pipr;
if (socket == 0)
{
if ((l & PIPR_CAVS1) == 0)
pcm860_socket_vccpower(socket, 5);
else
pcm860_socket_vccpower(socket, 3);
}
else
{
if ((l & PIPR_CBVS1) == 0)
pcm860_socket_vccpower(socket, 5);
else
pcm860_socket_vccpower(socket, 3);
}
ks_sleep((word)((300 + ks_msec_p_tick())/ks_msec_p_tick()));
#if(0)
/* Toggle reset */
l = pcm860_rd_gcr(socket);
if (socket == 0)
xx = PGCRA_CARESET;
else
xx = PGCRB_CBRESET;
l |= xx;
pcm860_wr_gcr(socket, l);
/* Sleep 10 msecs */
ks_sleep((word)(1+(10 + ks_msec_p_tick())/ks_msec_p_tick()));
#endif
/* Clear the reset bit */
l = pcm860_rd_gcr(socket);
if (socket == 0)
xx = ~PGCRA_CARESET;
else
xx = ~PGCRB_CBRESET;
l &= xx;
pcm860_wr_gcr(socket, l);
/* Sleep 10 msecs */
ks_sleep((word)(1+(10 + ks_msec_p_tick())/ks_msec_p_tick()));
/* Clear output enable */
l = pcm860_rd_gcr(socket);
if (socket == 0)
xx = ~PGCRA_CAOE;
else
xx = ~PGCRB_CBOE;
l &= xx;
pcm860_wr_gcr(socket, l);
/* Sleep 20 msecs */
ks_sleep((word)(1+(20 + ks_msec_p_tick())/ks_msec_p_tick()));
/* Wait for pcmcia ready. wait up to 1 seconds. */
is_ready = 0;
for (i = 0; i < ks_ticks_p_sec(); i = (word)(i+2))
{
l = IMMR->pcmcia_pipr;
if (socket == 0)
{
if (l & PIPR_CARDY) // check ready slot a
{
is_ready = 1;
break;
}
}
else
{
if (l & PIPR_CBRDY) // check ready slot b
{
is_ready = 1;
break;
}
}
ks_sleep(2);
}
if (!is_ready)
return(FALSE);
card_device_type[socket] = PCMCIA_NO_DEVICE;
card_is_powered[socket] = TRUE;
return(TRUE);
}
void pcmctrl_device_power_up(int socket) /*__fn__*/
{
}
static void pcmctrl_enable_io_mode(int socket)
{
}
/* pcmctrl_card_power_down(int socket) - Turn off power to a card. */
/* This function turns off power and clears the reset bit */
/* Returns: nothing */
static void pcmctrl_card_power_down(int socket) /*__fn__*/
{
dword l;
dword xx;
/* Set the reset bit and card output enable */
l = pcm860_rd_gcr(socket);
if (socket == 0)
xx = (PGCRA_CAOE|PGCRA_CARESET);
else
xx = (PGCRB_CBOE|PGCRB_CBRESET);
l |= xx;
pcm860_wr_gcr(socket, l);
/* Make sure power to the card is off through external power controller */
pcm860_socket_vccpower(socket, 0);
pcm860_socket_vpppower(socket, -1); /* Set to HiZ */
card_is_powered[socket] = FALSE;
card_device_type[socket] = PCMCIA_NO_DEVICE;
}
/* pcmctrl_card_down(int socket) - Card down */
/* */
/* The upper layers detected that the disk is not valid or is not */
/* installed. This routine is called so the slot is put in a known */
/* state for re-insertion for pcmcia this is power down, for */
/* True IDE this should probably assert -OE. */
/* */
/* */
/* Returns: */
void pcmctrl_card_down(int socket) /*__fn__*/
{
int i;
/* Make sure interrupts are disabled */
pcmctrl_enable_interrupt(socket, 0, FALSE);
/* Power it down */
pcmctrl_card_power_down(socket);
}
byte pcmctrl_get_cis_byte(int socket, dword offset) /* __fn__ */
{
byte c;
byte *p;
c = 0;
// Try Common (Bank zero) first
p = pcm860_map_window( socket, 1 /* is_16 */, PCM8_MTYPE_COMMON);
p = pcm860_map_window( socket, 1 /* is_16 */, PCM8_MTYPE_ATTRIBUTE);
if (p)
p += ( offset * 2 ); // CIS is byt twos
if (p)
c = *p;
return (c);
}
void pcmctrl_put_cis_byte(int socket, dword offset, byte c) /*__fn__*/
{
byte KS_FAR *p;
p = pcm860_map_window(socket, 1 /* is_16 */, PCM8_MTYPE_ATTRIBUTE);
if (p)
p += ( offset * 2 ); // CIS is byt twos
if (p)
*p = c;
}
#if (0)
BROKEN
void pcmctrl_map_3com(int socket, int irq, int iobase) /* __fn__ */
{
pcmctrl_enable_io_mode(socket);
/* Set up io windows */
/* chip 0, Socket 0, window 0, size 16, isa_add = iobase pcmcia addr = iobase */
/* Allow bus lines (CS16) to determine transfer size */
pd67xx_map_io(socket, IO_WINDOW_0, 16, (word)iobase,
(word)(IO_CTL_AUTO|IO_CTL_16BIT|IO_CTL_TR1));
pcmctrl_enable_interrupt(socket, irq, TRUE);
}
void pcmctrl_map_linksys_regs(int socket, int irq, int iobase) /*__fn__*/
{
/* enable IO mode. */
pcmctrl_enable_io_mode(socket);
/* Set up io windows */
/* chip 0, Socket 0, window 0, size 16, isa_add = 0x170 pcmcia addr = 0x170 */
/* Allow bus lines (CS16) to determine transfer size */
pd67xx_map_io(socket, IO_WINDOW_0, 32, (word)iobase, (byte)(IO_CTL_AUTO|IO_CTL_16BIT|IO_CTL_TR1));
/* Turn on interrupts */
pcmctrl_enable_interrupt(socket, irq, TRUE);
/* Apply Vpp power (does nothing since we use auto Vpp) */
pcmctrl_device_power_up(socket);
}
#endif
#endif /* INCLUDE_PCMCIA */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -