spi: rspi: Add support for active-high chip selects
[sfrench/cifs-2.6.git] / drivers / spi / spi-rspi.c
index aef05f2ac749c21d06bb1ac1631e102fa22680cf..06192c9ea81329112f4aba97d0f1b0a28064c195 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/sh_dma.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/rspi.h>
+#include <linux/spinlock.h>
 
 #define RSPI_SPCR              0x00    /* Control Register */
 #define RSPI_SSLP              0x01    /* Slave Select Polarity Register */
@@ -79,8 +80,7 @@
 #define SPCR_BSWAP             0x01    /* Byte Swap of read-data for DMAC */
 
 /* SSLP - Slave Select Polarity Register */
-#define SSLP_SSL1P             0x02    /* SSL1 Signal Polarity Setting */
-#define SSLP_SSL0P             0x01    /* SSL0 Signal Polarity Setting */
+#define SSLP_SSLP(i)           BIT(i)  /* SSLi Signal Polarity Setting */
 
 /* SPPCR - Pin Control Register */
 #define SPPCR_MOIFE            0x20    /* MOSI Idle Value Fixing Enable */
@@ -181,7 +181,9 @@ struct rspi_data {
        void __iomem *addr;
        u32 max_speed_hz;
        struct spi_controller *ctlr;
+       struct platform_device *pdev;
        wait_queue_head_t wait;
+       spinlock_t lock;                /* Protects RMW-access to RSPI_SSLP */
        struct clk *clk;
        u16 spcmd;
        u8 spsr;
@@ -919,6 +921,29 @@ static int qspi_setup_sequencer(struct rspi_data *rspi,
        return 0;
 }
 
+static int rspi_setup(struct spi_device *spi)
+{
+       struct rspi_data *rspi = spi_controller_get_devdata(spi->controller);
+       u8 sslp;
+
+       if (spi->cs_gpiod)
+               return 0;
+
+       pm_runtime_get_sync(&rspi->pdev->dev);
+       spin_lock_irq(&rspi->lock);
+
+       sslp = rspi_read8(rspi, RSPI_SSLP);
+       if (spi->mode & SPI_CS_HIGH)
+               sslp |= SSLP_SSLP(spi->chip_select);
+       else
+               sslp &= ~SSLP_SSLP(spi->chip_select);
+       rspi_write8(rspi, sslp, RSPI_SSLP);
+
+       spin_unlock_irq(&rspi->lock);
+       pm_runtime_put(&rspi->pdev->dev);
+       return 0;
+}
+
 static int rspi_prepare_message(struct spi_controller *ctlr,
                                struct spi_message *msg)
 {
@@ -1248,17 +1273,20 @@ static int rspi_probe(struct platform_device *pdev)
                goto error1;
        }
 
+       rspi->pdev = pdev;
        pm_runtime_enable(&pdev->dev);
 
        init_waitqueue_head(&rspi->wait);
+       spin_lock_init(&rspi->lock);
 
        ctlr->bus_num = pdev->id;
+       ctlr->setup = rspi_setup;
        ctlr->auto_runtime_pm = true;
        ctlr->transfer_one = ops->transfer_one;
        ctlr->prepare_message = rspi_prepare_message;
        ctlr->unprepare_message = rspi_unprepare_message;
-       ctlr->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST | SPI_LOOP |
-                         ops->extra_mode_bits;
+       ctlr->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST |
+                         SPI_LOOP | ops->extra_mode_bits;
        ctlr->flags = ops->flags;
        ctlr->dev.of_node = pdev->dev.of_node;
        ctlr->use_gpio_descriptors = true;