* [PATCH V2 1/8] spi: rspi: Add more RSPI register documentation
[not found] ` <1389522464-1569-1-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
@ 2014-01-12 10:27 ` Geert Uytterhoeven
2014-01-13 12:10 ` Mark Brown
2014-01-12 10:27 ` [PATCH V2 2/8] spi: rspi: Add more QSPI " Geert Uytterhoeven
` (4 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Geert Uytterhoeven @ 2014-01-12 10:27 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA,
Geert Uytterhoeven
From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Acked-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
---
V2:
- Add Acked-by
- Add more legacy SH docs, based on the SH7753 datasheet
drivers/spi/spi-rspi.c | 185 ++++++++++++++++++++++++++----------------------
1 file changed, 99 insertions(+), 86 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 239354618eac..53e6e07251c1 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -37,27 +37,29 @@
#include <linux/spi/spi.h>
#include <linux/spi/rspi.h>
-#define RSPI_SPCR 0x00
-#define RSPI_SSLP 0x01
-#define RSPI_SPPCR 0x02
-#define RSPI_SPSR 0x03
-#define RSPI_SPDR 0x04
-#define RSPI_SPSCR 0x08
-#define RSPI_SPSSR 0x09
-#define RSPI_SPBR 0x0a
-#define RSPI_SPDCR 0x0b
-#define RSPI_SPCKD 0x0c
-#define RSPI_SSLND 0x0d
-#define RSPI_SPND 0x0e
-#define RSPI_SPCR2 0x0f
-#define RSPI_SPCMD0 0x10
-#define RSPI_SPCMD1 0x12
-#define RSPI_SPCMD2 0x14
-#define RSPI_SPCMD3 0x16
-#define RSPI_SPCMD4 0x18
-#define RSPI_SPCMD5 0x1a
-#define RSPI_SPCMD6 0x1c
-#define RSPI_SPCMD7 0x1e
+#define RSPI_SPCR 0x00 /* Control Register */
+#define RSPI_SSLP 0x01 /* Slave Select Polarity Register */
+#define RSPI_SPPCR 0x02 /* Pin Control Register */
+#define RSPI_SPSR 0x03 /* Status Register */
+#define RSPI_SPDR 0x04 /* Data Register */
+#define RSPI_SPSCR 0x08 /* Sequence Control Register */
+#define RSPI_SPSSR 0x09 /* Sequence Status Register */
+#define RSPI_SPBR 0x0a /* Bit Rate Register */
+#define RSPI_SPDCR 0x0b /* Data Control Register */
+#define RSPI_SPCKD 0x0c /* Clock Delay Register */
+#define RSPI_SSLND 0x0d /* Slave Select Negation Delay Register */
+#define RSPI_SPND 0x0e /* Next-Access Delay Register */
+#define RSPI_SPCR2 0x0f /* Control Register 2 */
+#define RSPI_SPCMD0 0x10 /* Command Register 0 */
+#define RSPI_SPCMD1 0x12 /* Command Register 1 */
+#define RSPI_SPCMD2 0x14 /* Command Register 2 */
+#define RSPI_SPCMD3 0x16 /* Command Register 3 */
+#define RSPI_SPCMD4 0x18 /* Command Register 4 */
+#define RSPI_SPCMD5 0x1a /* Command Register 5 */
+#define RSPI_SPCMD6 0x1c /* Command Register 6 */
+#define RSPI_SPCMD7 0x1e /* Command Register 7 */
+#define RSPI_SPBFCR 0x20 /* Buffer Control Register */
+#define RSPI_SPBFDR 0x22 /* Buffer Data Count Setting Register */
/*qspi only */
#define QSPI_SPBFCR 0x18
@@ -67,87 +69,98 @@
#define QSPI_SPBMUL2 0x24
#define QSPI_SPBMUL3 0x28
-/* SPCR */
-#define SPCR_SPRIE 0x80
-#define SPCR_SPE 0x40
-#define SPCR_SPTIE 0x20
-#define SPCR_SPEIE 0x10
-#define SPCR_MSTR 0x08
-#define SPCR_MODFEN 0x04
-#define SPCR_TXMD 0x02
-#define SPCR_SPMS 0x01
-
-/* SSLP */
-#define SSLP_SSL1P 0x02
-#define SSLP_SSL0P 0x01
-
-/* SPPCR */
-#define SPPCR_MOIFE 0x20
-#define SPPCR_MOIFV 0x10
+/* SPCR - Control Register */
+#define SPCR_SPRIE 0x80 /* Receive Interrupt Enable */
+#define SPCR_SPE 0x40 /* Function Enable */
+#define SPCR_SPTIE 0x20 /* Transmit Interrupt Enable */
+#define SPCR_SPEIE 0x10 /* Error Interrupt Enable */
+#define SPCR_MSTR 0x08 /* Master/Slave Mode Select */
+#define SPCR_MODFEN 0x04 /* Mode Fault Error Detection Enable */
+/* RSPI on SH only */
+#define SPCR_TXMD 0x02 /* TX Only Mode (vs. Full Duplex) */
+#define SPCR_SPMS 0x01 /* 3-wire Mode (vs. 4-wire) */
+
+/* SSLP - Slave Select Polarity Register */
+#define SSLP_SSL1P 0x02 /* SSL1 Signal Polarity Setting */
+#define SSLP_SSL0P 0x01 /* SSL0 Signal Polarity Setting */
+
+/* SPPCR - Pin Control Register */
+#define SPPCR_MOIFE 0x20 /* MOSI Idle Value Fixing Enable */
+#define SPPCR_MOIFV 0x10 /* MOSI Idle Fixed Value */
#define SPPCR_SPOM 0x04
-#define SPPCR_SPLP2 0x02
-#define SPPCR_SPLP 0x01
-
-/* SPSR */
-#define SPSR_SPRF 0x80
-#define SPSR_SPTEF 0x20
-#define SPSR_PERF 0x08
-#define SPSR_MODF 0x04
-#define SPSR_IDLNF 0x02
-#define SPSR_OVRF 0x01
-
-/* SPSCR */
-#define SPSCR_SPSLN_MASK 0x07
-
-/* SPSSR */
-#define SPSSR_SPECM_MASK 0x70
-#define SPSSR_SPCP_MASK 0x07
-
-/* SPDCR */
-#define SPDCR_SPLW 0x20
-#define SPDCR_SPRDTD 0x10
+#define SPPCR_SPLP2 0x02 /* Loopback Mode 2 (non-inverting) */
+#define SPPCR_SPLP 0x01 /* Loopback Mode (inverting) */
+
+/* SPSR - Status Register */
+#define SPSR_SPRF 0x80 /* Receive Buffer Full Flag */
+#define SPSR_TEND 0x40 /* Transmit End */
+#define SPSR_SPTEF 0x20 /* Transmit Buffer Empty Flag */
+#define SPSR_PERF 0x08 /* Parity Error Flag */
+#define SPSR_MODF 0x04 /* Mode Fault Error Flag */
+#define SPSR_IDLNF 0x02 /* RSPI Idle Flag */
+#define SPSR_OVRF 0x01 /* Overrun Error Flag */
+
+/* SPSCR - Sequence Control Register */
+#define SPSCR_SPSLN_MASK 0x07 /* Sequence Length Specification */
+
+/* SPSSR - Sequence Status Register */
+#define SPSSR_SPECM_MASK 0x70 /* Command Error Mask */
+#define SPSSR_SPCP_MASK 0x07 /* Command Pointer Mask */
+
+/* SPDCR - Data Control Register */
+#define SPDCR_TXDMY 0x80 /* Dummy Data Transmission Enable */
+#define SPDCR_SPLW1 0x40 /* Access Width Specification (RZ) */
+#define SPDCR_SPLW0 0x20 /* Access Width Specification (RZ) */
+#define SPDCR_SPLLWORD (SPDCR_SPLW1 | SPDCR_SPLW0)
+#define SPDCR_SPLWORD SPDCR_SPLW1
+#define SPDCR_SPLBYTE SPDCR_SPLW0
+#define SPDCR_SPLW 0x20 /* Access Width Specification (SH) */
+#define SPDCR_SPRDTD 0x10 /* Receive Transmit Data Select */
#define SPDCR_SLSEL1 0x08
#define SPDCR_SLSEL0 0x04
-#define SPDCR_SLSEL_MASK 0x0c
+#define SPDCR_SLSEL_MASK 0x0c /* SSL1 Output Select */
#define SPDCR_SPFC1 0x02
#define SPDCR_SPFC0 0x01
+#define SPDCR_SPFC_MASK 0x03 /* Frame Count Setting (1-4) */
-/* SPCKD */
-#define SPCKD_SCKDL_MASK 0x07
+/* SPCKD - Clock Delay Register */
+#define SPCKD_SCKDL_MASK 0x07 /* Clock Delay Setting (1-8) */
-/* SSLND */
-#define SSLND_SLNDL_MASK 0x07
+/* SSLND - Slave Select Negation Delay Register */
+#define SSLND_SLNDL_MASK 0x07 /* SSL Negation Delay Setting (1-8) */
-/* SPND */
-#define SPND_SPNDL_MASK 0x07
+/* SPND - Next-Access Delay Register */
+#define SPND_SPNDL_MASK 0x07 /* Next-Access Delay Setting (1-8) */
-/* SPCR2 */
-#define SPCR2_PTE 0x08
-#define SPCR2_SPIE 0x04
-#define SPCR2_SPOE 0x02
-#define SPCR2_SPPE 0x01
+/* SPCR2 - Control Register 2 */
+#define SPCR2_PTE 0x08 /* Parity Self-Test Enable */
+#define SPCR2_SPIE 0x04 /* Idle Interrupt Enable */
+#define SPCR2_SPOE 0x02 /* Odd Parity Enable (vs. Even) */
+#define SPCR2_SPPE 0x01 /* Parity Enable */
-/* SPCMDn */
-#define SPCMD_SCKDEN 0x8000
-#define SPCMD_SLNDEN 0x4000
-#define SPCMD_SPNDEN 0x2000
-#define SPCMD_LSBF 0x1000
-#define SPCMD_SPB_MASK 0x0f00
+/* SPCMDn - Command Registers */
+#define SPCMD_SCKDEN 0x8000 /* Clock Delay Setting Enable */
+#define SPCMD_SLNDEN 0x4000 /* SSL Negation Delay Setting Enable */
+#define SPCMD_SPNDEN 0x2000 /* Next-Access Delay Enable */
+#define SPCMD_LSBF 0x1000 /* LSB First */
+#define SPCMD_SPB_MASK 0x0f00 /* Data Length Setting */
#define SPCMD_SPB_8_TO_16(bit) (((bit - 1) << 8) & SPCMD_SPB_MASK)
#define SPCMD_SPB_8BIT 0x0000 /* qspi only */
#define SPCMD_SPB_16BIT 0x0100
#define SPCMD_SPB_20BIT 0x0000
#define SPCMD_SPB_24BIT 0x0100
#define SPCMD_SPB_32BIT 0x0200
-#define SPCMD_SSLKP 0x0080
-#define SPCMD_SSLA_MASK 0x0030
-#define SPCMD_BRDV_MASK 0x000c
-#define SPCMD_CPOL 0x0002
-#define SPCMD_CPHA 0x0001
-
-/* SPBFCR */
-#define SPBFCR_TXRST 0x80 /* qspi only */
-#define SPBFCR_RXRST 0x40 /* qspi only */
+#define SPCMD_SSLKP 0x0080 /* SSL Signal Level Keeping */
+#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 */
+#define SPCMD_CPHA 0x0001 /* Clock Phase Setting */
+
+/* SPBFCR - Buffer Control Register */
+#define SPBFCR_TXRST 0x80 /* Transmit Buffer Data Reset (qspi only) */
+#define SPBFCR_RXRST 0x40 /* Receive Buffer Data Reset (qspi only) */
+#define SPBFCR_TXTRG_MASK 0x30 /* Transmit Buffer Data Triggering Number */
+#define SPBFCR_RXTRG_MASK 0x07 /* Receive Buffer Data Triggering Number */
#define DUMMY_DATA 0x00
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 2/8] spi: rspi: Add more QSPI register documentation
[not found] ` <1389522464-1569-1-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2014-01-12 10:27 ` [PATCH V2 1/8] spi: rspi: Add more RSPI register documentation Geert Uytterhoeven
@ 2014-01-12 10:27 ` Geert Uytterhoeven
[not found] ` <1389522464-1569-3-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2014-01-12 10:27 ` [PATCH V2 3/8] spi: rspi: Add support for more than one interrupt Geert Uytterhoeven
` (3 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Geert Uytterhoeven @ 2014-01-12 10:27 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA,
Geert Uytterhoeven
From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Acked-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
---
V2:
- Add Acked-by
- Add Word/Byte Swap of read-data for DMAC on R-Car M2 only
- Add Dual/Quad bits
- Fix SPCMD_SPRW
drivers/spi/spi-rspi.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 53e6e07251c1..eded530763ca 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -62,12 +62,12 @@
#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 */
@@ -151,6 +157,13 @@
#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 */
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 3/8] spi: rspi: Add support for more than one interrupt
[not found] ` <1389522464-1569-1-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2014-01-12 10:27 ` [PATCH V2 1/8] spi: rspi: Add more RSPI register documentation Geert Uytterhoeven
2014-01-12 10:27 ` [PATCH V2 2/8] spi: rspi: Add more QSPI " Geert Uytterhoeven
@ 2014-01-12 10:27 ` Geert Uytterhoeven
[not found] ` <1389522464-1569-4-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2014-01-12 10:27 ` [PATCH V2 4/8] spi: rspi: Add support for 8-bit Data Register access Geert Uytterhoeven
` (2 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Geert Uytterhoeven @ 2014-01-12 10:27 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA,
Geert Uytterhoeven
From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Add support for up to 3 interrupts, based on the SDK reference code.
This is needed for RZ/A1H.
Minimum 1 and maximum 3 interrupts can be passed via platform device
resources.
Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
---
v2:
- s/irq[]/irqs[]/
- s/numirq/num_irqs/
- Use unsigned int for loop counters that cannot be negative
- Merge the platform_get_irq() and devm_request_irq() loops
- Do not update copyright header in further untouched rspi.h
drivers/spi/spi-rspi.c | 52 +++++++++++++++++++++++++++++-------------------
1 file changed, 32 insertions(+), 20 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index eded530763ca..45da760281f9 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1,7 +1,7 @@
/*
* SH RSPI driver
*
- * Copyright (C) 2012 Renesas Solutions Corp.
+ * Copyright (C) 2012, 2013 Renesas Solutions Corp.
*
* Based on spi-sh.c:
* Copyright (C) 2011 Renesas Solutions Corp.
@@ -176,6 +176,7 @@
#define SPBFCR_RXTRG_MASK 0x07 /* Receive Buffer Data Triggering Number */
#define DUMMY_DATA 0x00
+#define MAX_NUM_IRQ 3
struct rspi_data {
void __iomem *addr;
@@ -187,12 +188,13 @@ struct rspi_data {
spinlock_t lock;
struct clk *clk;
u8 spsr;
+ int irqs[MAX_NUM_IRQ];
+ unsigned int num_irqs;
const struct spi_ops *ops;
/* for dmaengine */
struct dma_chan *chan_tx;
struct dma_chan *chan_rx;
- int irq;
unsigned dma_width_16bit:1;
unsigned dma_callbacked:1;
@@ -470,7 +472,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
struct scatterlist sg;
const void *buf = NULL;
struct dma_async_tx_descriptor *desc;
- unsigned len;
+ unsigned int len, i;
int ret = 0;
if (rspi->dma_width_16bit) {
@@ -508,7 +510,8 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
* DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
* called. So, this driver disables the IRQ while DMA transfer.
*/
- disable_irq(rspi->irq);
+ for (i = 0; i < rspi->num_irqs; i++)
+ disable_irq(rspi->irqs[i]);
rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
rspi_enable_irq(rspi, SPCR_SPTIE);
@@ -527,7 +530,8 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
ret = -ETIMEDOUT;
rspi_disable_irq(rspi, SPCR_SPTIE);
- enable_irq(rspi->irq);
+ for (i = 0; i < rspi->num_irqs; i++)
+ enable_irq(rspi->irqs[i]);
end:
rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
@@ -636,7 +640,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
struct scatterlist sg, sg_dummy;
void *dummy = NULL, *rx_buf = NULL;
struct dma_async_tx_descriptor *desc, *desc_dummy;
- unsigned len;
+ unsigned int len, i;
int ret = 0;
if (rspi->dma_width_16bit) {
@@ -694,7 +698,8 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
* DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
* called. So, this driver disables the IRQ while DMA transfer.
*/
- disable_irq(rspi->irq);
+ for (i = 0; i < rspi->num_irqs; i++)
+ disable_irq(rspi->irqs[i]);
rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
@@ -717,7 +722,8 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
ret = -ETIMEDOUT;
rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
- enable_irq(rspi->irq);
+ for (i = 0; i < rspi->num_irqs; i++)
+ enable_irq(rspi->irqs[i]);
end:
rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
@@ -928,6 +934,7 @@ static int rspi_probe(struct platform_device *pdev)
struct spi_master *master;
struct rspi_data *rspi;
int ret, irq;
+ unsigned int i;
char clk_name[16];
const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
const struct spi_ops *ops;
@@ -940,12 +947,6 @@ static int rspi_probe(struct platform_device *pdev)
return -ENODEV;
}
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "platform_get_irq error\n");
- return -ENODEV;
- }
-
master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
if (master == NULL) {
dev_err(&pdev->dev, "spi_alloc_master error.\n");
@@ -988,14 +989,25 @@ static int rspi_probe(struct platform_device *pdev)
master->transfer = rspi_transfer;
master->cleanup = rspi_cleanup;
- 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 error1;
+ for (i = 0; i < MAX_NUM_IRQ; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (irq < 0) {
+ if (rspi->num_irqs)
+ break;
+ dev_err(&pdev->dev, "platform_get_irq error\n");
+ ret = -ENODEV;
+ goto error1;
+ }
+ ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0,
+ dev_name(&pdev->dev), rspi);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "request_irq %d error\n", irq);
+ goto error1;
+ }
+ rspi->irqs[i] = irq;
+ rspi->num_irqs++;
}
- rspi->irq = irq;
ret = rspi_request_dma(rspi, pdev);
if (ret < 0) {
dev_err(&pdev->dev, "rspi_request_dma failed.\n");
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 4/8] spi: rspi: Add support for 8-bit Data Register access
[not found] ` <1389522464-1569-1-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
` (2 preceding siblings ...)
2014-01-12 10:27 ` [PATCH V2 3/8] spi: rspi: Add support for more than one interrupt Geert Uytterhoeven
@ 2014-01-12 10:27 ` Geert Uytterhoeven
[not found] ` <1389522464-1569-5-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2014-01-12 10:27 ` [PATCH V2 7/8] spi: rspi: Add support for specifying CPHA/CPOL Geert Uytterhoeven
2014-01-12 10:27 ` [PATCH V2 8/8] spi: rspi: Add support for loopback mode Geert Uytterhoeven
5 siblings, 1 reply; 19+ messages in thread
From: Geert Uytterhoeven @ 2014-01-12 10:27 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA,
Geert Uytterhoeven
From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Add support for accessing the RSPI Data Register using 8-bit operations,
based on the SDK reference code. This is needed for RZ/A1H.
The data width is passed using platform data, defaulting to 16-bit for
legacy RSPI. QSPI always uses 8-bit accesses.
Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
---
v2:
- Drop last if clause in rspi{write,read}_data(), and document we fall
back to 16-bit there
- Return sensible error value in rspi_parse_platform_data()
- Update copyright header in rspi.h
drivers/spi/spi-rspi.c | 89 +++++++++++++++++++++++++++++++++++++++-------
include/linux/spi/rspi.h | 4 ++-
2 files changed, 79 insertions(+), 14 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 45da760281f9..c3332d2b48e9 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -188,6 +188,8 @@ struct rspi_data {
spinlock_t lock;
struct clk *clk;
u8 spsr;
+ u8 spdcr;
+ u8 data_width;
int irqs[MAX_NUM_IRQ];
unsigned int num_irqs;
const struct spi_ops *ops;
@@ -225,8 +227,26 @@ static u16 rspi_read16(const struct rspi_data *rspi, u16 offset)
return ioread16(rspi->addr + offset);
}
+static void rspi_write_data(const struct rspi_data *rspi, u16 data)
+{
+ if (rspi->data_width == 8)
+ rspi_write8(rspi, data, RSPI_SPDR);
+ else /* 16 bit only */
+ rspi_write16(rspi, data, RSPI_SPDR);
+}
+
+static u16 rspi_read_data(const struct rspi_data *rspi)
+{
+ if (rspi->data_width == 8)
+ return rspi_read8(rspi, RSPI_SPDR);
+ else /* 16 bit only */
+ return rspi_read16(rspi, RSPI_SPDR);
+}
+
/* optional functions */
struct spi_ops {
+ int (*parse_platform_data)(struct rspi_data *rspi,
+ const struct rspi_plat_data *rspi_pd);
int (*set_config_register)(const struct rspi_data *rspi,
int access_size);
int (*send_pio)(struct rspi_data *rspi, struct spi_message *mesg,
@@ -239,6 +259,33 @@ struct spi_ops {
/*
* functions for RSPI
*/
+static int rspi_parse_platform_data(struct rspi_data *rspi,
+ const struct rspi_plat_data *rspi_pd)
+{
+ if (rspi_pd && rspi_pd->data_width) {
+ rspi->data_width = rspi_pd->data_width;
+ switch (rspi_pd->data_width) {
+ case 8:
+ rspi->spdcr = SPDCR_SPLBYTE;
+ break;
+ case 16:
+ rspi->spdcr = SPDCR_SPLWORD;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ /*
+ * Use legacy 16-bit width data access if a data_width value
+ * isn't defined in the platform data.
+ */
+ rspi->data_width = 16;
+ rspi->spdcr = 0;
+ }
+
+ return 0;
+}
+
static int rspi_set_config_register(const struct rspi_data *rspi,
int access_size)
{
@@ -252,7 +299,7 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
/* Sets number of frames to be used: 1 frame */
- rspi_write8(rspi, 0x00, RSPI_SPDCR);
+ rspi_write8(rspi, rspi->spdcr, RSPI_SPDCR);
/* Sets RSPCK, SSL, next-access delay value */
rspi_write8(rspi, 0x00, RSPI_SPCKD);
@@ -275,6 +322,16 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
/*
* functions for QSPI
*/
+static int qspi_parse_platform_data(struct rspi_data *rspi,
+ const struct rspi_plat_data *rspi_pd)
+{
+ /* Fixed 8-bit for now */
+ rspi->data_width = 8;
+ rspi->spdcr = 0;
+
+ return 0;
+}
+
static int qspi_set_config_register(const struct rspi_data *rspi,
int access_size)
{
@@ -289,7 +346,7 @@ static int qspi_set_config_register(const struct rspi_data *rspi,
rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
/* Sets number of frames to be used: 1 frame */
- rspi_write8(rspi, 0x00, RSPI_SPDCR);
+ rspi_write8(rspi, rspi->spdcr, RSPI_SPDCR);
/* Sets RSPCK, SSL, next-access delay value */
rspi_write8(rspi, 0x00, RSPI_SPCKD);
@@ -374,7 +431,7 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
return -ETIMEDOUT;
}
- rspi_write16(rspi, *data, RSPI_SPDR);
+ rspi_write_data(rspi, *data);
data++;
remain--;
}
@@ -401,14 +458,14 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
"%s: tx empty timeout\n", __func__);
return -ETIMEDOUT;
}
- rspi_write8(rspi, *data++, RSPI_SPDR);
+ rspi_write_data(rspi, *data++);
if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
dev_err(&rspi->master->dev,
"%s: receive timeout\n", __func__);
return -ETIMEDOUT;
}
- rspi_read8(rspi, RSPI_SPDR);
+ rspi_read_data(rspi);
remain--;
}
@@ -548,7 +605,7 @@ static void rspi_receive_init(const struct rspi_data *rspi)
spsr = rspi_read8(rspi, RSPI_SPSR);
if (spsr & SPSR_SPRF)
- rspi_read16(rspi, RSPI_SPDR); /* dummy read */
+ rspi_read_data(rspi); /* dummy read */
if (spsr & SPSR_OVRF)
rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF,
RSPI_SPSR);
@@ -573,15 +630,14 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
return -ETIMEDOUT;
}
/* dummy write for generate clock */
- rspi_write16(rspi, DUMMY_DATA, RSPI_SPDR);
+ rspi_write_data(rspi, DUMMY_DATA);
if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
dev_err(&rspi->master->dev,
"%s: receive timeout\n", __func__);
return -ETIMEDOUT;
}
- /* SPDR allows 16 or 32-bit access only */
- *data = (u8)rspi_read16(rspi, RSPI_SPDR);
+ *data = rspi_read_data(rspi);
data++;
remain--;
@@ -596,7 +652,7 @@ static void qspi_receive_init(const struct rspi_data *rspi)
spsr = rspi_read8(rspi, RSPI_SPSR);
if (spsr & SPSR_SPRF)
- rspi_read8(rspi, RSPI_SPDR); /* dummy read */
+ rspi_read_data(rspi); /* dummy read */
rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
rspi_write8(rspi, 0x00, QSPI_SPBFCR);
}
@@ -618,15 +674,14 @@ static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
return -ETIMEDOUT;
}
/* dummy write for generate clock */
- rspi_write8(rspi, DUMMY_DATA, RSPI_SPDR);
+ rspi_write_data(rspi, DUMMY_DATA);
if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
dev_err(&rspi->master->dev,
"%s: receive timeout\n", __func__);
return -ETIMEDOUT;
}
- /* SPDR allows 8, 16 or 32-bit access */
- *data++ = rspi_read8(rspi, RSPI_SPDR);
+ *data++ = rspi_read_data(rspi);
remain--;
}
@@ -989,6 +1044,12 @@ static int rspi_probe(struct platform_device *pdev)
master->transfer = rspi_transfer;
master->cleanup = rspi_cleanup;
+ ret = ops->parse_platform_data(rspi, rspi_pd);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "rspi invalid platform data.\n");
+ goto error1;
+ }
+
for (i = 0; i < MAX_NUM_IRQ; i++) {
irq = platform_get_irq(pdev, i);
if (irq < 0) {
@@ -1033,12 +1094,14 @@ error1:
}
static struct spi_ops rspi_ops = {
+ .parse_platform_data = rspi_parse_platform_data,
.set_config_register = rspi_set_config_register,
.send_pio = rspi_send_pio,
.receive_pio = rspi_receive_pio,
};
static struct spi_ops qspi_ops = {
+ .parse_platform_data = qspi_parse_platform_data,
.set_config_register = qspi_set_config_register,
.send_pio = qspi_send_pio,
.receive_pio = qspi_receive_pio,
diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
index a25bd6f65e7f..7316dd9c7ba9 100644
--- a/include/linux/spi/rspi.h
+++ b/include/linux/spi/rspi.h
@@ -1,7 +1,7 @@
/*
* Renesas SPI driver
*
- * Copyright (C) 2012 Renesas Solutions Corp.
+ * Copyright (C) 2012, 2013 Renesas Solutions Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +22,8 @@
#define __LINUX_SPI_RENESAS_SPI_H__
struct rspi_plat_data {
+ u8 data_width; /* Data register access width */
+
unsigned int dma_tx_id;
unsigned int dma_rx_id;
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 7/8] spi: rspi: Add support for specifying CPHA/CPOL
[not found] ` <1389522464-1569-1-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
` (3 preceding siblings ...)
2014-01-12 10:27 ` [PATCH V2 4/8] spi: rspi: Add support for 8-bit Data Register access Geert Uytterhoeven
@ 2014-01-12 10:27 ` Geert Uytterhoeven
2014-01-13 17:23 ` Mark Brown
2014-01-12 10:27 ` [PATCH V2 8/8] spi: rspi: Add support for loopback mode Geert Uytterhoeven
5 siblings, 1 reply; 19+ messages in thread
From: Geert Uytterhoeven @ 2014-01-12 10:27 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA,
Geert Uytterhoeven
From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Add support for specifying the SPI clock phase and polarity, based on the
SDK reference code.
Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Acked-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
---
V2:
- Add Acked-by
drivers/spi/spi-rspi.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 18c56d1feb8e..4b25c8617b02 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -190,6 +190,7 @@ struct rspi_data {
u8 spsr;
u8 spdcr;
u8 data_width;
+ u16 spcmd;
int irqs[MAX_NUM_IRQ];
unsigned int num_irqs;
const struct spi_ops *ops;
@@ -336,7 +337,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 */
@@ -391,7 +392,7 @@ static int qspi_set_config_register(const struct rspi_data *rspi,
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);
@@ -911,6 +912,12 @@ static int rspi_setup(struct spi_device *spi)
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;
@@ -1088,6 +1095,7 @@ static int rspi_probe(struct platform_device *pdev)
master->setup = rspi_setup;
master->transfer = rspi_transfer;
master->cleanup = rspi_cleanup;
+ master->mode_bits = SPI_CPHA | SPI_CPOL;
ret = ops->parse_platform_data(rspi, rspi_pd);
if (ret < 0) {
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH V2 7/8] spi: rspi: Add support for specifying CPHA/CPOL
2014-01-12 10:27 ` [PATCH V2 7/8] spi: rspi: Add support for specifying CPHA/CPOL Geert Uytterhoeven
@ 2014-01-13 17:23 ` Mark Brown
0 siblings, 0 replies; 19+ messages in thread
From: Mark Brown @ 2014-01-13 17:23 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-spi, linux-sh, Geert Uytterhoeven
[-- Attachment #1: Type: text/plain, Size: 252 bytes --]
On Sun, Jan 12, 2014 at 11:27:43AM +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
>
> Add support for specifying the SPI clock phase and polarity, based on the
> SDK reference code.
Applied, thanks.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH V2 8/8] spi: rspi: Add support for loopback mode
[not found] ` <1389522464-1569-1-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
` (4 preceding siblings ...)
2014-01-12 10:27 ` [PATCH V2 7/8] spi: rspi: Add support for specifying CPHA/CPOL Geert Uytterhoeven
@ 2014-01-12 10:27 ` Geert Uytterhoeven
5 siblings, 0 replies; 19+ messages in thread
From: Geert Uytterhoeven @ 2014-01-12 10:27 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA,
Geert Uytterhoeven
From: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Add support for specifying loopback mode for RSPI only, based on the SDK
reference code.
Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
---
V2:
- No changes
drivers/spi/spi-rspi.c | 59 +++++++++++++++++++++++++++++++++++++++---------
1 file changed, 48 insertions(+), 11 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 4b25c8617b02..04d512e1e894 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -170,8 +170,8 @@
#define SPCMD_CPHA 0x0001 /* Clock Phase Setting */
/* SPBFCR - Buffer Control Register */
-#define SPBFCR_TXRST 0x80 /* Transmit Buffer Data Reset (qspi only) */
-#define SPBFCR_RXRST 0x40 /* Receive Buffer Data Reset (qspi only) */
+#define SPBFCR_TXRST 0x80 /* Transmit Buffer Data Reset */
+#define SPBFCR_RXRST 0x40 /* Receive Buffer Data Reset */
#define SPBFCR_TXTRG_MASK 0x30 /* Transmit Buffer Data Triggering Number */
#define SPBFCR_RXTRG_MASK 0x07 /* Receive Buffer Data Triggering Number */
@@ -188,6 +188,7 @@ struct rspi_data {
spinlock_t lock;
struct clk *clk;
u8 spsr;
+ u8 sppcr;
u8 spdcr;
u8 data_width;
u16 spcmd;
@@ -256,7 +257,7 @@ struct spi_ops {
struct spi_transfer *t);
int (*receive_pio)(struct rspi_data *rspi, struct spi_message *mesg,
struct spi_transfer *t);
-
+ u16 mode_bits;
};
/*
@@ -317,8 +318,8 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
{
int spbr;
- /* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
- rspi_write8(rspi, 0x00, RSPI_SPPCR);
+ /* Sets output mode */
+ rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
/* Sets transfer bit rate */
spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
@@ -369,8 +370,8 @@ static int qspi_set_config_register(const struct rspi_data *rspi,
u16 spcmd;
int spbr;
- /* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
- rspi_write8(rspi, 0x00, RSPI_SPPCR);
+ /* Sets output mode */
+ rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
/* Sets transfer bit rate */
spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz);
@@ -413,6 +414,21 @@ static int qspi_set_config_register(const struct rspi_data *rspi,
#define set_config_register(spi, n) spi->ops->set_config_register(spi, n)
+static void rspi_clear_rxbuf(struct rspi_data *rspi)
+{
+ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPBFCR) | SPBFCR_RXRST,
+ RSPI_SPBFCR);
+ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPBFCR) & (~SPBFCR_RXRST),
+ RSPI_SPBFCR);
+}
+static void rspi_clear_txbuf(struct rspi_data *rspi)
+{
+ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPBFCR) | SPBFCR_TXRST,
+ RSPI_SPBFCR);
+ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPBFCR) & (~SPBFCR_TXRST),
+ RSPI_SPBFCR);
+}
+
static void rspi_enable_irq(const struct rspi_data *rspi, u8 enable)
{
rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | enable, RSPI_SPCR);
@@ -452,6 +468,13 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
{
int remain = t->len;
const u8 *data = t->tx_buf;
+
+ if (rspi->sppcr & SPPCR_SPLP) {
+ /* loopback mode */
+ rspi_clear_txbuf(rspi);
+ rspi_clear_rxbuf(rspi);
+ }
+
while (remain > 0) {
rspi_set_txmode(rspi);
@@ -461,7 +484,8 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
return -ETIMEDOUT;
}
- if (!rspi->txmode && remain != t->len) {
+ if (!rspi->txmode && remain != t->len &&
+ !(rspi->sppcr & SPPCR_SPLP)) {
if (rspi_wait_for_interrupt(rspi, SPSR_SPRF,
SPCR_SPRIE) < 0) {
dev_err(&rspi->master->dev,
@@ -478,7 +502,7 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
/* Waiting for the last transmition */
rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
- if (!rspi->txmode) {
+ if (!rspi->txmode && !(rspi->sppcr & SPPCR_SPLP)) {
if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
dev_err(&rspi->master->dev,
"%s: receive timeout\n", __func__);
@@ -651,7 +675,7 @@ static void rspi_receive_init(const struct rspi_data *rspi)
u8 spsr;
spsr = rspi_read8(rspi, RSPI_SPSR);
- if (spsr & SPSR_SPRF)
+ if (spsr & SPSR_SPRF && !(rspi->sppcr & SPPCR_SPLP))
rspi_read_data(rspi); /* dummy read */
if (spsr & SPSR_OVRF)
rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF,
@@ -689,6 +713,12 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
remain--;
}
+ if (rspi->sppcr & SPPCR_SPLP) {
+ /* loopback mode */
+ rspi_clear_txbuf(rspi);
+ rspi_clear_rxbuf(rspi);
+ }
+
return 0;
}
@@ -918,6 +948,11 @@ static int rspi_setup(struct spi_device *spi)
if (spi->mode & SPI_CPHA)
rspi->spcmd |= SPCMD_CPHA;
+ /* CMOS output mode and MOSI signal from previous transfer */
+ rspi->sppcr = 0;
+ if (spi->mode & SPI_LOOP)
+ rspi->sppcr |= SPPCR_SPLP;
+
set_config_register(rspi, 8);
return 0;
@@ -1095,7 +1130,7 @@ static int rspi_probe(struct platform_device *pdev)
master->setup = rspi_setup;
master->transfer = rspi_transfer;
master->cleanup = rspi_cleanup;
- master->mode_bits = SPI_CPHA | SPI_CPOL;
+ master->mode_bits = ops->mode_bits;
ret = ops->parse_platform_data(rspi, rspi_pd);
if (ret < 0) {
@@ -1151,6 +1186,7 @@ static struct spi_ops rspi_ops = {
.set_config_register = rspi_set_config_register,
.send_pio = rspi_send_pio,
.receive_pio = rspi_receive_pio,
+ .mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP,
};
static struct spi_ops qspi_ops = {
@@ -1158,6 +1194,7 @@ static struct spi_ops qspi_ops = {
.set_config_register = qspi_set_config_register,
.send_pio = qspi_send_pio,
.receive_pio = qspi_receive_pio,
+ .mode_bits = SPI_CPHA | SPI_CPOL,
};
static struct platform_device_id spi_driver_ids[] = {
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 19+ messages in thread