diff mbox

[1/6] DaVinci: SPI Driver for DaVinci and DA8xx SOC's

Message ID 0554BEF07D437848AF01B9C9B5F0BC5D7BB14533@dlee01.ent.ti.com (mailing list archive)
State Superseded
Headers show

Commit Message

s-paulraj@ti.com Aug. 5, 2009, 12:58 a.m. UTC
Dave,

I do not see a reason why this should not go upstream.

There is 1 issue
At this point of time i am unable to think of a good solution which actually takes care of minor differences in the IP between DM355/DM365/DM6467 and Primus. I do not know of  a clean way to do it without using is_cpu _* which i understand is strictly discouraged.


Thanks,
Sandeep

Comments

David Brownell Aug. 5, 2009, 4 a.m. UTC | #1
On Tuesday 04 August 2009, Paulraj, Sandeep wrote:
> I do not see a reason why this should not go upstream.

OK, I'll try to send that soon ...


> There is 1 issue
> At this point of time i am unable to think of a good
> solution which actually takes care of minor differences
> in the IP between DM355/DM365/DM6467 and Primus. I do
> not know of  a clean way to do it without using is_cpu_*
> which i understand is strictly discouraged.    

Actually *some* of it can be driven purely by the board
setup code ... rely on it not to set features that the
hardware doesn't support, and that suffices for quite a
few of those mechanisms.  Maybe all of them, even ...
diff mbox

Patch

======== CUT HERE
A few more fixes vs my previous patch:

 - Remove needless spi->bits_per_word default, now handled
   by the SPI core;

 - Move SPIFMTx setting to the spi_setup() code, out of
   the per-message overhead;

 - Move some never-change SPI settings to probe(), again
   out of the per-message overhead.

This keeps a lot of setup code from being per-message overhead.
---
 drivers/spi/davinci_spi.c |   89 ++++++++++++++++++++++----------------------
 1 file changed, 46 insertions(+), 43 deletions(-)

--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -198,10 +198,6 @@  static int davinci_spi_setup(struct spi_

        davinci_spi = spi_master_get_devdata(spi->master);

-       /* if bits per word length is zero then set it default 8 */
-       if (!spi->bits_per_word)
-               spi->bits_per_word = 8;
-
        /*
         * SPI in DaVinci and DA8xx operate between
         * 600 KHz and 50 MHz
@@ -209,23 +205,13 @@  static int davinci_spi_setup(struct spi_
        if (spi->max_speed_hz < 600000 || spi->max_speed_hz > 50000000)
                return -EINVAL;

-       retval = davinci_spi_setup_transfer(spi, NULL);
-
-       return retval;
-}
-
-static int davinci_spi_bufs_prep(struct spi_device *spi,
-                                struct davinci_spi *davinci_spi)
-{
-       int op_mode = 0;
-
        /*
-        * Set up device-specific SPI configuration parameters.
-        * Most of these would normally be handled in spi_setup(),
-        * updating the per-chipselect FMT registers, but some of
-        * them use global controls like SPI_LOOP and SPI_READY.
+        * Set up SPIFMTn register, unique to this chipselect.
+        *
+        * NOTE: we could do all of these with one write.  Also, some
+        * of the "version 2" features are found in chips that don't
+        * support all of them...
         */
-
        if (spi->mode & SPI_LSB_FIRST)
                set_fmt_bits(davinci_spi->base, SPIFMT_SHIFTDIR_MASK,
                                spi->chip_select);
@@ -247,6 +233,19 @@  static int davinci_spi_bufs_prep(struct
                clear_fmt_bits(davinci_spi->base, SPIFMT_PHASE_MASK,
                                spi->chip_select);

+       /*
+        * Version 1 hardware supports two basic SPI modes:
+        *  - Standard SPI mode uses 4 pins, with chipselect
+        *  - 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS)
+        *      (distinct from SPI_3WIRE, with just one data wire;
+        *      or similar variants without MOSI or without MISO)
+        *
+        * Version 2 hardware supports an optional handshaking signal,
+        * so it can support two more modes:
+        *  - 5 pin SPI variant is standard SPI plus SPI_READY
+        *  - 4 pin with enable is (SPI_READY | SPI_NO_CS)
+        */
+
        if (davinci_spi->version == SPI_VERSION_2) {
                clear_fmt_bits(davinci_spi->base, SPIFMT_WDELAY_MASK,
                                spi->chip_select);
@@ -293,33 +292,21 @@  static int davinci_spi_bufs_prep(struct
                                        spi->chip_select);
        }

-       /* Clock internal */
-       if (davinci_spi->pdata->clk_internal)
-               set_io_bits(davinci_spi->base + SPIGCR1,
-                               SPIGCR1_CLKMOD_MASK);
-       else
-               clear_io_bits(davinci_spi->base + SPIGCR1,
-                               SPIGCR1_CLKMOD_MASK);
+       retval = davinci_spi_setup_transfer(spi, NULL);

-       /* master mode default */
-       set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_MASTER_MASK);
+       return retval;
+}

-       if (davinci_spi->pdata->intr_level)
-               iowrite32(SPI_INTLVL_1, davinci_spi->base + SPILVL);
-       else
-               iowrite32(SPI_INTLVL_0, davinci_spi->base + SPILVL);
+static int davinci_spi_bufs_prep(struct spi_device *spi,
+                                struct davinci_spi *davinci_spi)
+{
+       int op_mode = 0;

        /*
-        * Version 1 hardware supports two basic SPI modes:
-        *  - Standard SPI mode uses 4 pins, with chipselect
-        *  - 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS)
-        *      (distinct from SPI_3WIRE, with just one data wire;
-        *      or similar variants without MOSI or without MISO)
-        *
-        * Version 2 hardware supports an optional handshaking signal,
-        * so it can support two more modes:
-        *  - 5 pin SPI variant is standard SPI plus SPI_READY
-        *  - 4 pin with enable is (SPI_READY | SPI_NO_CS)
+        * REVISIT  unless devices disagree about SPI_LOOP or
+        * SPI_READY (SPI_NO_CS only allows one device!), this
+        * should not need to be done before each message...
+        * optimize for both flags staying cleared.
         */

        op_mode = SPIPC0_DIFUN_MASK
@@ -672,11 +659,27 @@  static int davinci_spi_probe(struct plat

        init_completion(&davinci_spi->done);

-       /* Reset In/OUT SPI modle */
+       /* Reset In/OUT SPI module */
        iowrite32(0, davinci_spi->base + SPIGCR0);
        udelay(100);
        iowrite32(1, davinci_spi->base + SPIGCR0);

+       /* Clock internal */
+       if (davinci_spi->pdata->clk_internal)
+               set_io_bits(davinci_spi->base + SPIGCR1,
+                               SPIGCR1_CLKMOD_MASK);
+       else
+               clear_io_bits(davinci_spi->base + SPIGCR1,
+                               SPIGCR1_CLKMOD_MASK);
+
+       /* master mode default */
+       set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_MASTER_MASK);
+
+       if (davinci_spi->pdata->intr_level)
+               iowrite32(SPI_INTLVL_1, davinci_spi->base + SPILVL);
+       else
+               iowrite32(SPI_INTLVL_0, davinci_spi->base + SPILVL);
+
        ret = spi_bitbang_start(&davinci_spi->bitbang);
        if (ret != 0)
                goto free_clk;