some more fixes to the SPI controller driver

SVN-Revision: 15146
This commit is contained in:
Florian Fainelli 2009-04-08 08:52:57 +00:00
parent 31a146b56d
commit 14832d3c23
2 changed files with 31 additions and 29 deletions

View file

@ -36,7 +36,7 @@
#include <bcm63xx_dev_spi.h> #include <bcm63xx_dev_spi.h>
#define PFX KBUILD_MODNAME #define PFX KBUILD_MODNAME
#define DRV_VER "0.1.1" #define DRV_VER "0.1.2"
struct bcm63xx_spi { struct bcm63xx_spi {
/* bitbang has to be first */ /* bitbang has to be first */
@ -62,15 +62,16 @@ struct bcm63xx_spi {
static void bcm63xx_spi_chipselect(struct spi_device *spi, int is_on) static void bcm63xx_spi_chipselect(struct spi_device *spi, int is_on)
{ {
struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
u16 val; u16 val;
val = bcm_spi_readw(SPI_CMD); val = bcm_spi_readw(bs->regs, SPI_CMD);
if (is_on == BITBANG_CS_INACTIVE) if (is_on == BITBANG_CS_INACTIVE)
val |= SPI_CMD_NOOP; val |= SPI_CMD_NOOP;
else if (is_on == BITBANG_CS_ACTIVE) else if (is_on == BITBANG_CS_ACTIVE)
val |= (1 << spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT); val |= (1 << spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
bcm_spi_writew(val, SPI_CMD); bcm_spi_writew(val, bs->regs, SPI_CMD);
} }
static int bcm63xx_spi_setup_transfer(struct spi_device *spi, static int bcm63xx_spi_setup_transfer(struct spi_device *spi,
@ -125,7 +126,7 @@ static int bcm63xx_spi_setup_transfer(struct spi_device *spi,
break; break;
} }
bcm_spi_writeb(clk_cfg, SPI_CLK_CFG); bcm_spi_writeb(clk_cfg, bs->regs, SPI_CLK_CFG);
dev_dbg(&spi->dev, "Setting clock register to %d (hz %d, cmd %02x)\n", dev_dbg(&spi->dev, "Setting clock register to %d (hz %d, cmd %02x)\n",
div, hz, clk_cfg); div, hz, clk_cfg);
@ -172,14 +173,14 @@ static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)
u8 tail; u8 tail;
/* Fill the Tx FIFO with as many bytes as possible */ /* Fill the Tx FIFO with as many bytes as possible */
tail = bcm_spi_readb(SPI_MSG_TAIL); tail = bcm_spi_readb(bs->regs, SPI_MSG_TAIL);
while ((tail < bs->fifo_size) && (bs->remaining_bytes > 0)) { while ((tail < bs->fifo_size) && (bs->remaining_bytes > 0)) {
if (bs->tx_ptr) if (bs->tx_ptr)
bcm_spi_writeb(*bs->tx_ptr++, SPI_MSG_DATA); bcm_spi_writeb(*bs->tx_ptr++, bs->regs, SPI_MSG_DATA);
else else
bcm_spi_writeb(0, SPI_MSG_DATA); bcm_spi_writeb(0, bs->regs, SPI_MSG_DATA);
bs->remaining_bytes--; bs->remaining_bytes--;
tail = bcm_spi_readb(SPI_MSG_TAIL); tail = bcm_spi_readb(bs->regs, SPI_MSG_TAIL);
} }
} }
@ -202,24 +203,24 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
/* Enable the command done interrupt which /* Enable the command done interrupt which
* we use to determine completion of a command */ * we use to determine completion of a command */
bcm_writeb(SPI_INTR_CMD_DONE, SPI_INT_MASK); bcm_spi_writeb(SPI_INTR_CMD_DONE, bs->regs, SPI_INT_MASK);
/* Fill in the Message control register */ /* Fill in the Message control register */
msg_ctl = bcm_spi_readb(SPI_MSG_CTL); msg_ctl = bcm_spi_readb(bs->regs, SPI_MSG_CTL);
msg_ctl |= (t->len << SPI_BYTE_CNT_SHIFT); msg_ctl |= (t->len << SPI_BYTE_CNT_SHIFT);
msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT); msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT);
bcm_spi_writeb(msg_ctl, SPI_MSG_CTL); bcm_spi_writeb(msg_ctl, bs->regs, SPI_MSG_CTL);
/* Issue the transfer */ /* Issue the transfer */
cmd = bcm_spi_readb(SPI_CMD); cmd = bcm_spi_readb(bs->regs, SPI_CMD);
cmd |= SPI_CMD_START_IMMEDIATE; cmd |= SPI_CMD_START_IMMEDIATE;
cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
bcm_spi_writeb(cmd, SPI_CMD); bcm_spi_writeb(cmd, bs->regs, SPI_CMD);
wait_for_completion(&bs->done); wait_for_completion(&bs->done);
/* Disable the CMD_DONE interrupt */ /* Disable the CMD_DONE interrupt */
bcm_spi_writeb(~(SPI_INTR_CMD_DONE), SPI_INT_MASK); bcm_spi_writeb(~(SPI_INTR_CMD_DONE), bs->regs, SPI_INT_MASK);
return t->len - bs->remaining_bytes; return t->len - bs->remaining_bytes;
} }
@ -235,23 +236,23 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
u16 cmd; u16 cmd;
/* Read interupts and clear them immediately */ /* Read interupts and clear them immediately */
intr = bcm_spi_readb(SPI_INT_STATUS); intr = bcm_spi_readb(bs->regs, SPI_INT_STATUS);
bcm_writeb(SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); bcm_spi_writeb(SPI_INTR_CLEAR_ALL, bs->regs, SPI_INT_STATUS);
/* A tansfer completed */ /* A tansfer completed */
if (intr & SPI_INTR_CMD_DONE) { if (intr & SPI_INTR_CMD_DONE) {
u8 rx_empty; u8 rx_empty;
rx_empty = bcm_spi_readb(SPI_ST); rx_empty = bcm_spi_readb(bs->regs, SPI_ST);
/* Read out all the data */ /* Read out all the data */
while ((rx_empty & SPI_RX_EMPTY) == 0) { while ((rx_empty & SPI_RX_EMPTY) == 0) {
u8 data; u8 data;
data = bcm_spi_readb(SPI_RX_DATA); data = bcm_spi_readb(bs->regs, SPI_RX_DATA);
if (bs->rx_ptr) if (bs->rx_ptr)
*bs->rx_ptr++ = data; *bs->rx_ptr++ = data;
rx_empty = bcm_spi_readb(SPI_RX_EMPTY); rx_empty = bcm_spi_readb(bs->regs, SPI_RX_EMPTY);
} }
/* See if there is more data to send */ /* See if there is more data to send */
@ -259,10 +260,10 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
bcm63xx_spi_fill_tx_fifo(bs); bcm63xx_spi_fill_tx_fifo(bs);
/* Start the transfer */ /* Start the transfer */
cmd = bcm_spi_readb(SPI_CMD); cmd = bcm_spi_readb(bs->regs, SPI_CMD);
cmd |= SPI_CMD_START_IMMEDIATE; cmd |= SPI_CMD_START_IMMEDIATE;
cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
bcm_spi_writeb(cmd, SPI_CMD); bcm_spi_writeb(cmd, bs->regs, SPI_CMD);
} else } else
complete(&bs->done); complete(&bs->done);
} }
@ -346,8 +347,8 @@ static int __init bcm63xx_spi_probe(struct platform_device *pdev)
/* Initialize hardware */ /* Initialize hardware */
clk_enable(bs->clk); clk_enable(bs->clk);
bcm_spi_writew(SPI_CMD_HARD_RESET, SPI_CMD); bcm_spi_writew(SPI_CMD_HARD_RESET, bs->regs, SPI_CMD);
bcm_spi_writeb(SPI_INTR_CLEAR_ALL, SPI_INT_MASK); bcm_spi_writeb(SPI_INTR_CLEAR_ALL, bs->regs, SPI_INT_MASK);
dev_info(&pdev->dev, PFX " at 0x%08x (irq %d, FIFOs size %d) v%s\n", dev_info(&pdev->dev, PFX " at 0x%08x (irq %d, FIFOs size %d) v%s\n",
r->start, irq, bs->fifo_size, DRV_VER); r->start, irq, bs->fifo_size, DRV_VER);
@ -442,3 +443,4 @@ MODULE_ALIAS("platform:bcm63xx_spi");
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
MODULE_DESCRIPTION("Broadcom BCM63xx SPI Controller driver"); MODULE_DESCRIPTION("Broadcom BCM63xx SPI Controller driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VER);

View file

@ -93,15 +93,15 @@
/* /*
* helpers for the SPI register sets * helpers for the SPI register sets
*/ */
#define bcm_spi_readb(o) bcm_readb(bcm63xx_regset_address(RSET_SPI) + \ #define bcm_spi_readb(b,o) bcm_readb((b) + \
bcm63xx_spireg(o)) bcm63xx_spireg(o))
#define bcm_spi_readw(o) bcm_readw(bcm63xx_regset_address(RSET_SPI) + \ #define bcm_spi_readw(b,o) bcm_readw((b) + \
bcm63xx_spireg(o)) bcm63xx_spireg(o))
#define bcm_spi_writeb(v,o) bcm_writeb((v), \ #define bcm_spi_writeb(v,b,o) bcm_writeb((v), \
bcm63xx_regset_address(RSET_SPI) + \ (b) + \
bcm63xx_spireg(o)) bcm63xx_spireg(o))
#define bcm_spi_writew(v,o) bcm_writew((v), \ #define bcm_spi_writew(v,b,o) bcm_writew((v), \
bcm63xx_regset_address(RSET_SPI) + \ (b) + \
bcm63xx_spireg(o)) bcm63xx_spireg(o))
#endif /* ! BCM63XX_IO_H_ */ #endif /* ! BCM63XX_IO_H_ */