1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-11-19 06:25:55 +02:00

[brcm63xx] multiple SPI driver fixes

- fix platform device registration
- fix chipselect, command register defines, add missing clock
- make slave select proper
- fix multibytes transferts

Signed-off-by: Tanguy Bouzéloc <tanguy.bouzeloc@efixo.com>

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@24849 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
florian 2010-12-29 16:19:59 +00:00
parent 53a56b4c09
commit 7ce92bc6e8

View File

@ -318,7 +318,7 @@
#endif /* BCM63XX_REGS_H_ */ #endif /* BCM63XX_REGS_H_ */
--- /dev/null --- /dev/null
+++ b/drivers/spi/bcm63xx_spi.c +++ b/drivers/spi/bcm63xx_spi.c
@@ -0,0 +1,501 @@ @@ -0,0 +1,494 @@
+/* +/*
+ * Broadcom BCM63xx SPI controller support + * Broadcom BCM63xx SPI controller support
+ * + *
@ -370,31 +370,36 @@
+ /* Data buffers */ + /* Data buffers */
+ const unsigned char *tx_ptr; + const unsigned char *tx_ptr;
+ unsigned char *rx_ptr; + unsigned char *rx_ptr;
+
+ /* data iomem */
+ u8 __iomem *tx_io;
+ const u8 __iomem *rx_io;
+
+ int remaining_bytes; + int remaining_bytes;
+ +
+ struct clk *clk; + struct clk *clk;
+ struct platform_device *pdev; + struct platform_device *pdev;
+}; +};
+ +
+static inline u8 bcm_spi_readb(struct bcm63xx_hsspi *bs, +static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs,
+ unsigned int offset) + unsigned int offset)
+{ +{
+ return bcm_readw(bs->regs + bcm63xx_spireg(offset)); + return bcm_readw(bs->regs + bcm63xx_spireg(offset));
+} +}
+ +
+static inline u16 bcm_spi_readw(struct bcm63xx_hsspi *bs, +static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs,
+ unsigned int offset) + unsigned int offset)
+{ +{
+ return bcm_readw(bs->regs + bcm63xx_spireg(offset)); + return bcm_readw(bs->regs + bcm63xx_spireg(offset));
+} +}
+ +
+static inline void bcm_spi_writeb(struct bcm63xx_hsspi *bs, +static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,
+ u8 value, unsigned int offset) + u8 value, unsigned int offset)
+{ +{
+ bcm_writeb(value, bs->regs + bcm63xx_spireg(offset)); + bcm_writeb(value, bs->regs + bcm63xx_spireg(offset));
+} +}
+ +
+static inline void bcm_spi_writew(struct bcm63xx_hsspi *bs, +static inline void bcm_spi_writew(struct bcm63xx_spi *bs,
+ u16 value, unsigned int offset) + u16 value, unsigned int offset)
+{ +{
+ bcm_writew(value, bs->regs + bcm63xx_spireg(offset)); + bcm_writew(value, bs->regs + bcm63xx_spireg(offset));
@ -442,13 +447,13 @@
+ case 32: + case 32:
+ clk_cfg = SPI_CLK_1_563MHZ; + clk_cfg = SPI_CLK_1_563MHZ;
+ break; + break;
+ case 128: + case 64:
+ clk_cfg = SPI_CLK_0_781MHZ; + clk_cfg = SPI_CLK_0_781MHZ;
+ break; + break;
+ case 64: + case 128:
+ default: + default:
+ /* Set to slowest mode for compatibility */ + /* Set to slowest mode for compatibility */
+ clk_cfg = SPI_CLK_0_781MHZ; + clk_cfg = SPI_CLK_0_391MHZ;
+ break; + break;
+ } + }
+ +
@ -497,20 +502,13 @@
+/* Fill the TX FIFO with as many bytes as possible */ +/* Fill the TX FIFO with as many bytes as possible */
+static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs) +static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)
+{ +{
+ u8 tail; + u8 size;
+ +
+ /* Fill the Tx FIFO with as many bytes as possible */ + /* Fill the Tx FIFO with as many bytes as possible */
+ tail = bcm_spi_readb(bs, SPI_MSG_TAIL); + size = bs->remaining_bytes < bs->fifo_size ? bs->remaining_bytes :
+ + bs->fifo_size;
+ while ((tail < bs->fifo_size) && (bs->remaining_bytes > 0)) { + memcpy_toio(bs->tx_io, bs->tx_ptr, size);
+ if (bs->tx_ptr) + bs->remaining_bytes -= size;
+ bcm_spi_writeb(bs, *bs->tx_ptr++, SPI_MSG_DATA);
+ else
+ bcm_spi_writeb(bs, 0, SPI_MSG_DATA);
+
+ bs->remaining_bytes--;
+ tail = bcm_spi_readb(bs, SPI_MSG_TAIL);
+ }
+} +}
+ +
+static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) +static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
@ -551,6 +549,7 @@
+ /* Issue the transfer */ + /* Issue the transfer */
+ 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);
+ cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
+ bcm_spi_writew(bs, cmd, SPI_CMD); + bcm_spi_writew(bs, cmd, SPI_CMD);
+ wait_for_completion(&bs->done); + wait_for_completion(&bs->done);
+ +
@ -603,16 +602,8 @@
+ rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); + rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
+ +
+ /* Read out all the data */ + /* Read out all the data */
+ if (rx_tail) { + if (rx_tail)
+ u8 data; + memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
+ u8 i = 0;
+
+ for(i = 0; i < rx_tail; i++) {
+ data = bcm_spi_readb(bs, SPI_RX_DATA);
+ if (bs->rx_ptr)
+ *bs->rx_ptr++ = data;
+ }
+ }
+ +
+ /* See if there is more data to send */ + /* See if there is more data to send */
+ if (bs->remaining_bytes > 0) { + if (bs->remaining_bytes > 0) {
@ -708,6 +699,8 @@
+ master->transfer = bcm63xx_transfer; + master->transfer = bcm63xx_transfer;
+ bs->speed_hz = pdata->speed_hz; + bs->speed_hz = pdata->speed_hz;
+ bs->stopping = 0; + bs->stopping = 0;
+ bs->tx_io = (u8*)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
+ bs->rx_io = (const u8*)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
+ spin_lock_init(&bs->lock); + spin_lock_init(&bs->lock);
+ +
+ /* Initialize hardware */ + /* Initialize hardware */
@ -796,7 +789,7 @@
+ .owner = THIS_MODULE, + .owner = THIS_MODULE,
+ }, + },
+ .probe = bcm63xx_spi_probe, + .probe = bcm63xx_spi_probe,
+ .remove = bcm63xx_spi_remove, + .remove = __exit_p(bcm63xx_spi_remove),
+ .suspend = bcm63xx_spi_suspend, + .suspend = bcm63xx_spi_suspend,
+ .resume = bcm63xx_spi_resume, + .resume = bcm63xx_spi_resume,
+}; +};