projects
/
oweals
/
u-boot.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
spi: xilinx_spi: Fix to configure CPOL, CPHA mask
[oweals/u-boot.git]
/
drivers
/
spi
/
omap3_spi.c
diff --git
a/drivers/spi/omap3_spi.c
b/drivers/spi/omap3_spi.c
index e80be8eaac27741e3fa179fb228aa224f8c5ff22..85f9e85fd4b92ff6af8d48bf8bb1d452ac68256e 100644
(file)
--- a/
drivers/spi/omap3_spi.c
+++ b/
drivers/spi/omap3_spi.c
@@
-20,8
+20,7
@@
#include <asm/io.h>
#include "omap3_spi.h"
#include <asm/io.h>
#include "omap3_spi.h"
-#define WORD_LEN 8
-#define SPI_WAIT_TIMEOUT 3000000;
+#define SPI_WAIT_TIMEOUT 10
static void spi_reset(struct omap3_spi_slave *ds)
{
static void spi_reset(struct omap3_spi_slave *ds)
{
@@
-185,7
+184,7
@@
int spi_claim_bus(struct spi_slave *slave)
/* wordlength */
conf &= ~OMAP3_MCSPI_CHCONF_WL_MASK;
/* wordlength */
conf &= ~OMAP3_MCSPI_CHCONF_WL_MASK;
- conf |= (
WORD_LEN
- 1) << 7;
+ conf |= (
ds->slave.wordlen
- 1) << 7;
/* set chipselect polarity; manage with FORCE */
if (!(ds->mode & SPI_CS_HIGH))
/* set chipselect polarity; manage with FORCE */
if (!(ds->mode & SPI_CS_HIGH))
@@
-223,39
+222,48
@@
void spi_release_bus(struct spi_slave *slave)
spi_reset(ds);
}
spi_reset(ds);
}
-int omap3_spi_write(struct spi_slave *slave, unsigned int len, const
u8
*txp,
+int omap3_spi_write(struct spi_slave *slave, unsigned int len, const
void
*txp,
unsigned long flags)
{
struct omap3_spi_slave *ds = to_omap3_spi(slave);
int i;
unsigned long flags)
{
struct omap3_spi_slave *ds = to_omap3_spi(slave);
int i;
-
int timeout = SPI_WAIT_TIMEOUT
;
+
ulong start
;
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
/* Enable the channel */
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
/* Enable the channel */
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
- chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
+ chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
+ chconf |= (ds->slave.wordlen - 1) << 7;
chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY;
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
omap3_spi_write_chconf(ds,chconf);
for (i = 0; i < len; i++) {
/* wait till TX register is empty (TXS == 1) */
chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY;
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
omap3_spi_write_chconf(ds,chconf);
for (i = 0; i < len; i++) {
/* wait till TX register is empty (TXS == 1) */
+ start = get_timer(0);
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
OMAP3_MCSPI_CHSTAT_TXS)) {
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
OMAP3_MCSPI_CHSTAT_TXS)) {
- if (
--timeout <= 0
) {
+ if (
get_timer(start) > SPI_WAIT_TIMEOUT
) {
printf("SPI TXS timed out, status=0x%08x\n",
readl(&ds->regs->channel[ds->slave.cs].chstat));
return -1;
}
}
/* Write the data */
printf("SPI TXS timed out, status=0x%08x\n",
readl(&ds->regs->channel[ds->slave.cs].chstat));
return -1;
}
}
/* Write the data */
- writel(txp[i], &ds->regs->channel[ds->slave.cs].tx);
+ unsigned int *tx = &ds->regs->channel[ds->slave.cs].tx;
+ if (ds->slave.wordlen > 16)
+ writel(((u32 *)txp)[i], tx);
+ else if (ds->slave.wordlen > 8)
+ writel(((u16 *)txp)[i], tx);
+ else
+ writel(((u8 *)txp)[i], tx);
}
/* wait to finish of transfer */
}
/* wait to finish of transfer */
- while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
- OMAP3_MCSPI_CHSTAT_EOT));
+ while ((readl(&ds->regs->channel[ds->slave.cs].chstat) &
+ (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) !=
+ (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS));
/* Disable the channel otherwise the next immediate RX will get affected */
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
/* Disable the channel otherwise the next immediate RX will get affected */
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
@@
-268,18
+276,19
@@
int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
return 0;
}
return 0;
}
-int omap3_spi_read(struct spi_slave *slave, unsigned int len,
u8
*rxp,
+int omap3_spi_read(struct spi_slave *slave, unsigned int len,
void
*rxp,
unsigned long flags)
{
struct omap3_spi_slave *ds = to_omap3_spi(slave);
int i;
unsigned long flags)
{
struct omap3_spi_slave *ds = to_omap3_spi(slave);
int i;
-
int timeout = SPI_WAIT_TIMEOUT
;
+
ulong start
;
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
/* Enable the channel */
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
/* Enable the channel */
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
- chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
+ chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
+ chconf |= (ds->slave.wordlen - 1) << 7;
chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
omap3_spi_write_chconf(ds,chconf);
chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
omap3_spi_write_chconf(ds,chconf);
@@
-287,10
+296,11
@@
int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
writel(0, &ds->regs->channel[ds->slave.cs].tx);
for (i = 0; i < len; i++) {
writel(0, &ds->regs->channel[ds->slave.cs].tx);
for (i = 0; i < len; i++) {
+ start = get_timer(0);
/* Wait till RX register contains data (RXS == 1) */
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
OMAP3_MCSPI_CHSTAT_RXS)) {
/* Wait till RX register contains data (RXS == 1) */
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
OMAP3_MCSPI_CHSTAT_RXS)) {
- if (
--timeout <= 0
) {
+ if (
get_timer(start) > SPI_WAIT_TIMEOUT
) {
printf("SPI RXS timed out, status=0x%08x\n",
readl(&ds->regs->channel[ds->slave.cs].chstat));
return -1;
printf("SPI RXS timed out, status=0x%08x\n",
readl(&ds->regs->channel[ds->slave.cs].chstat));
return -1;
@@
-302,7
+312,13
@@
int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
/* Read the data */
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
/* Read the data */
- rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
+ unsigned int *rx = &ds->regs->channel[ds->slave.cs].rx;
+ if (ds->slave.wordlen > 16)
+ ((u32 *)rxp)[i] = readl(rx);
+ else if (ds->slave.wordlen > 8)
+ ((u16 *)rxp)[i] = (u16)readl(rx);
+ else
+ ((u8 *)rxp)[i] = (u8)readl(rx);
}
if (flags & SPI_XFER_END) {
}
if (flags & SPI_XFER_END) {
@@
-314,11
+330,11
@@
int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
}
/*McSPI Transmit Receive Mode*/
}
/*McSPI Transmit Receive Mode*/
-int omap3_spi_txrx(struct spi_slave *slave,
-
unsigned int len, const u8 *txp, u8
*rxp, unsigned long flags)
+int omap3_spi_txrx(struct spi_slave *slave,
unsigned int len,
+
const void *txp, void
*rxp, unsigned long flags)
{
struct omap3_spi_slave *ds = to_omap3_spi(slave);
{
struct omap3_spi_slave *ds = to_omap3_spi(slave);
-
int timeout = SPI_WAIT_TIMEOUT
;
+
ulong start
;
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
int irqstatus = readl(&ds->regs->irqstatus);
int i=0;
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
int irqstatus = readl(&ds->regs->irqstatus);
int i=0;
@@
-327,7
+343,8
@@
int omap3_spi_txrx(struct spi_slave *slave,
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
/*set TRANSMIT-RECEIVE Mode*/
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
/*set TRANSMIT-RECEIVE Mode*/
- chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
+ chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
+ chconf |= (ds->slave.wordlen - 1) << 7;
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
omap3_spi_write_chconf(ds,chconf);
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
omap3_spi_write_chconf(ds,chconf);
@@
-335,28
+352,42
@@
int omap3_spi_txrx(struct spi_slave *slave,
for (i=0; i < len; i++){
/* Write: wait for TX empty (TXS == 1)*/
irqstatus |= (1<< (4*(ds->slave.bus)));
for (i=0; i < len; i++){
/* Write: wait for TX empty (TXS == 1)*/
irqstatus |= (1<< (4*(ds->slave.bus)));
+ start = get_timer(0);
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
OMAP3_MCSPI_CHSTAT_TXS)) {
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
OMAP3_MCSPI_CHSTAT_TXS)) {
- if (
--timeout <= 0
) {
+ if (
get_timer(start) > SPI_WAIT_TIMEOUT
) {
printf("SPI TXS timed out, status=0x%08x\n",
readl(&ds->regs->channel[ds->slave.cs].chstat));
return -1;
}
}
/* Write the data */
printf("SPI TXS timed out, status=0x%08x\n",
readl(&ds->regs->channel[ds->slave.cs].chstat));
return -1;
}
}
/* Write the data */
- writel(txp[i], &ds->regs->channel[ds->slave.cs].tx);
+ unsigned int *tx = &ds->regs->channel[ds->slave.cs].tx;
+ if (ds->slave.wordlen > 16)
+ writel(((u32 *)txp)[i], tx);
+ else if (ds->slave.wordlen > 8)
+ writel(((u16 *)txp)[i], tx);
+ else
+ writel(((u8 *)txp)[i], tx);
/*Read: wait for RX containing data (RXS == 1)*/
/*Read: wait for RX containing data (RXS == 1)*/
+ start = get_timer(0);
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
OMAP3_MCSPI_CHSTAT_RXS)) {
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
OMAP3_MCSPI_CHSTAT_RXS)) {
- if (
--timeout <= 0
) {
+ if (
get_timer(start) > SPI_WAIT_TIMEOUT
) {
printf("SPI RXS timed out, status=0x%08x\n",
readl(&ds->regs->channel[ds->slave.cs].chstat));
return -1;
}
}
/* Read the data */
printf("SPI RXS timed out, status=0x%08x\n",
readl(&ds->regs->channel[ds->slave.cs].chstat));
return -1;
}
}
/* Read the data */
- rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
+ unsigned int *rx = &ds->regs->channel[ds->slave.cs].rx;
+ if (ds->slave.wordlen > 16)
+ ((u32 *)rxp)[i] = readl(rx);
+ else if (ds->slave.wordlen > 8)
+ ((u16 *)rxp)[i] = (u16)readl(rx);
+ else
+ ((u8 *)rxp)[i] = (u8)readl(rx);
}
/* Disable the channel */
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
}
/* Disable the channel */
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
@@
-375,14
+406,17
@@
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
{
struct omap3_spi_slave *ds = to_omap3_spi(slave);
unsigned int len;
{
struct omap3_spi_slave *ds = to_omap3_spi(slave);
unsigned int len;
- const u8 *txp = dout;
- u8 *rxp = din;
int ret = -1;
int ret = -1;
- if (bitlen % 8)
+ if (ds->slave.wordlen < 4 || ds->slave.wordlen > 32) {
+ printf("omap3_spi: invalid wordlen %d\n", ds->slave.wordlen);
+ return -1;
+ }
+
+ if (bitlen % ds->slave.wordlen)
return -1;
return -1;
- len = bitlen /
8
;
+ len = bitlen /
ds->slave.wordlen
;
if (bitlen == 0) { /* only change CS */
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
if (bitlen == 0) { /* only change CS */
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
@@
-400,11
+434,11
@@
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
ret = 0;
} else {
if (dout != NULL && din != NULL)
ret = 0;
} else {
if (dout != NULL && din != NULL)
- ret = omap3_spi_txrx(slave, len,
txp, rxp
, flags);
+ ret = omap3_spi_txrx(slave, len,
dout, din
, flags);
else if (dout != NULL)
else if (dout != NULL)
- ret = omap3_spi_write(slave, len,
txp
, flags);
+ ret = omap3_spi_write(slave, len,
dout
, flags);
else if (din != NULL)
else if (din != NULL)
- ret = omap3_spi_read(slave, len,
rxp
, flags);
+ ret = omap3_spi_read(slave, len,
din
, flags);
}
return ret;
}
}
return ret;
}