📄 pcic.c
字号:
semGive (&pcicMuteSem); /* mutual execlusion stop */ return (OK); }/********************************************************************************* pcicCscOff - Disable the card status change interrupt.** This routine Disables the card status change interrupt.** RETURNS: OK (always).*/LOCAL STATUS pcicCscOff ( int sock, /* socket no. */ int irq /* IRQ level for CSC */ ) { semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */ /* Turn off all card status change interrupts */#if 0 pcicSet (sock, PCIC_CSCINT, (irq << 4) | 0x00);#endif AT91_SYS->PIOB_ODR = at91_pcmcia_irqs[0].bits; /* disable output */ AT91_SYS->PIOB_IDR = at91_pcmcia_irqs[0].bits; /* disable it */ semGive (&pcicMuteSem); /* mutual execlusion stop */ return (OK); }/********************************************************************************* pcicCscPoll - Get the card status by polling the register.** This routine gets the card status by polling the register.* This routine can be called in interrupt level.** RETURNS: The card status of the socket.*/LOCAL int pcicCscPoll ( int sock /* socket no. */ ) { BOOL intMode = intContext (); int value; int value0; int status=0; if (!intMode) semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */ /* value = at91_pcmcia_poll_event(0); if(value&PC_DETECT) status = PC_DETECT; if(value&PC_STSCHG) status = PC_STSCHG; if(value&PC_READY) status = PC_READY;*/ if (!(AT91_SYS->PIOB_PDSR & (AT91C_CF_PB0_CD1 | AT91C_CF_PB1_CD2))) { status |= PC_DETECT; } if (status&PC_DETECT) { if((AT91_SYS->PIOB_PDSR & AT91C_CF_PB4_RDY)) status |= PC_READY; }#if 0 value = pcicGet (sock, PCIC_CSC); while ((value0 = pcicGet (sock, PCIC_CSC)) != 0) value |= value0; if (pcicGet (sock, PCIC_INTCTL) & PCIC_PC_IOCARD) status = (value & PCIC_CSC_STSCHG) ? PC_STSCHG : 0; else { status = (value & PCIC_CSC_BVD1) ? PC_BATDEAD : 0; status |= (value & PCIC_CSC_BVD2) ? PC_BATWARN : 0; } status |= (value & PCIC_CSC_READY) ? PC_READY : 0; status |= (value & PCIC_CSC_DETECT) ? PC_DETECT : 0;#endif if (!intMode) semGive (&pcicMuteSem); /* mutual execlusion stop */ return (status); }/********************************************************************************* pcicIrqGet - Get IRQ level of the socket.** This routine gets IRQ level of the socket.** RETURNS: The IRQ level of the socket.*/LOCAL int pcicIrqGet ( int sock /* socket no. */ ) { char value; semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */ /* value = pcicGet (sock, PCIC_INTCTL);*/ value = AT91C_ID_PIOB ; semGive (&pcicMuteSem); /* mutual execlusion stop */ return (value & PCIC_IRQ_MASK); }/********************************************************************************* pcicIrqSet - Set IRQ level of the socket.** This routine sets IRQ level of the socket.** RETURNS: OK, or ERROR if the IRQ level is greater than 15.*/LOCAL STATUS pcicIrqSet ( int sock, /* socket no. */ int irq /* IRQ level for the PC card */ ) {#if 0 char value; if (irq > 15) return (ERROR); semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */ value = pcicGet (sock, PCIC_INTCTL); value = (value & ~PCIC_IRQ_MASK) | irq; pcicSet (sock, PCIC_INTCTL, value); semGive (&pcicMuteSem); /* mutual execlusion stop */#endif return (OK); }/********************************************************************************* pcicReset - Reset a card in the socket.** This routine reset a card in the socket.** RETURNS: OK (always).*/LOCAL STATUS pcicReset ( int sock /* socket no. */ ) { int count=1000; semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */#if 0 /* Turn off interrupts, select memory-only interface */ pcicBclr (sock, PCIC_INTCTL, PCIC_PC_IOCARD | PCIC_IRQ_MASK); /* Turn off all IO and Memory windows */ pcicBclr (sock, PCIC_ADDRWIN, PCIC_ENA_ALL);#endif AT91_SYS->PIOB_SODR = AT91C_CF_PB5_RESET; /* set it */ semGive (&pcicMuteSem); /* mutual execlusion stop */ if( AT91F_CF_Card_OK()!=1) return (ERROR); else return OK; }/********************************************************************************* pcicIowinGet - Get the IO window of the socket.** This routine gets the IO window of the socket.** RETURNS: OK, or ERROR if the window number is greater than max windows.*/LOCAL STATUS pcicIowinGet ( int sock, /* socket no. */ PCMCIA_IOWIN *io /* io window structure to get */ ) { char window = io->window; char ioctl; char addr; if (window >= PCIC_IO_WINDOWS) return (ERROR); semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */#if 0 ioctl = pcicGet (sock, PCIC_IOCTL); addr = pcicGet (sock, PCIC_ADDRWIN); io->start = pcicGet2 (sock, PCIC_IO(window)+PCIC_W_START); io->stop = pcicGet2 (sock, PCIC_IO(window)+PCIC_W_STOP); io->extraws = (ioctl & PCIC_IOCTL_WAIT(window)) ? 1 : 0; io->flags = (addr & PCIC_ENA_IO(window)) ? MAP_ACTIVE : 0; io->flags |= (ioctl & PCIC_IOCTL_0WS(window)) ? MAP_0WS : 0; io->flags |= (ioctl & PCIC_IOCTL_CS16(window)) ? MAP_CS16 : 0; io->flags |= (ioctl & PCIC_IOCTL_16BIT(window)) ? MAP_16BIT : 0;#endif/* io->start = (int) at91_pcmcia_socket[sock].virt_io ; io->stop = io->start +PAGE_SIZE - 1; io->flags = at91_pcmcia_socket[sock].cs_state.flags; */ /* io->extraws = (io->flags&MAP_USE_WAIT) ? 1 : 0;*/ semGive (&pcicMuteSem); /* mutual execlusion stop */ return (OK); }/********************************************************************************* pcicIowinSet - Set the IO window of the socket.** This routine sets the IO window of the socket.** RETURNS: OK, or ERROR if there is an error.*/LOCAL STATUS pcicIowinSet ( int sock, /* socket no. */ PCMCIA_IOWIN *io /* io window structure to set */ ) { char window = io->window; char ioctl; if ((window >= PCIC_IO_WINDOWS) || (io->start > 0xffff) || (io->stop > 0xffff) || (io->stop < io->start)) return (ERROR); semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */#if 0 ioctl = pcicGet (sock, PCIC_IOCTL) & ~PCIC_IOCTL_MASK(window); /* Turn off the window before changing anything */ if (pcicGet (sock, PCIC_ADDRWIN) & PCIC_ENA_IO(window)) pcicBclr (sock, PCIC_ADDRWIN, PCIC_ENA_IO(window)); pcicSet2 (sock, PCIC_IO(window)+PCIC_W_START, io->start); pcicSet2 (sock, PCIC_IO(window)+PCIC_W_STOP, io->stop); if (io->extraws) ioctl |= PCIC_IOCTL_WAIT(window); if (io->flags & MAP_0WS) ioctl |= PCIC_IOCTL_0WS(window); if (io->flags & MAP_CS16) ioctl |= PCIC_IOCTL_CS16(window); if (io->flags & MAP_16BIT) ioctl |= PCIC_IOCTL_16BIT(window); pcicSet (sock, PCIC_IOCTL, ioctl); /* Turn on the window if necessary */ if (io->flags & MAP_ACTIVE) pcicBset (sock, PCIC_ADDRWIN, PCIC_ENA_IO(window));#endif semGive (&pcicMuteSem); /* mutual execlusion stop */ return (OK); }/********************************************************************************* pcicMemwinGet - Get the Memory window of the socket.** This routine gets the Memory window of the socket.** RETURNS: OK, or ERROR if the window number is greater than max windows.*/LOCAL STATUS pcicMemwinGet ( int sock, /* socket no. */ PCMCIA_MEMWIN *mem /* memory window structure to get */ ) { char window = mem->window; char addr; short base; short value; if (window >= PCIC_MEM_WINDOWS) return (ERROR); semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */#if 0 addr = pcicGet (sock, PCIC_ADDRWIN); base = PCIC_MEM(window); mem->flags = (addr & PCIC_ENA_MEM(window)) ? MAP_ACTIVE : 0; value = pcicGet2 (sock, base+PCIC_W_START); mem->flags |= (value & PCIC_MEM_16BIT) ? MAP_16BIT : 0; mem->flags |= (value & PCIC_MEM_0WS) ? MAP_0WS : 0; mem->start = ((long)(value & 0x0fff) << 12); value = pcicGet2 (sock, base+PCIC_W_STOP); mem->extraws = (value & PCIC_MEM_WS0) ? 1 : 0; mem->extraws += (value & PCIC_MEM_WS1) ? 2 : 0; mem->stop = ((long)(value & 0x0fff) << 12) + 0x0fff; value = pcicGet2 (sock, base+PCIC_W_OFF); mem->flags |= (value & PCIC_MEM_WRPROT) ? MAP_WRPROT : 0; mem->flags |= (value & PCIC_MEM_REG) ? MAP_ATTRIB : 0; mem->cardstart = ((long)(value & 0x3fff) << 12) + mem->start; mem->cardstart &= 0x3ffffff;#endif semGive (&pcicMuteSem); /* mutual execlusion stop */ return (OK); }/********************************************************************************* pcicMemwinSet - Set the Memory window of the socket.** This routine sets the Memory window of the socket.** RETURNS: OK, or ERROR if there is an error.*/LOCAL STATUS pcicMemwinSet ( int sock, /* socket no. */ PCMCIA_MEMWIN *mem /* memory window structure to set */ ) { char window = mem->window; short base; short value; /* if ((window >= PCIC_MEM_WINDOWS) || (mem->cardstart > 0x3ffffff) || (mem->start > 0xffffff) || (mem->stop > 0xffffff) || (mem->start > mem->stop) || (mem->extraws > 3)) return (ERROR);*/ semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */#if 0 base = PCIC_MEM(window); /* Turn off the window before changing anything */ if (pcicGet (sock, PCIC_ADDRWIN) & PCIC_ENA_MEM(window)) pcicBclr (sock, PCIC_ADDRWIN, PCIC_ENA_MEM(window)); value = mem->start >> 12; if (mem->flags & MAP_16BIT) { value |= PCIC_MEM_16BIT; pcicBset (sock, PCIC_ADDRWIN, PCIC_ENA_MEMCS16); } if (mem->flags & MAP_0WS) value |= PCIC_MEM_0WS; pcicSet2 (sock, base+PCIC_W_START, value); value = mem->stop >> 12; if (mem->extraws & 1) value |= PCIC_MEM_WS0; if (mem->extraws & 2) value |= PCIC_MEM_WS1; pcicSet2 (sock, base+PCIC_W_STOP, value); value = ((mem->cardstart - mem->start) >> 12) & 0x3fff; if (mem->flags & MAP_WRPROT) value |= PCIC_MEM_WRPROT; if (mem->flags & MAP_ATTRIB) value |= PCIC_MEM_REG; pcicSet2 (sock, base+PCIC_W_OFF, value); /* Turn on the window if necessary */ if (mem->flags & MAP_ACTIVE) pcicBset (sock, PCIC_ADDRWIN, PCIC_ENA_MEM(window));#endif semGive (&pcicMuteSem); /* mutual execlusion stop */ return (OK); }#if 0/********************************************************************************* pcicGet - Get a value from the register.** This routine gets a value from the register.** RETURNS: A value of the register.*/LOCAL int pcicGet ( int sock, /* socket no. */ int reg /* register no. */ ) { short port = PCIC_PORT (sock); char offset = PCIC_REG (sock, reg); sysOutByte (port, offset); return (sysInByte (port+1)); }/********************************************************************************* pcicSet - Set a value into the register.** This routine sets a value into the register.** RETURNS: N/A*/LOCAL void pcicSet ( int sock, /* socket no. */ int reg, /* register no. */ char value /* value to set */ ) { short port = PCIC_PORT (sock); char offset = PCIC_REG (sock, reg); sysOutByte (port, offset); sysOutByte (port+1, value); }/********************************************************************************* pcicBset - Set specified bits in the register.** This routine sets specified bits in the register.** RETURNS: N/A*/LOCAL void pcicBset ( int sock, /* socket no. */ int reg, /* register no. */ char mask /* bits to set */ ) { char value = pcicGet (sock, reg); value |= mask; pcicSet (sock, reg, value); }/********************************************************************************* pcicBclr - Clear specified bits in the register.** This routine clears specified bits in the register.** RETURNS: N/A*/LOCAL void pcicBclr ( int sock, /* socket no. */ int reg, /* register no. */ char mask /* bits to clear */ ) { char value = pcicGet (sock, reg); value &= ~mask; pcicSet (sock, reg, value); }/********************************************************************************* pcicGet2 - Get a value from the consecutive registers.** This routine gets a value from the consecutive registers.** RETURNS: a value of the register*/LOCAL int pcicGet2 ( int sock, /* socket no. */ int reg /* register no. */ ) { short a = pcicGet (sock, reg); short b = pcicGet (sock, reg+1); return (a + (b<<8)); }/********************************************************************************* pcicSet2 - Set a value into the consecutive registers.** This routine sets a value into the consecutive registers.** RETURNS: N/A*/LOCAL void pcicSet2 ( int sock, /* socket no. */ int reg, /* register no. */ short value /* value to set */ ) { pcicSet (sock, reg, value & 0xff); pcicSet (sock, reg+1, value >> 8); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -