On 02/03/2011 02:37 AM, Thomas Chou wrote:
> This patch adds support of OpenCores tiny SPI driver.
>
> http://opencores.org/project,tiny_spi
>

> +static int tiny_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
> +{
> +     struct tiny_spi *hw = tiny_spi_to_hw(spi);
> +     const u8 *txp = t->tx_buf;
> +     u8 *rxp = t->rx_buf;
> +     unsigned int i;
> +
> +     if (hw->irq>= 0) {
> +             /* use intrrupt driven data transfer */
> +             hw->len = t->len;
> +             hw->txp = t->tx_buf;
> +             hw->rxp = t->rx_buf;
> +             hw->txc = 0;
> +             hw->rxc = 0;
> +
> +             /* send the first byte */
> +             if (t->len>  1) {
> +                     writeb(hw->txp ? *hw->txp++ : 0,
> +                            hw->base + TINY_SPI_TXDATA);
> +                     hw->txc++;
> +                     writeb(hw->txp ? *hw->txp++ : 0,
> +                            hw->base + TINY_SPI_TXDATA);
> +                     hw->txc++;
> +                     writeb(TINY_SPI_STATUS_TXR, hw->base + TINY_SPI_STATUS);
> +             } else {
> +                     writeb(hw->txp ? *hw->txp++ : 0,
> +                            hw->base + TINY_SPI_TXDATA);
> +                     hw->txc++;
> +                     writeb(TINY_SPI_STATUS_TXE, hw->base + TINY_SPI_STATUS);
> +             }
> +
> +             wait_for_completion(&hw->done);
> +     } else if (txp&&  rxp) {
> +             /* we need to tighten the transfer loop */
> +             writeb(*txp++, hw->base + TINY_SPI_TXDATA);
> +             if (t->len>  1) {
> +                     writeb(*txp++, hw->base + TINY_SPI_TXDATA);
> +                     for (i = 2; i<  t->len; i++) {
> +                             u8 rx, tx = *txp++;
> +                             while (!(readb(hw->base + TINY_SPI_STATUS)&
> +                                      TINY_SPI_STATUS_TXR))
> +                                     cpu_relax();

Putting the read status, cpu releax in an inline function would make this 
function a lot easier to read.

> +                             rx = readb(hw->base + TINY_SPI_TXDATA);
> +                             writeb(tx, hw->base + TINY_SPI_TXDATA);
> +                             *rxp++ = rx;
> +                     }
> +                     while (!(readb(hw->base + TINY_SPI_STATUS)&
> +                              TINY_SPI_STATUS_TXR))
> +                             cpu_relax();
> +                     *rxp++ = readb(hw->base + TINY_SPI_TXDATA);
> +             }
> +             while (!(readb(hw->base + TINY_SPI_STATUS)&
> +                      TINY_SPI_STATUS_TXE))
> +                     cpu_relax();
> +             *rxp++ = readb(hw->base + TINY_SPI_RXDATA);
> +     } else if (rxp) {
> +             writeb(0, hw->base + TINY_SPI_TXDATA);
> +             if (t->len>  1) {
> +                     writeb(0,
> +                            hw->base + TINY_SPI_TXDATA);
> +                     for (i = 2; i<  t->len; i++) {
> +                             u8 rx;
> +                             while (!(readb(hw->base + TINY_SPI_STATUS)&
> +                                      TINY_SPI_STATUS_TXR))
> +                                     cpu_relax();
> +                             rx = readb(hw->base + TINY_SPI_TXDATA);
> +                             writeb(0,
> +                                    hw->base + TINY_SPI_TXDATA);
> +                             *rxp++ = rx;
> +                     }
> +                     while (!(readb(hw->base + TINY_SPI_STATUS)&
> +                              TINY_SPI_STATUS_TXR))
> +                             cpu_relax();
> +                     *rxp++ = readb(hw->base + TINY_SPI_TXDATA);
> +             }
> +             while (!(readb(hw->base + TINY_SPI_STATUS)&
> +                      TINY_SPI_STATUS_TXE))
> +                     cpu_relax();
> +             *rxp++ = readb(hw->base + TINY_SPI_RXDATA);
> +     } else if (txp) {
> +             writeb(*txp++, hw->base + TINY_SPI_TXDATA);
> +             if (t->len>  1) {
> +                     writeb(*txp++, hw->base + TINY_SPI_TXDATA);
> +                     for (i = 2; i<  t->len; i++) {
> +                             u8 tx = *txp++;
> +                             while (!(readb(hw->base + TINY_SPI_STATUS)&
> +                                      TINY_SPI_STATUS_TXR))
> +                                     cpu_relax();
> +                             writeb(tx, hw->base + TINY_SPI_TXDATA);
> +                     }
> +             }
> +             while (!(readb(hw->base + TINY_SPI_STATUS)&
> +                      TINY_SPI_STATUS_TXE))
> +                     cpu_relax();
> +     } else {
> +             writeb(0, hw->base + TINY_SPI_TXDATA);
> +             if (t->len>  1) {
> +                     writeb(0,
> +                            hw->base + TINY_SPI_TXDATA);
> +                     for (i = 2; i<  t->len; i++) {
> +                             while (!(readb(hw->base + TINY_SPI_STATUS)&
> +                                      TINY_SPI_STATUS_TXR))
> +                                     cpu_relax();
> +                             writeb(0,
> +                                    hw->base + TINY_SPI_TXDATA);
> +                     }
> +             }
> +             while (!(readb(hw->base + TINY_SPI_STATUS)&
> +                      TINY_SPI_STATUS_TXE))
> +                     cpu_relax();
> +     }
> +     return t->len;
> +}

------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d
_______________________________________________
spi-devel-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

Reply via email to