⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssp.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 2 页
字号:
			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 + -