📄 ssp.c
字号:
iRet = SSP_Write_I2SCodec( Handle, Addr, Value ); break; } case SERIAL_FLASH: { break; } default: { return(-1); } } return iRet;}static void SetSSPtoPS2(void){ unsigned int uiRegTemp; if( gSSPmode == SSP_MODE_PS2 ) { return; } /* * Disable the SSP, disable interrupts */ outl( 0, SSPCR1 ); /* * It takes almost a millisecond for a key to come in so * make sure we have completed all transactions. */ mdelay(1); // // Set EGPIO7 to disable EEPROM device on EDB9301, EDB9302, EDB9307, // EDB9312, and EDB9315. // uiRegTemp = inl(GPIO_PADDR); outl( uiRegTemp | 0x80, GPIO_PADDR ); uiRegTemp = inl(GPIO_PADR); outl( uiRegTemp | 0x80, GPIO_PADR ); /* * Disable SFRM1 to I2S codec by setting EGPIO8 (port B, bit 0). * The EDB9307 and EDB9315 boards need this. */#if defined(CONFIG_ARCH_EDB9307) || defined(CONFIG_ARCH_EDB9315) uiRegTemp = inl(GPIO_PBDDR) | 0x01; outl( uiRegTemp, GPIO_PBDDR ); uiRegTemp = inl(GPIO_PBDR) | 0x01; outl( uiRegTemp, GPIO_PBDR ); uiRegTemp = inl(GPIO_PBDR);#endif /* * Disable SFRM1 to I2S codec I2S by setting EGPIO6 (port A, bit 6). * The EDB9301 and EDB9302 boards need this. */#if defined(CONFIG_ARCH_EDB9301) || defined(CONFIG_ARCH_EDB9302) uiRegTemp = inl(GPIO_PADDR); outl( uiRegTemp | 0x40, GPIO_PADDR ); uiRegTemp = inl(GPIO_PADR); outl( uiRegTemp | 0x40, GPIO_PADR ); uiRegTemp = inl(GPIO_PADR);#endif /* * Still haven't enabled the keyboard. So anything in * the rx fifo is garbage. Time to take out the trash. */ while( inl(SSPSR) & SSPSR_RNE ) { uiRegTemp = inl(SSPDR); } /* * SPICR0_SPO - SCLKOUT Polarity * SPICR0_SPH - SCLKOUT Phase * Motorola format, 11 bit, one start, 8 data, one bit for * parity, one stop bit. */ outl( (SSPCR0_FRF_MOTOROLA | SSPCR0_SPH | SSPCR0_SPO | SSPCR0_DSS_11BIT), SSPCR0 ); /* * Configure the device as a slave, Clear FIFO overrun interrupts, * enable interrupts and reset the device. */ outl( (SSPC1_MS | SSPC1_RIE | SSPC1_SOD), SSPCR1 ); outl( 0, SSPIIR ); outl( (SSPC1_MS | SSPC1_RIE | SSPC1_SOD | SSPC1_SSE), SSPCR1 ); /* * Configure EGPIO pins 12 and 14 as outputs because they are used * as buffer enables for the SPI interface to the ps2 keyboard. * Clear EGPIO pins 12 and 14, this will enable the SPI keyboard. */ uiRegTemp = inl(GPIO_PBDDR); outl( uiRegTemp | 0x50, GPIO_PBDDR ); uiRegTemp = inl(GPIO_PBDR); outl( uiRegTemp & ~0x50, GPIO_PBDR ); gSSPmode = SSP_MODE_PS2;}static void SetSSPtoI2S(void){ unsigned int uiRegTemp; if( gSSPmode == SSP_MODE_I2S ) { return; } /* * Disable recieve interrupts. */ outl( (SSPC1_MS | SSPC1_SSE), SSPCR1 ); /* * Set GPIO pins 12 and 14, this will bring the clock line low * which signals to the keyboard to buffer keystrokes. * Note that EGPIO 14 is the clock line and EGPIO 12 is data line. */ uiRegTemp = inl(GPIO_PBDR); outl( 0x50 | uiRegTemp, GPIO_PBDR ); /* * It takes almost a millisecond for an partial keystrokes to come in. * Delay to make sure we have completed all transactions. */ mdelay(1); /* * Anything we just recieved is garbage. Time to take out the trash. */ while( inl(SSPSR) & SSPSR_RNE ) { uiRegTemp = inl(SSPDR); } /* * Disable the SSP and disable interrupts */ outl( 0, SSPCR1 ); /* * Clock will be 14.7 MHz divided by 4. */ outl( 2, SSPCPSR ); /* * Configure EGPIO7 as an output and set it. This selects * I2S codec as the device on the SSP output instead of * the serial flash on EDB9312. On EDB9301, EDB9302, EDB9307, and * EDB9315 it disables EEPROM but doesn't select anything. */ uiRegTemp = inl(GPIO_PADDR); outl( uiRegTemp | 0x80, GPIO_PADDR ); uiRegTemp = inl(GPIO_PADR); outl( uiRegTemp | 0x80, GPIO_PADR ); /* * Enable SFRM1 to I2S codec by clearing EGPIO8 (port B, bit 0). * The EDB9307 and EDB9315 boards need this. */#if defined(CONFIG_ARCH_EDB9307) || defined(CONFIG_ARCH_EDB9315) uiRegTemp = inl(GPIO_PBDDR) | 0x01; outl( uiRegTemp, GPIO_PBDDR ); uiRegTemp = inl(GPIO_PBDR) & 0xfe; outl( uiRegTemp, GPIO_PBDR ); uiRegTemp = inl(GPIO_PBDR);#endif /* * Enable SFRM1 to I2S codec I2S by clearing EGPIO6 (port A, bit 6). * The EDB9301 and EDB9302 boards need this. */#if defined(CONFIG_ARCH_EDB9301) || defined(CONFIG_ARCH_EDB9302) uiRegTemp = inl(GPIO_PADDR); outl( uiRegTemp | 0x40, GPIO_PADDR ); uiRegTemp = inl(GPIO_PADR); outl( uiRegTemp & ~0x40, GPIO_PADR ); uiRegTemp = inl(GPIO_PADR);#endif /* * Motorola format, 8 bit. */ outl( (SSPCR0_SPO | SSPCR0_SPH | SSPCR0_FRF_MOTOROLA | SSPCR0_DSS_8BIT), SSPCR0 ); /* * Configure the device as master, reenable the device. */ outl( SSPC1_SSE, SSPCR1 ); gSSPmode = SSP_MODE_I2S; udelay(10);}static void SetSSPtoFLASH(void){ unsigned int uiRegTemp; if( gSSPmode == SSP_MODE_FLASH) return; /* * Disable recieve interrupts. */ outl( (SSPC1_MS | SSPC1_SSE), SSPCR1 ); /* * Set GPIO pins 12 and 14, this will bring the clock line low * which signals to the keyboard to buffer keystrokes. * Note that EGPIO 14 is the clock line and EGPIO 12 is data line. */ outl( inl(GPIO_PBDR) | 0x50, GPIO_PBDR ); /* * It takes almost a millisecond for an partial keystrokes to come in. * Delay to make sure we have completed all transactions. */ mdelay(1); /* * Anything we just recieved is garbage. Time to take out the trash. */ while( inl(SSPSR) & SSPSR_RNE ) inl(SSPDR); /* * Disable the SSP and disable interrupts */ outl( 0, SSPCR1 ); /* * Clock will be 14.7 MHz divided by 14. */ outl( 2, SSPCPSR ); /* * Configure EGPIO7 as an output and clear it. This selects * serial flash as the device on the SSP output instead of * the I2S codec and is valid for EDB9301, EDB9302, EDB9307, EDB9312, * and EDB9315. */ outl( inl(GPIO_PADDR) | 0x80, GPIO_PADDR ); outl( inl(GPIO_PADR) & ~0x80, GPIO_PADR ); /* * Disable SFRM1 to I2S codec by setting EGPIO8 (port B, bit 0). * The EDB9307 and EDB9315 boards need this. */#if defined(CONFIG_ARCH_EDB9307) || defined(CONFIG_ARCH_EDB9315) uiRegTemp = inl(GPIO_PBDDR) | 0x01; outl( uiRegTemp, GPIO_PBDDR ); uiRegTemp = inl(GPIO_PBDR) | 0x01; outl( uiRegTemp, GPIO_PBDR ); uiRegTemp = inl(GPIO_PBDR);#endif /* * Disable SFRM1 to I2S codec I2S by setting EGPIO6 (port A, bit 6). * The EDB9301 and EDB9302 boards needs this. */#if defined(CONFIG_ARCH_EDB9301) || defined(CONFIG_ARCH_EDB9302) uiRegTemp = inl(GPIO_PADDR); outl( uiRegTemp | 0x40, GPIO_PADDR ); uiRegTemp = inl(GPIO_PADR); outl( uiRegTemp | 0x40, GPIO_PADR ); uiRegTemp = inl(GPIO_PBDR);#endif /* * Motorola format, 8 bit. */ outl( ((6 << SSPCR0_SCR_SHIFT) | SSPCR0_SPO | SSPCR0_SPH | SSPCR0_FRF_MOTOROLA | SSPCR0_DSS_8BIT), SSPCR0 ); /* * Configure the device as master, reenable the device. */ outl( SSPC1_SSE, SSPCR1 ); gSSPmode = SSP_MODE_FLASH; udelay(10);}/* * CheckHandle * * If Handle is valid, returns 0. Otherwise it returns -1. */static int CheckHandle(int Handle){ int iRet; if ((Handle != KeyboardHandle) && (Handle != I2SHandle) && (Handle != FlashHandle)) { DPRINTK("OOPS! Invalid SSP Handle!\n"); return(-1); } /* * Get the SSP driver instance number from the handle. */ iRet = (((int)Handle & SSP_DEVICE_MASK) >> SSP_DEVICE_SHIFT); return iRet;}/* * ReadIntoBuffer * * Drains the SSP rx fifo into a buffer here. If we overflow this buffer * then something's wrong. */static int ReadIntoBuffer(void){ unsigned int count, index, saved_count, uiRegTemp; count = 0; index = 0; if( gSSPmode != SSP_MODE_PS2 ) { return 0; } /* * This spinlock will prevent I2S from grabbing the SSP to do a * write while we are using the SSP for PS2. * * There is a slight chance that we are in the beginning phase * of doing an I2S write but the mode flag hadn't yet switched * to I2S. If that happens we will end up waiting on I2S to * finish a write. Not great. */ spin_lock(&ssp_spinlock); while( inl(SSPSR) & SSPSR_RNE) { /* * Read in the value from the SPI controller into * the partial key buffer. */ uiKeyBuffer[count] = inl(SSPDR); if (((uiKeyBuffer[count] & 0x3fc) != 0x3e0) && ((uiKeyBuffer[count] & 0x3fc) != 0x3c0)) { /* * Set GPIO pins 12 and 14, this will bring the clock line low * which signals to the keyboard to buffer keystrokes. * Note that EGPIO 14 is the clock line and EGPIO 12 is data line. */ uiRegTemp = inl(GPIO_PBDR); outl( 0x50 | uiRegTemp, GPIO_PBDR ); outl( 0, SSPCR1 ); outl( (SSPC1_MS | SSPC1_RIE | SSPC1_SSE), SSPCR1 ); /* * Clear EGPIO pins 12 and 14, this will enable the SPI keyboard. */ uiRegTemp = inl(GPIO_PBDR); outl( uiRegTemp & ~0x50, GPIO_PBDR ); count++; break; } count++; } saved_count = count; index = 0; while (count) { // // No callback, dump data. // if (gKeyCallback) { gKeyCallback(uiKeyBuffer[index++]); } count--; } spin_unlock(&ssp_spinlock); return saved_count;}/* * SSP_Write_I2SCodec * */static int SSP_Write_I2SCodec( int Handle, unsigned int RegAddr, unsigned int RegValue){ SSPmodes_t saved_mode; DPRINTK("SSP_Write_I2SCodec\n"); spin_lock(&ssp_spinlock); /* * Save the SSP mode. Switch to I2S mode if we're not * already in I2S mode. */ saved_mode = gSSPmode; SetSSPtoI2S(); /* * Let TX fifo clear out. Poll the Transmit Fifo Empty bit. */ while( !( inl(SSPSR) & SSPSR_TFE ) ); /* * Write the data out to the tx fifo. */ outl( 0x20, SSPDR ); /* chip address for CS4228 */ outl( (RegAddr & 0xff), SSPDR ); outl( (RegValue & 0xff), SSPDR ); /* * Let TX fifo clear out. Poll the Transmit Fifo Empty bit. */ while( !( inl(SSPSR) & SSPSR_TFE ) ); /* * Delay to let stuff make it out of the SR before doing * anthing else to the SSP. It takes 6.8 uSec to do a * I2S codec register write. */ udelay(10); /* * If we were in PS2 mode, switch back to PS2 mode. * If we weren't in PS2 mode, that means we didn't compile in * the PS2 keyboard support, so no need to switch to PS2 mode. */ if( saved_mode == SSP_MODE_PS2 ) { SetSSPtoPS2(); } spin_unlock(&ssp_spinlock); /* * Return success. */ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -