Merge tag 'spi-v3.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
[pandora-kernel.git] / drivers / spi / spi-rspi.c
index 1f69343..28987d9 100644 (file)
 #define RSPI_SPBFDR            0x22    /* Buffer Data Count Setting Register */
 
 /*qspi only */
-#define QSPI_SPBFCR            0x18
-#define QSPI_SPBDCR            0x1a
-#define QSPI_SPBMUL0           0x1c
-#define QSPI_SPBMUL1           0x20
-#define QSPI_SPBMUL2           0x24
-#define QSPI_SPBMUL3           0x28
+#define QSPI_SPBFCR            0x18    /* Buffer Control Register */
+#define QSPI_SPBDCR            0x1a    /* Buffer Data Count Register */
+#define QSPI_SPBMUL0           0x1c    /* Transfer Data Length Multiplier Setting Register 0 */
+#define QSPI_SPBMUL1           0x20    /* Transfer Data Length Multiplier Setting Register 1 */
+#define QSPI_SPBMUL2           0x24    /* Transfer Data Length Multiplier Setting Register 2 */
+#define QSPI_SPBMUL3           0x28    /* Transfer Data Length Multiplier Setting Register 3 */
 
 /* SPCR - Control Register */
 #define SPCR_SPRIE             0x80    /* Receive Interrupt Enable */
@@ -79,6 +79,9 @@
 /* RSPI on SH only */
 #define SPCR_TXMD              0x02    /* TX Only Mode (vs. Full Duplex) */
 #define SPCR_SPMS              0x01    /* 3-wire Mode (vs. 4-wire) */
+/* QSPI on R-Car M2 only */
+#define SPCR_WSWAP             0x02    /* Word Swap of read-data for DMAC */
+#define SPCR_BSWAP             0x01    /* Byte Swap of read-data for DMAC */
 
 /* SSLP - Slave Select Polarity Register */
 #define SSLP_SSL1P             0x02    /* SSL1 Signal Polarity Setting */
@@ -91,6 +94,9 @@
 #define SPPCR_SPLP2            0x02    /* Loopback Mode 2 (non-inverting) */
 #define SPPCR_SPLP             0x01    /* Loopback Mode (inverting) */
 
+#define SPPCR_IO3FV            0x04    /* Single-/Dual-SPI Mode IO3 Output Fixed Value */
+#define SPPCR_IO2FV            0x04    /* Single-/Dual-SPI Mode IO2 Output Fixed Value */
+
 /* SPSR - Status Register */
 #define SPSR_SPRF              0x80    /* Receive Buffer Full Flag */
 #define SPSR_TEND              0x40    /* Transmit End */
 #define SPCMD_SPB_24BIT                0x0100
 #define SPCMD_SPB_32BIT                0x0200
 #define SPCMD_SSLKP            0x0080  /* SSL Signal Level Keeping */
+#define SPCMD_SPIMOD_MASK      0x0060  /* SPI Operating Mode (QSPI only) */
+#define SPCMD_SPIMOD1          0x0040
+#define SPCMD_SPIMOD0          0x0020
+#define SPCMD_SPIMOD_SINGLE    0
+#define SPCMD_SPIMOD_DUAL      SPCMD_SPIMOD0
+#define SPCMD_SPIMOD_QUAD      SPCMD_SPIMOD1
+#define SPCMD_SPRW             0x0010  /* SPI Read/Write Access (Dual/Quad) */
 #define SPCMD_SSLA_MASK                0x0030  /* SSL Assert Signal Setting (RSPI) */
 #define SPCMD_BRDV_MASK                0x000c  /* Bit Rate Division Setting */
 #define SPCMD_CPOL             0x0002  /* Clock Polarity Setting */
@@ -174,6 +187,7 @@ struct rspi_data {
        spinlock_t lock;
        struct clk *clk;
        u8 spsr;
+       u16 spcmd;
        const struct spi_ops *ops;
 
        /* for dmaengine */
@@ -248,7 +262,7 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
        rspi_write8(rspi, 0x00, RSPI_SPCR2);
 
        /* Sets SPCMD */
-       rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP,
+       rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | rspi->spcmd,
                     RSPI_SPCMD0);
 
        /* Sets RSPI mode */
@@ -286,10 +300,10 @@ static int qspi_set_config_register(const struct rspi_data *rspi,
                spcmd = SPCMD_SPB_8BIT;
        else if (access_size == 16)
                spcmd = SPCMD_SPB_16BIT;
-       else if (access_size == 32)
+       else
                spcmd = SPCMD_SPB_32BIT;
 
-       spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | SPCMD_SSLKP | SPCMD_SPNDEN;
+       spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | rspi->spcmd | SPCMD_SPNDEN;
 
        /* Resets transfer data length */
        rspi_write32(rspi, 0, QSPI_SPBMUL0);
@@ -364,7 +378,7 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
                remain--;
        }
 
-       /* Waiting for the last transmition */
+       /* Waiting for the last transmission */
        rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
 
        return 0;
@@ -398,7 +412,7 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
                remain--;
        }
 
-       /* Waiting for the last transmition */
+       /* Waiting for the last transmission */
        rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
 
        return 0;
@@ -534,7 +548,7 @@ static void rspi_receive_init(const struct rspi_data *rspi)
                rspi_read16(rspi, RSPI_SPDR);   /* dummy read */
        if (spsr & SPSR_OVRF)
                rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF,
-                           RSPI_SPCR);
+                           RSPI_SPSR);
 }
 
 static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
@@ -788,10 +802,14 @@ static int rspi_setup(struct spi_device *spi)
 {
        struct rspi_data *rspi = spi_master_get_devdata(spi->master);
 
-       if (!spi->bits_per_word)
-               spi->bits_per_word = 8;
        rspi->max_speed_hz = spi->max_speed_hz;
 
+       rspi->spcmd = SPCMD_SSLKP;
+       if (spi->mode & SPI_CPOL)
+               rspi->spcmd |= SPCMD_CPOL;
+       if (spi->mode & SPI_CPHA)
+               rspi->spcmd |= SPCMD_CPHA;
+
        set_config_register(rspi, 8);
 
        return 0;
@@ -902,14 +920,10 @@ static void rspi_release_dma(struct rspi_data *rspi)
 
 static int rspi_remove(struct platform_device *pdev)
 {
-       struct rspi_data *rspi = spi_master_get(platform_get_drvdata(pdev));
+       struct rspi_data *rspi = platform_get_drvdata(pdev);
 
-       spi_unregister_master(rspi->master);
        rspi_release_dma(rspi);
-       free_irq(platform_get_irq(pdev, 0), rspi);
-       clk_put(rspi->clk);
-       iounmap(rspi->addr);
-       spi_master_put(rspi->master);
+       clk_disable(rspi->clk);
 
        return 0;
 }
@@ -931,12 +945,6 @@ static int rspi_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "there is no set_config_register\n");
                return -ENODEV;
        }
-       /* get base addr */
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (unlikely(res == NULL)) {
-               dev_err(&pdev->dev, "invalid resource\n");
-               return -EINVAL;
-       }
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
@@ -954,19 +962,20 @@ static int rspi_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, rspi);
        rspi->ops = ops;
        rspi->master = master;
-       rspi->addr = ioremap(res->start, resource_size(res));
-       if (rspi->addr == NULL) {
-               dev_err(&pdev->dev, "ioremap error.\n");
-               ret = -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rspi->addr = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(rspi->addr)) {
+               ret = PTR_ERR(rspi->addr);
                goto error1;
        }
 
        snprintf(clk_name, sizeof(clk_name), "%s%d", id_entry->name, pdev->id);
-       rspi->clk = clk_get(&pdev->dev, clk_name);
+       rspi->clk = devm_clk_get(&pdev->dev, clk_name);
        if (IS_ERR(rspi->clk)) {
                dev_err(&pdev->dev, "cannot get clock\n");
                ret = PTR_ERR(rspi->clk);
-               goto error2;
+               goto error1;
        }
        clk_enable(rspi->clk);
 
@@ -975,45 +984,45 @@ static int rspi_probe(struct platform_device *pdev)
        INIT_WORK(&rspi->ws, rspi_work);
        init_waitqueue_head(&rspi->wait);
 
-       master->num_chipselect = rspi_pd->num_chipselect;
-       if (!master->num_chipselect)
+       if (rspi_pd && rspi_pd->num_chipselect)
+               master->num_chipselect = rspi_pd->num_chipselect;
+       else
                master->num_chipselect = 2; /* default */
 
        master->bus_num = pdev->id;
        master->setup = rspi_setup;
        master->transfer = rspi_transfer;
        master->cleanup = rspi_cleanup;
+       master->mode_bits = SPI_CPHA | SPI_CPOL;
 
-       ret = request_irq(irq, rspi_irq, 0, dev_name(&pdev->dev), rspi);
+       ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0,
+                              dev_name(&pdev->dev), rspi);
        if (ret < 0) {
                dev_err(&pdev->dev, "request_irq error\n");
-               goto error3;
+               goto error2;
        }
 
        rspi->irq = irq;
        ret = rspi_request_dma(rspi, pdev);
        if (ret < 0) {
                dev_err(&pdev->dev, "rspi_request_dma failed.\n");
-               goto error4;
+               goto error3;
        }
 
-       ret = spi_register_master(master);
+       ret = devm_spi_register_master(&pdev->dev, master);
        if (ret < 0) {
                dev_err(&pdev->dev, "spi_register_master error.\n");
-               goto error4;
+               goto error3;
        }
 
        dev_info(&pdev->dev, "probed\n");
 
        return 0;
 
-error4:
-       rspi_release_dma(rspi);
-       free_irq(irq, rspi);
 error3:
-       clk_put(rspi->clk);
+       rspi_release_dma(rspi);
 error2:
-       iounmap(rspi->addr);
+       clk_disable(rspi->clk);
 error1:
        spi_master_put(master);