@ -57,6 +57,20 @@ static void spi_reset(struct omap3_spi_slave *ds)
writel ( OMAP3_MCSPI_WAKEUPENABLE_WKEN , & ds - > regs - > wakeupenable ) ;
}
static void omap3_spi_write_chconf ( struct omap3_spi_slave * ds , int val )
{
writel ( val , & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
/* Flash post writes to make immediate effect */
readl ( & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
}
static void omap3_spi_set_enable ( struct omap3_spi_slave * ds , int enable )
{
writel ( enable , & ds - > regs - > channel [ ds - > slave . cs ] . chctrl ) ;
/* Flash post writes to make immediate effect */
readl ( & ds - > regs - > channel [ ds - > slave . cs ] . chctrl ) ;
}
void spi_init ( )
{
/* do nothing */
@ -212,7 +226,7 @@ int spi_claim_bus(struct spi_slave *slave)
/* Transmit & receive mode */
conf & = ~ OMAP3_MCSPI_CHCONF_TRM_MASK ;
writel ( conf , & ds - > regs - > channel [ ds - > slave . cs ] . ch conf) ;
omap3_spi_write_chconf ( ds , conf ) ;
return 0 ;
}
@ -233,14 +247,13 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
int timeout = SPI_WAIT_TIMEOUT ;
int chconf = readl ( & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
if ( flags & SPI_XFER_BEGIN )
writel ( OMAP3_MCSPI_CHCTRL_EN ,
& ds - > regs - > channel [ ds - > slave . cs ] . chctrl ) ;
/* Enable the channel */
omap3_spi_set_enable ( ds , OMAP3_MCSPI_CHCTRL_EN ) ;
chconf & = ~ OMAP3_MCSPI_CHCONF_TRM_MASK ;
chconf | = OMAP3_MCSPI_CHCONF_TRM_TX_ONLY ;
chconf | = OMAP3_MCSPI_CHCONF_FORCE ;
writel ( chconf , & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
omap3_spi_write_chconf ( ds , chconf ) ;
for ( i = 0 ; i < len ; i + + ) {
/* wait till TX register is empty (TXS == 1) */
@ -256,15 +269,17 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
writel ( txp [ i ] , & ds - > regs - > channel [ ds - > slave . cs ] . tx ) ;
}
if ( flags & SPI_XFER_END ) {
/* wait to finish of transfer */
while ( ! ( readl ( & ds - > regs - > channel [ ds - > slave . cs ] . chstat ) &
OMAP3_MCSPI_CHSTAT_EOT ) ) ;
chconf & = ~ OMAP3_MCSPI_CHCONF_FORCE ;
writel ( chconf , & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
/* Disable the channel otherwise the next immediate RX will get affected */
omap3_spi_set_enable ( ds , OMAP3_MCSPI_CHCTRL_DIS ) ;
writel ( 0 , & ds - > regs - > channel [ ds - > slave . cs ] . chctrl ) ;
if ( flags & SPI_XFER_END ) {
chconf & = ~ OMAP3_MCSPI_CHCONF_FORCE ;
omap3_spi_write_chconf ( ds , chconf ) ;
}
return 0 ;
}
@ -277,14 +292,13 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
int timeout = SPI_WAIT_TIMEOUT ;
int chconf = readl ( & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
if ( flags & SPI_XFER_BEGIN )
writel ( OMAP3_MCSPI_CHCTRL_EN ,
& ds - > regs - > channel [ ds - > slave . cs ] . chctrl ) ;
/* Enable the channel */
omap3_spi_set_enable ( ds , OMAP3_MCSPI_CHCTRL_EN ) ;
chconf & = ~ OMAP3_MCSPI_CHCONF_TRM_MASK ;
chconf | = OMAP3_MCSPI_CHCONF_TRM_RX_ONLY ;
chconf | = OMAP3_MCSPI_CHCONF_FORCE ;
writel ( chconf , & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
omap3_spi_write_chconf ( ds , chconf ) ;
writel ( 0 , & ds - > regs - > channel [ ds - > slave . cs ] . tx ) ;
@ -298,15 +312,18 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
return - 1 ;
}
}
/* Disable the channel to prevent furher receiving */
if ( i = = ( len - 1 ) )
omap3_spi_set_enable ( ds , OMAP3_MCSPI_CHCTRL_DIS ) ;
/* Read the data */
rxp [ i ] = readl ( & ds - > regs - > channel [ ds - > slave . cs ] . rx ) ;
}
if ( flags & SPI_XFER_END ) {
chconf & = ~ OMAP3_MCSPI_CHCONF_FORCE ;
writel ( chconf , & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
writel ( 0 , & ds - > regs - > channel [ ds - > slave . cs ] . chctrl ) ;
omap3_spi_write_chconf ( ds , chconf ) ;
}
return 0 ;
@ -323,14 +340,12 @@ int omap3_spi_txrx(struct spi_slave *slave,
int i = 0 ;
/*Enable SPI channel*/
if ( flags & SPI_XFER_BEGIN )
writel ( OMAP3_MCSPI_CHCTRL_EN ,
& ds - > regs - > channel [ ds - > slave . cs ] . chctrl ) ;
omap3_spi_set_enable ( ds , OMAP3_MCSPI_CHCTRL_EN ) ;
/*set TRANSMIT-RECEIVE Mode*/
chconf & = ~ OMAP3_MCSPI_CHCONF_TRM_MASK ;
chconf | = OMAP3_MCSPI_CHCONF_FORCE ;
writel ( chconf , & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
omap3_spi_write_chconf ( ds , chconf ) ;
/*Shift in and out 1 byte at time*/
for ( i = 0 ; i < len ; i + + ) {
@ -359,13 +374,13 @@ int omap3_spi_txrx(struct spi_slave *slave,
/* Read the data */
rxp [ i ] = readl ( & ds - > regs - > channel [ ds - > slave . cs ] . rx ) ;
}
/* Disable the channel */
omap3_spi_set_enable ( ds , OMAP3_MCSPI_CHCTRL_DIS ) ;
/*if transfer must be terminated disable the channel*/
if ( flags & SPI_XFER_END ) {
chconf & = ~ OMAP3_MCSPI_CHCONF_FORCE ;
writel ( chconf , & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
writel ( 0 , & ds - > regs - > channel [ ds - > slave . cs ] . chctrl ) ;
omap3_spi_write_chconf ( ds , chconf ) ;
}
return 0 ;
@ -389,17 +404,14 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
int chconf = readl ( & ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
if ( flags & SPI_XFER_BEGIN ) {
writel ( OMAP3_MCSPI_CHCTRL_EN ,
& ds - > regs - > channel [ ds - > slave . cs ] . chctrl ) ;
omap3_spi_set_enable ( ds , OMAP3_MCSPI_CHCTRL_EN ) ;
chconf | = OMAP3_MCSPI_CHCONF_FORCE ;
writel ( chconf ,
& ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
omap3_spi_write_chconf ( ds , chconf ) ;
}
if ( flags & SPI_XFER_END ) {
chconf & = ~ OMAP3_MCSPI_CHCONF_FORCE ;
writel ( chconf ,
& ds - > regs - > channel [ ds - > slave . cs ] . chconf ) ;
writel ( 0 , & ds - > regs - > channel [ ds - > slave . cs ] . chctrl ) ;
omap3_spi_write_chconf ( ds , chconf ) ;
omap3_spi_set_enable ( ds , OMAP3_MCSPI_CHCTRL_DIS ) ;
}
ret = 0 ;
} else {