* [PATCH 0/8] spi: rspi: Add prelimary support for RZ/A1H
@ 2013-12-24 11:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh
This patch series adds preliminary support for RSPI in the RZ/A1H aka
R7S72100 SoC, which is found on the Genmai development board.
It hasn't received much testing, so please don't apply yet.
[1/8] spi: rspi: Add more RSPI register documentation
[2/8] spi: rspi: Add more QSPI register documentation
[3/8] spi: rspi: Add support for more than one interrupt
[4/8] spi: rspi: Add support for 8-bit Data Register access
[5/8] spi: rspi: Add support for no TX only mode
[6/8] spi: rspi: Add support for missing SPCR2 register
[7/8] spi: rspi: Add support for specifying CPHA/CPOL
[8/8] spi: rspi: Add support for loopback mode
Thanks for your comments, and Merry Christmas!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/8] spi: rspi: Add prelimary support for RZ/A1H
@ 2013-12-24 11:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh
This patch series adds preliminary support for RSPI in the RZ/A1H aka
R7S72100 SoC, which is found on the Genmai development board.
It hasn't received much testing, so please don't apply yet.
[1/8] spi: rspi: Add more RSPI register documentation
[2/8] spi: rspi: Add more QSPI register documentation
[3/8] spi: rspi: Add support for more than one interrupt
[4/8] spi: rspi: Add support for 8-bit Data Register access
[5/8] spi: rspi: Add support for no TX only mode
[6/8] spi: rspi: Add support for missing SPCR2 register
[7/8] spi: rspi: Add support for specifying CPHA/CPOL
[8/8] spi: rspi: Add support for loopback mode
Thanks for your comments, and Merry Christmas!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 1/8] spi: rspi: Add more RSPI register documentation
[not found] ` <1387885248-28425-1-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
@ 2013-12-24 11:40 ` Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
1 sibling, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi-u79uwXL29TY76Z2rM5mHXA
Cc: linux-sh-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
drivers/spi/spi-rspi.c | 143 ++++++++++++++++++++++++++----------------------
1 file changed, 77 insertions(+), 66 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 239354618eac..afd7466c65cd 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,44 +69,51 @@
#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
+/* 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 */
#define SPCR_TXMD 0x02
#define SPCR_SPMS 0x01
-/* SSLP */
+/* SSLP - Slave Select Polarity Register */
#define SSLP_SSL1P 0x02
-#define SSLP_SSL0P 0x01
+#define SSLP_SSL0P 0x01 /* SSL Signal Polarity Setting */
-/* SPPCR */
-#define SPPCR_MOIFE 0x20
-#define SPPCR_MOIFV 0x10
+/* 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
+#define SPPCR_SPLP 0x01 /* Loopback */
-/* SPSR */
-#define SPSR_SPRF 0x80
-#define SPSR_SPTEF 0x20
+/* 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
-#define SPSR_MODF 0x04
+#define SPSR_MODF 0x04 /* Mode Fault Error Flag */
#define SPSR_IDLNF 0x02
-#define SPSR_OVRF 0x01
+#define SPSR_OVRF 0x01 /* Overrun Error Flag */
-/* SPSCR */
-#define SPSCR_SPSLN_MASK 0x07
+/* SPSCR - Sequence Control Register */
+#define SPSCR_SPSLN_MASK 0x07 /* Sequence Length Specification */
-/* SPSSR */
+/* SPSSR - Sequence Status Register */
#define SPSSR_SPECM_MASK 0x70
-#define SPSSR_SPCP_MASK 0x07
-
-/* SPDCR */
-#define SPDCR_SPLW 0x20
+#define SPSSR_SPCP_MASK 0x07 /* Command Pointer */
+
+/* SPDCR - Data Control Register */
+#define SPDCR_TXDMY 0x80 /* Dummy Data Transmission Enable */
+#define SPDCR_SPLW1 0x40 /* Access Width Specification */
+#define SPDCR_SPLW0 0x20
+#define SPDCR_SPLLWORD (SPDCR_SPLW1 | SPDCR_SPLW0)
+#define SPDCR_SPLWORD SPDCR_SPLW1
+#define SPDCR_SPLBYTE SPDCR_SPLW0
+#define SPDCR_SPLW 0x20 /* Access Width Specification */
#define SPDCR_SPRDTD 0x10
#define SPDCR_SLSEL1 0x08
#define SPDCR_SLSEL0 0x04
@@ -112,27 +121,27 @@
#define SPDCR_SPFC1 0x02
#define SPDCR_SPFC0 0x01
-/* 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 */
+/* SPCR2 - Control Register 2 */
#define SPCR2_PTE 0x08
#define SPCR2_SPIE 0x04
#define SPCR2_SPOE 0x02
#define SPCR2_SPPE 0x01
-/* 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
@@ -141,13 +150,15 @@
#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_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
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 1/8] spi: rspi: Add more RSPI register documentation
@ 2013-12-24 11:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi-u79uwXL29TY76Z2rM5mHXA
Cc: linux-sh-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven
Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
---
drivers/spi/spi-rspi.c | 143 ++++++++++++++++++++++++++----------------------
1 file changed, 77 insertions(+), 66 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 239354618eac..afd7466c65cd 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,44 +69,51 @@
#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
+/* 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 */
#define SPCR_TXMD 0x02
#define SPCR_SPMS 0x01
-/* SSLP */
+/* SSLP - Slave Select Polarity Register */
#define SSLP_SSL1P 0x02
-#define SSLP_SSL0P 0x01
+#define SSLP_SSL0P 0x01 /* SSL Signal Polarity Setting */
-/* SPPCR */
-#define SPPCR_MOIFE 0x20
-#define SPPCR_MOIFV 0x10
+/* 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
+#define SPPCR_SPLP 0x01 /* Loopback */
-/* SPSR */
-#define SPSR_SPRF 0x80
-#define SPSR_SPTEF 0x20
+/* 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
-#define SPSR_MODF 0x04
+#define SPSR_MODF 0x04 /* Mode Fault Error Flag */
#define SPSR_IDLNF 0x02
-#define SPSR_OVRF 0x01
+#define SPSR_OVRF 0x01 /* Overrun Error Flag */
-/* SPSCR */
-#define SPSCR_SPSLN_MASK 0x07
+/* SPSCR - Sequence Control Register */
+#define SPSCR_SPSLN_MASK 0x07 /* Sequence Length Specification */
-/* SPSSR */
+/* SPSSR - Sequence Status Register */
#define SPSSR_SPECM_MASK 0x70
-#define SPSSR_SPCP_MASK 0x07
-
-/* SPDCR */
-#define SPDCR_SPLW 0x20
+#define SPSSR_SPCP_MASK 0x07 /* Command Pointer */
+
+/* SPDCR - Data Control Register */
+#define SPDCR_TXDMY 0x80 /* Dummy Data Transmission Enable */
+#define SPDCR_SPLW1 0x40 /* Access Width Specification */
+#define SPDCR_SPLW0 0x20
+#define SPDCR_SPLLWORD (SPDCR_SPLW1 | SPDCR_SPLW0)
+#define SPDCR_SPLWORD SPDCR_SPLW1
+#define SPDCR_SPLBYTE SPDCR_SPLW0
+#define SPDCR_SPLW 0x20 /* Access Width Specification */
#define SPDCR_SPRDTD 0x10
#define SPDCR_SLSEL1 0x08
#define SPDCR_SLSEL0 0x04
@@ -112,27 +121,27 @@
#define SPDCR_SPFC1 0x02
#define SPDCR_SPFC0 0x01
-/* 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 */
+/* SPCR2 - Control Register 2 */
#define SPCR2_PTE 0x08
#define SPCR2_SPIE 0x04
#define SPCR2_SPOE 0x02
#define SPCR2_SPPE 0x01
-/* 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
@@ -141,13 +150,15 @@
#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_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] 36+ messages in thread
* [PATCH 2/8] spi: rspi: Add more QSPI register documentation
2013-12-24 11:40 ` Geert Uytterhoeven
@ 2013-12-24 11:40 ` Geert Uytterhoeven
-1 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
drivers/spi/spi-rspi.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index afd7466c65cd..46232e3b6e8c 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 */
@@ -90,6 +90,9 @@
#define SPPCR_SPLP2 0x02
#define SPPCR_SPLP 0x01 /* Loopback */
+#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 */
@@ -109,7 +112,7 @@
/* SPDCR - Data Control Register */
#define SPDCR_TXDMY 0x80 /* Dummy Data Transmission Enable */
#define SPDCR_SPLW1 0x40 /* Access Width Specification */
-#define SPDCR_SPLW0 0x20
+#define SPDCR_SPLW0 0x20 /* Access Width Specification */
#define SPDCR_SPLLWORD (SPDCR_SPLW1 | SPDCR_SPLW0)
#define SPDCR_SPLWORD SPDCR_SPLW1
#define SPDCR_SPLBYTE SPDCR_SPLW0
@@ -148,12 +151,15 @@
#define SPCMD_SPB_20BIT 0x0000
#define SPCMD_SPB_24BIT 0x0100
#define SPCMD_SPB_32BIT 0x0200
-#define SPCMD_SSLKP 0x0080
+#define SPCMD_SSLKP 0x0080 /* SSL Signal Level Keeping */
#define SPCMD_SSLA_MASK 0x0030
#define SPCMD_BRDV_MASK 0x000c /* Bit Rate Division Setting */
#define SPCMD_CPOL 0x0002 /* Clock Polarity Setting */
#define SPCMD_CPHA 0x0001 /* Clock Phase Setting */
+#define SPCMD_SPIMOD_MASK 0x0060 /* SPI Operating Mode */
+#define SPCMD_SPRW 0x0060 /* SPI Read/Write Access */
+
/* SPBFCR - Buffer Control Register */
#define SPBFCR_TXRST 0x80 /* Transmit Buffer Data Reset (qspi only) */
#define SPBFCR_RXRST 0x40 /* Receive Buffer Data Reset (qspi only) */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 2/8] spi: rspi: Add more QSPI register documentation
@ 2013-12-24 11:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
drivers/spi/spi-rspi.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index afd7466c65cd..46232e3b6e8c 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 */
@@ -90,6 +90,9 @@
#define SPPCR_SPLP2 0x02
#define SPPCR_SPLP 0x01 /* Loopback */
+#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 */
@@ -109,7 +112,7 @@
/* SPDCR - Data Control Register */
#define SPDCR_TXDMY 0x80 /* Dummy Data Transmission Enable */
#define SPDCR_SPLW1 0x40 /* Access Width Specification */
-#define SPDCR_SPLW0 0x20
+#define SPDCR_SPLW0 0x20 /* Access Width Specification */
#define SPDCR_SPLLWORD (SPDCR_SPLW1 | SPDCR_SPLW0)
#define SPDCR_SPLWORD SPDCR_SPLW1
#define SPDCR_SPLBYTE SPDCR_SPLW0
@@ -148,12 +151,15 @@
#define SPCMD_SPB_20BIT 0x0000
#define SPCMD_SPB_24BIT 0x0100
#define SPCMD_SPB_32BIT 0x0200
-#define SPCMD_SSLKP 0x0080
+#define SPCMD_SSLKP 0x0080 /* SSL Signal Level Keeping */
#define SPCMD_SSLA_MASK 0x0030
#define SPCMD_BRDV_MASK 0x000c /* Bit Rate Division Setting */
#define SPCMD_CPOL 0x0002 /* Clock Polarity Setting */
#define SPCMD_CPHA 0x0001 /* Clock Phase Setting */
+#define SPCMD_SPIMOD_MASK 0x0060 /* SPI Operating Mode */
+#define SPCMD_SPRW 0x0060 /* SPI Read/Write Access */
+
/* SPBFCR - Buffer Control Register */
#define SPBFCR_TXRST 0x80 /* Transmit Buffer Data Reset (qspi only) */
#define SPBFCR_RXRST 0x40 /* Receive Buffer Data Reset (qspi only) */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 3/8] spi: rspi: Add support for more than one interrupt
2013-12-24 11:40 ` Geert Uytterhoeven
@ 2013-12-24 11:40 ` Geert Uytterhoeven
-1 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
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@linux-m68k.org>
---
drivers/spi/spi-rspi.c | 57 +++++++++++++++++++++++++++++-----------------
include/linux/spi/rspi.h | 2 +-
2 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 46232e3b6e8c..c7bbc54ef785 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.
@@ -167,6 +167,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;
@@ -178,12 +179,13 @@ struct rspi_data {
spinlock_t lock;
struct clk *clk;
u8 spsr;
+ int irq[MAX_NUM_IRQ];
+ unsigned int numirq;
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;
@@ -462,7 +464,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
const void *buf = NULL;
struct dma_async_tx_descriptor *desc;
unsigned len;
- int ret = 0;
+ int i, ret = 0;
if (rspi->dma_width_16bit) {
void *tmp;
@@ -499,7 +501,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->numirq; i++)
+ disable_irq(rspi->irq[i]);
rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
rspi_enable_irq(rspi, SPCR_SPTIE);
@@ -518,7 +521,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->numirq; i++)
+ enable_irq(rspi->irq[i]);
end:
rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
@@ -628,7 +632,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
void *dummy = NULL, *rx_buf = NULL;
struct dma_async_tx_descriptor *desc, *desc_dummy;
unsigned len;
- int ret = 0;
+ int i, ret = 0;
if (rspi->dma_width_16bit) {
/*
@@ -685,7 +689,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->numirq; i++)
+ disable_irq(rspi->irq[i]);
rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
@@ -708,7 +713,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->numirq; i++)
+ enable_irq(rspi->irq[i]);
end:
rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
@@ -918,7 +924,7 @@ static int rspi_probe(struct platform_device *pdev)
struct resource *res;
struct spi_master *master;
struct rspi_data *rspi;
- int ret, irq;
+ int i, ret, irq;
char clk_name[16];
const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
const struct spi_ops *ops;
@@ -931,12 +937,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");
@@ -948,6 +948,19 @@ static int rspi_probe(struct platform_device *pdev)
rspi->ops = ops;
rspi->master = master;
+ for (i = 0; i < MAX_NUM_IRQ; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (irq < 0) {
+ if (rspi->numirq)
+ break;
+ dev_err(&pdev->dev, "platform_get_irq error\n");
+ ret = -ENODEV;
+ goto error1;
+ }
+ rspi->irq[i] = irq;
+ rspi->numirq++;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rspi->addr = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(rspi->addr)) {
@@ -979,14 +992,16 @@ 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 < rspi->numirq; i++) {
+ ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
+ dev_name(&pdev->dev), rspi);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "request_irq %d error\n",
+ rspi->irq[i]);
+ goto error1;
+ }
}
- rspi->irq = irq;
ret = rspi_request_dma(rspi, pdev);
if (ret < 0) {
dev_err(&pdev->dev, "rspi_request_dma failed.\n");
diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
index a25bd6f65e7f..3f55232f74ff 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
--
1.7.9.5
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 3/8] spi: rspi: Add support for more than one interrupt
@ 2013-12-24 11:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
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@linux-m68k.org>
---
drivers/spi/spi-rspi.c | 57 +++++++++++++++++++++++++++++-----------------
include/linux/spi/rspi.h | 2 +-
2 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 46232e3b6e8c..c7bbc54ef785 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.
@@ -167,6 +167,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;
@@ -178,12 +179,13 @@ struct rspi_data {
spinlock_t lock;
struct clk *clk;
u8 spsr;
+ int irq[MAX_NUM_IRQ];
+ unsigned int numirq;
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;
@@ -462,7 +464,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
const void *buf = NULL;
struct dma_async_tx_descriptor *desc;
unsigned len;
- int ret = 0;
+ int i, ret = 0;
if (rspi->dma_width_16bit) {
void *tmp;
@@ -499,7 +501,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->numirq; i++)
+ disable_irq(rspi->irq[i]);
rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
rspi_enable_irq(rspi, SPCR_SPTIE);
@@ -518,7 +521,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->numirq; i++)
+ enable_irq(rspi->irq[i]);
end:
rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
@@ -628,7 +632,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
void *dummy = NULL, *rx_buf = NULL;
struct dma_async_tx_descriptor *desc, *desc_dummy;
unsigned len;
- int ret = 0;
+ int i, ret = 0;
if (rspi->dma_width_16bit) {
/*
@@ -685,7 +689,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->numirq; i++)
+ disable_irq(rspi->irq[i]);
rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
@@ -708,7 +713,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->numirq; i++)
+ enable_irq(rspi->irq[i]);
end:
rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
@@ -918,7 +924,7 @@ static int rspi_probe(struct platform_device *pdev)
struct resource *res;
struct spi_master *master;
struct rspi_data *rspi;
- int ret, irq;
+ int i, ret, irq;
char clk_name[16];
const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
const struct spi_ops *ops;
@@ -931,12 +937,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");
@@ -948,6 +948,19 @@ static int rspi_probe(struct platform_device *pdev)
rspi->ops = ops;
rspi->master = master;
+ for (i = 0; i < MAX_NUM_IRQ; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (irq < 0) {
+ if (rspi->numirq)
+ break;
+ dev_err(&pdev->dev, "platform_get_irq error\n");
+ ret = -ENODEV;
+ goto error1;
+ }
+ rspi->irq[i] = irq;
+ rspi->numirq++;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rspi->addr = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(rspi->addr)) {
@@ -979,14 +992,16 @@ 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 < rspi->numirq; i++) {
+ ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
+ dev_name(&pdev->dev), rspi);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "request_irq %d error\n",
+ rspi->irq[i]);
+ goto error1;
+ }
}
- rspi->irq = irq;
ret = rspi_request_dma(rspi, pdev);
if (ret < 0) {
dev_err(&pdev->dev, "rspi_request_dma failed.\n");
diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
index a25bd6f65e7f..3f55232f74ff 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
--
1.7.9.5
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 4/8] spi: rspi: Add support for 8-bit Data Register access
[not found] ` <1387885248-28425-1-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
@ 2013-12-24 11:40 ` Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
1 sibling, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi-u79uwXL29TY76Z2rM5mHXA
Cc: linux-sh-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven
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@linux-m68k.org>
---
drivers/spi/spi-rspi.c | 90 +++++++++++++++++++++++++++++++++++++++-------
include/linux/spi/rspi.h | 2 ++
2 files changed, 79 insertions(+), 13 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index c7bbc54ef785..00788091fc16 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -179,6 +179,8 @@ struct rspi_data {
spinlock_t lock;
struct clk *clk;
u8 spsr;
+ u8 spdcr;
+ u8 data_width;
int irq[MAX_NUM_IRQ];
unsigned int numirq;
const struct spi_ops *ops;
@@ -216,8 +218,27 @@ 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 if (rspi->data_width = 16)
+ 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 if (rspi->data_width = 16)
+ return rspi_read16(rspi, RSPI_SPDR);
+ return 0;
+}
+
/* 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,
@@ -230,6 +251,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 -1;
+ }
+ } 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)
{
@@ -243,7 +291,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);
@@ -266,6 +314,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)
{
@@ -280,7 +338,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);
@@ -365,7 +423,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--;
}
@@ -392,14 +450,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--;
}
@@ -539,7 +597,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);
@@ -564,15 +622,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--;
@@ -587,7 +644,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);
}
@@ -609,15 +666,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--;
}
@@ -1002,6 +1058,12 @@ static int rspi_probe(struct platform_device *pdev)
}
}
+ ret = ops->parse_platform_data(rspi, rspi_pd);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "rspi invalid platform data.\n");
+ goto error1;
+ }
+
ret = rspi_request_dma(rspi, pdev);
if (ret < 0) {
dev_err(&pdev->dev, "rspi_request_dma failed.\n");
@@ -1027,12 +1089,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 3f55232f74ff..7316dd9c7ba9 100644
--- a/include/linux/spi/rspi.h
+++ b/include/linux/spi/rspi.h
@@ -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
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 4/8] spi: rspi: Add support for 8-bit Data Register access
@ 2013-12-24 11:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi-u79uwXL29TY76Z2rM5mHXA
Cc: linux-sh-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven
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>
---
drivers/spi/spi-rspi.c | 90 +++++++++++++++++++++++++++++++++++++++-------
include/linux/spi/rspi.h | 2 ++
2 files changed, 79 insertions(+), 13 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index c7bbc54ef785..00788091fc16 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -179,6 +179,8 @@ struct rspi_data {
spinlock_t lock;
struct clk *clk;
u8 spsr;
+ u8 spdcr;
+ u8 data_width;
int irq[MAX_NUM_IRQ];
unsigned int numirq;
const struct spi_ops *ops;
@@ -216,8 +218,27 @@ 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 if (rspi->data_width == 16)
+ 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 if (rspi->data_width == 16)
+ return rspi_read16(rspi, RSPI_SPDR);
+ return 0;
+}
+
/* 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,
@@ -230,6 +251,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 -1;
+ }
+ } 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)
{
@@ -243,7 +291,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);
@@ -266,6 +314,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)
{
@@ -280,7 +338,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);
@@ -365,7 +423,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--;
}
@@ -392,14 +450,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--;
}
@@ -539,7 +597,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);
@@ -564,15 +622,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--;
@@ -587,7 +644,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);
}
@@ -609,15 +666,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--;
}
@@ -1002,6 +1058,12 @@ static int rspi_probe(struct platform_device *pdev)
}
}
+ ret = ops->parse_platform_data(rspi, rspi_pd);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "rspi invalid platform data.\n");
+ goto error1;
+ }
+
ret = rspi_request_dma(rspi, pdev);
if (ret < 0) {
dev_err(&pdev->dev, "rspi_request_dma failed.\n");
@@ -1027,12 +1089,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 3f55232f74ff..7316dd9c7ba9 100644
--- a/include/linux/spi/rspi.h
+++ b/include/linux/spi/rspi.h
@@ -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] 36+ messages in thread
* [PATCH 5/8] spi: rspi: Add support for no TX only mode
2013-12-24 11:40 ` Geert Uytterhoeven
@ 2013-12-24 11:40 ` Geert Uytterhoeven
-1 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
Add support for RSPI variants lacking TX only mode, based on the SDK
reference code. This is needed for RZ/A1H.
The TX only mode flag is passed using platform data, defaulting to true for
legacy RSPI. QSPI nevers has TX only mode.
If TX only mode is not available, we have to wait for the receive interrupt
bit to become set, and perform a dummy read, in the transmit path.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
drivers/spi/spi-rspi.c | 50 ++++++++++++++++++++++++++++++++++++++++------
include/linux/spi/rspi.h | 1 +
2 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 00788091fc16..92aaa1eac5a9 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -191,6 +191,7 @@ struct rspi_data {
unsigned dma_width_16bit:1;
unsigned dma_callbacked:1;
+ unsigned txmode:1;
};
static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
@@ -251,6 +252,20 @@ struct spi_ops {
/*
* functions for RSPI
*/
+static void rspi_set_txmode(const struct rspi_data *rspi)
+{
+ if (rspi->txmode)
+ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
+ RSPI_SPCR);
+}
+
+static void rspi_clear_txmode(const struct rspi_data *rspi)
+{
+ if (rspi->txmode)
+ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD,
+ RSPI_SPCR);
+}
+
static int rspi_parse_platform_data(struct rspi_data *rspi,
const struct rspi_plat_data *rspi_pd)
{
@@ -275,6 +290,11 @@ static int rspi_parse_platform_data(struct rspi_data *rspi,
rspi->spdcr = 0;
}
+ if (rspi_pd)
+ rspi->txmode = rspi_pd->txmode;
+ else
+ rspi->txmode = 1; /* legacy RSPI defaults to true */
+
return 0;
}
@@ -321,6 +341,9 @@ static int qspi_parse_platform_data(struct rspi_data *rspi,
rspi->data_width = 8;
rspi->spdcr = 0;
+ /* No TX only mode */
+ rspi->txmode = 0;
+
return 0;
}
@@ -414,8 +437,7 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
int remain = t->len;
const u8 *data = t->tx_buf;
while (remain > 0) {
- rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
- RSPI_SPCR);
+ rspi_set_txmode(rspi);
if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
dev_err(&rspi->master->dev,
@@ -423,6 +445,15 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
return -ETIMEDOUT;
}
+ if (!rspi->txmode && remain != t->len) {
+ if (rspi_wait_for_interrupt(rspi, SPSR_SPRF,
+ SPCR_SPRIE) < 0) {
+ dev_err(&rspi->master->dev,
+ "%s: receive timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+ rspi_read_data(rspi); /* dummy read */
+ }
rspi_write_data(rspi, *data);
data++;
remain--;
@@ -431,6 +462,14 @@ 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_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
+ dev_err(&rspi->master->dev,
+ "%s: receive timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+ rspi_read_data(rspi); /* dummy read */
+ }
return 0;
}
@@ -562,7 +601,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
for (i = 0; i < rspi->numirq; i++)
disable_irq(rspi->irq[i]);
- rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
+ rspi_set_txmode(rspi);
rspi_enable_irq(rspi, SPCR_SPTIE);
rspi->dma_callbacked = 0;
@@ -613,8 +652,7 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
data = t->rx_buf;
while (remain > 0) {
- rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD,
- RSPI_SPCR);
+ rspi_clear_txmode(rspi);
if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
dev_err(&rspi->master->dev,
@@ -748,7 +786,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
for (i = 0; i < rspi->numirq; i++)
disable_irq(rspi->irq[i]);
- rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
+ rspi_clear_txmode(rspi);
rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
rspi->dma_callbacked = 0;
diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
index 7316dd9c7ba9..0f5f612f0092 100644
--- a/include/linux/spi/rspi.h
+++ b/include/linux/spi/rspi.h
@@ -28,6 +28,7 @@ struct rspi_plat_data {
unsigned int dma_rx_id;
unsigned dma_width_16bit:1; /* DMAC read/write width = 16-bit */
+ unsigned txmode:1; /* TX only mode */
u16 num_chipselect;
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 5/8] spi: rspi: Add support for no TX only mode
@ 2013-12-24 11:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
Add support for RSPI variants lacking TX only mode, based on the SDK
reference code. This is needed for RZ/A1H.
The TX only mode flag is passed using platform data, defaulting to true for
legacy RSPI. QSPI nevers has TX only mode.
If TX only mode is not available, we have to wait for the receive interrupt
bit to become set, and perform a dummy read, in the transmit path.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
drivers/spi/spi-rspi.c | 50 ++++++++++++++++++++++++++++++++++++++++------
include/linux/spi/rspi.h | 1 +
2 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 00788091fc16..92aaa1eac5a9 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -191,6 +191,7 @@ struct rspi_data {
unsigned dma_width_16bit:1;
unsigned dma_callbacked:1;
+ unsigned txmode:1;
};
static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
@@ -251,6 +252,20 @@ struct spi_ops {
/*
* functions for RSPI
*/
+static void rspi_set_txmode(const struct rspi_data *rspi)
+{
+ if (rspi->txmode)
+ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
+ RSPI_SPCR);
+}
+
+static void rspi_clear_txmode(const struct rspi_data *rspi)
+{
+ if (rspi->txmode)
+ rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD,
+ RSPI_SPCR);
+}
+
static int rspi_parse_platform_data(struct rspi_data *rspi,
const struct rspi_plat_data *rspi_pd)
{
@@ -275,6 +290,11 @@ static int rspi_parse_platform_data(struct rspi_data *rspi,
rspi->spdcr = 0;
}
+ if (rspi_pd)
+ rspi->txmode = rspi_pd->txmode;
+ else
+ rspi->txmode = 1; /* legacy RSPI defaults to true */
+
return 0;
}
@@ -321,6 +341,9 @@ static int qspi_parse_platform_data(struct rspi_data *rspi,
rspi->data_width = 8;
rspi->spdcr = 0;
+ /* No TX only mode */
+ rspi->txmode = 0;
+
return 0;
}
@@ -414,8 +437,7 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
int remain = t->len;
const u8 *data = t->tx_buf;
while (remain > 0) {
- rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
- RSPI_SPCR);
+ rspi_set_txmode(rspi);
if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
dev_err(&rspi->master->dev,
@@ -423,6 +445,15 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
return -ETIMEDOUT;
}
+ if (!rspi->txmode && remain != t->len) {
+ if (rspi_wait_for_interrupt(rspi, SPSR_SPRF,
+ SPCR_SPRIE) < 0) {
+ dev_err(&rspi->master->dev,
+ "%s: receive timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+ rspi_read_data(rspi); /* dummy read */
+ }
rspi_write_data(rspi, *data);
data++;
remain--;
@@ -431,6 +462,14 @@ 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_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
+ dev_err(&rspi->master->dev,
+ "%s: receive timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+ rspi_read_data(rspi); /* dummy read */
+ }
return 0;
}
@@ -562,7 +601,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
for (i = 0; i < rspi->numirq; i++)
disable_irq(rspi->irq[i]);
- rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
+ rspi_set_txmode(rspi);
rspi_enable_irq(rspi, SPCR_SPTIE);
rspi->dma_callbacked = 0;
@@ -613,8 +652,7 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
data = t->rx_buf;
while (remain > 0) {
- rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD,
- RSPI_SPCR);
+ rspi_clear_txmode(rspi);
if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
dev_err(&rspi->master->dev,
@@ -748,7 +786,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
for (i = 0; i < rspi->numirq; i++)
disable_irq(rspi->irq[i]);
- rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
+ rspi_clear_txmode(rspi);
rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
rspi->dma_callbacked = 0;
diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
index 7316dd9c7ba9..0f5f612f0092 100644
--- a/include/linux/spi/rspi.h
+++ b/include/linux/spi/rspi.h
@@ -28,6 +28,7 @@ struct rspi_plat_data {
unsigned int dma_rx_id;
unsigned dma_width_16bit:1; /* DMAC read/write width = 16-bit */
+ unsigned txmode:1; /* TX only mode */
u16 num_chipselect;
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 6/8] spi: rspi: Add support for missing SPCR2 register
2013-12-24 11:40 ` Geert Uytterhoeven
@ 2013-12-24 11:40 ` Geert Uytterhoeven
-1 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
Add support for RSPI variants lacking the RSPI Control Register 2, based on
the SDK reference code. This is needed for RZ/A1H.
The availability of this register is passed using platform data, defaulting
to true for legacy RSPI. QSPI never has this register.
If the register is not available, it should not be touched.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
drivers/spi/spi-rspi.c | 17 ++++++++++++-----
include/linux/spi/rspi.h | 1 +
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 92aaa1eac5a9..34674fe6df5d 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -192,6 +192,7 @@ struct rspi_data {
unsigned dma_width_16bit:1;
unsigned dma_callbacked:1;
unsigned txmode:1;
+ unsigned spcr2:1;
};
static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
@@ -290,10 +291,14 @@ static int rspi_parse_platform_data(struct rspi_data *rspi,
rspi->spdcr = 0;
}
- if (rspi_pd)
+ if (rspi_pd) {
rspi->txmode = rspi_pd->txmode;
- else
- rspi->txmode = 1; /* legacy RSPI defaults to true */
+ rspi->spcr2 = rspi_pd->spcr2;
+ } else {
+ /* legacy RSPI defaults to true */
+ rspi->txmode = 1;
+ rspi->spcr2 = 1;
+ }
return 0;
}
@@ -319,7 +324,8 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
rspi_write8(rspi, 0x00, RSPI_SPND);
/* Sets parity, interrupt mask */
- rspi_write8(rspi, 0x00, RSPI_SPCR2);
+ if (rspi->spcr2)
+ rspi_write8(rspi, 0x00, RSPI_SPCR2);
/* Sets SPCMD */
rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP,
@@ -341,8 +347,9 @@ static int qspi_parse_platform_data(struct rspi_data *rspi,
rspi->data_width = 8;
rspi->spdcr = 0;
- /* No TX only mode */
+ /* No TX only mode, no parity register */
rspi->txmode = 0;
+ rspi->spcr2 = 0;
return 0;
}
diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
index 0f5f612f0092..08d217f25413 100644
--- a/include/linux/spi/rspi.h
+++ b/include/linux/spi/rspi.h
@@ -29,6 +29,7 @@ struct rspi_plat_data {
unsigned dma_width_16bit:1; /* DMAC read/write width = 16-bit */
unsigned txmode:1; /* TX only mode */
+ unsigned spcr2:1; /* Set parity register */
u16 num_chipselect;
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 6/8] spi: rspi: Add support for missing SPCR2 register
@ 2013-12-24 11:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
Add support for RSPI variants lacking the RSPI Control Register 2, based on
the SDK reference code. This is needed for RZ/A1H.
The availability of this register is passed using platform data, defaulting
to true for legacy RSPI. QSPI never has this register.
If the register is not available, it should not be touched.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
drivers/spi/spi-rspi.c | 17 ++++++++++++-----
include/linux/spi/rspi.h | 1 +
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 92aaa1eac5a9..34674fe6df5d 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -192,6 +192,7 @@ struct rspi_data {
unsigned dma_width_16bit:1;
unsigned dma_callbacked:1;
unsigned txmode:1;
+ unsigned spcr2:1;
};
static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
@@ -290,10 +291,14 @@ static int rspi_parse_platform_data(struct rspi_data *rspi,
rspi->spdcr = 0;
}
- if (rspi_pd)
+ if (rspi_pd) {
rspi->txmode = rspi_pd->txmode;
- else
- rspi->txmode = 1; /* legacy RSPI defaults to true */
+ rspi->spcr2 = rspi_pd->spcr2;
+ } else {
+ /* legacy RSPI defaults to true */
+ rspi->txmode = 1;
+ rspi->spcr2 = 1;
+ }
return 0;
}
@@ -319,7 +324,8 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
rspi_write8(rspi, 0x00, RSPI_SPND);
/* Sets parity, interrupt mask */
- rspi_write8(rspi, 0x00, RSPI_SPCR2);
+ if (rspi->spcr2)
+ rspi_write8(rspi, 0x00, RSPI_SPCR2);
/* Sets SPCMD */
rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP,
@@ -341,8 +347,9 @@ static int qspi_parse_platform_data(struct rspi_data *rspi,
rspi->data_width = 8;
rspi->spdcr = 0;
- /* No TX only mode */
+ /* No TX only mode, no parity register */
rspi->txmode = 0;
+ rspi->spcr2 = 0;
return 0;
}
diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
index 0f5f612f0092..08d217f25413 100644
--- a/include/linux/spi/rspi.h
+++ b/include/linux/spi/rspi.h
@@ -29,6 +29,7 @@ struct rspi_plat_data {
unsigned dma_width_16bit:1; /* DMAC read/write width = 16-bit */
unsigned txmode:1; /* TX only mode */
+ unsigned spcr2:1; /* Set parity register */
u16 num_chipselect;
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 7/8] spi: rspi: Add support for specifying CPHA/CPOL
2013-12-24 11:40 ` Geert Uytterhoeven
@ 2013-12-24 11:40 ` Geert Uytterhoeven
-1 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
Add support for specifying the SPI clock phase and polarity, based on the
SDK reference code.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
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 34674fe6df5d..850025278519 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -181,6 +181,7 @@ struct rspi_data {
u8 spsr;
u8 spdcr;
u8 data_width;
+ u16 spcmd;
int irq[MAX_NUM_IRQ];
unsigned int numirq;
const struct spi_ops *ops;
@@ -328,7 +329,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 */
@@ -383,7 +384,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);
@@ -903,6 +904,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;
@@ -1092,6 +1099,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;
for (i = 0; i < rspi->numirq; i++) {
ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 7/8] spi: rspi: Add support for specifying CPHA/CPOL
@ 2013-12-24 11:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
Add support for specifying the SPI clock phase and polarity, based on the
SDK reference code.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
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 34674fe6df5d..850025278519 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -181,6 +181,7 @@ struct rspi_data {
u8 spsr;
u8 spdcr;
u8 data_width;
+ u16 spcmd;
int irq[MAX_NUM_IRQ];
unsigned int numirq;
const struct spi_ops *ops;
@@ -328,7 +329,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 */
@@ -383,7 +384,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);
@@ -903,6 +904,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;
@@ -1092,6 +1099,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;
for (i = 0; i < rspi->numirq; i++) {
ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 8/8] spi: rspi: Add support for loopback mode
2013-12-24 11:40 ` Geert Uytterhoeven
@ 2013-12-24 11:40 ` Geert Uytterhoeven
-1 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
Add support for specifying loopback mode for RSPI only, based on the SDK
reference code.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
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 850025278519..c8f51a3978e1 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -161,8 +161,8 @@
#define SPCMD_SPRW 0x0060 /* SPI Read/Write Access */
/* 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 */
@@ -179,6 +179,7 @@ struct rspi_data {
spinlock_t lock;
struct clk *clk;
u8 spsr;
+ u8 sppcr;
u8 spdcr;
u8 data_width;
u16 spcmd;
@@ -248,7 +249,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;
};
/*
@@ -309,8 +310,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;
@@ -361,8 +362,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);
@@ -405,6 +406,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);
@@ -444,6 +460,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);
@@ -453,7 +476,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,
@@ -470,7 +494,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__);
@@ -643,7 +667,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,
@@ -681,6 +705,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;
}
@@ -910,6 +940,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;
@@ -1099,7 +1134,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;
for (i = 0; i < rspi->numirq; i++) {
ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
@@ -1146,6 +1181,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 = {
@@ -1153,6 +1189,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
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 8/8] spi: rspi: Add support for loopback mode
@ 2013-12-24 11:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-24 11:40 UTC (permalink / raw)
To: linux-spi; +Cc: linux-sh, Geert Uytterhoeven
Add support for specifying loopback mode for RSPI only, based on the SDK
reference code.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
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 850025278519..c8f51a3978e1 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -161,8 +161,8 @@
#define SPCMD_SPRW 0x0060 /* SPI Read/Write Access */
/* 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 */
@@ -179,6 +179,7 @@ struct rspi_data {
spinlock_t lock;
struct clk *clk;
u8 spsr;
+ u8 sppcr;
u8 spdcr;
u8 data_width;
u16 spcmd;
@@ -248,7 +249,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;
};
/*
@@ -309,8 +310,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;
@@ -361,8 +362,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);
@@ -405,6 +406,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);
@@ -444,6 +460,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);
@@ -453,7 +476,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,
@@ -470,7 +494,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__);
@@ -643,7 +667,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,
@@ -681,6 +705,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;
}
@@ -910,6 +940,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;
@@ -1099,7 +1134,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;
for (i = 0; i < rspi->numirq; i++) {
ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
@@ -1146,6 +1181,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 = {
@@ -1153,6 +1189,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
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH 0/8] spi: rspi: Add prelimary support for RZ/A1H
2013-12-24 11:40 ` Geert Uytterhoeven
@ 2013-12-27 19:22 ` Geert Uytterhoeven
-1 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-27 19:22 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-spi, Linux-sh list
On Tue, Dec 24, 2013 at 12:40 PM, Geert Uytterhoeven
<geert+renesas@linux-m68k.org> wrote:
> This patch series adds preliminary support for RSPI in the RZ/A1H aka
> R7S72100 SoC, which is found on the Genmai development board.
>
> It hasn't received much testing, so please don't apply yet.
In the mean time this has received some more testing on the Genmai
development board, using loopback mode, with the same outcome as
the SDK reference code.
> [1/8] spi: rspi: Add more RSPI register documentation
> [2/8] spi: rspi: Add more QSPI register documentation
> [3/8] spi: rspi: Add support for more than one interrupt
> [4/8] spi: rspi: Add support for 8-bit Data Register access
> [5/8] spi: rspi: Add support for no TX only mode
> [6/8] spi: rspi: Add support for missing SPCR2 register
> [7/8] spi: rspi: Add support for specifying CPHA/CPOL
> [8/8] spi: rspi: Add support for loopback mode
No changes needed to the code, one silly spelling typo in the summary
of [5/8] (s/nevers/never/). Anyway, will resend the series later.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/8] spi: rspi: Add prelimary support for RZ/A1H
@ 2013-12-27 19:22 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2013-12-27 19:22 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-spi, Linux-sh list
On Tue, Dec 24, 2013 at 12:40 PM, Geert Uytterhoeven
<geert+renesas@linux-m68k.org> wrote:
> This patch series adds preliminary support for RSPI in the RZ/A1H aka
> R7S72100 SoC, which is found on the Genmai development board.
>
> It hasn't received much testing, so please don't apply yet.
In the mean time this has received some more testing on the Genmai
development board, using loopback mode, with the same outcome as
the SDK reference code.
> [1/8] spi: rspi: Add more RSPI register documentation
> [2/8] spi: rspi: Add more QSPI register documentation
> [3/8] spi: rspi: Add support for more than one interrupt
> [4/8] spi: rspi: Add support for 8-bit Data Register access
> [5/8] spi: rspi: Add support for no TX only mode
> [6/8] spi: rspi: Add support for missing SPCR2 register
> [7/8] spi: rspi: Add support for specifying CPHA/CPOL
> [8/8] spi: rspi: Add support for loopback mode
No changes needed to the code, one silly spelling typo in the summary
of [5/8] (s/nevers/never/). Anyway, will resend the series later.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 1/8] spi: rspi: Add more RSPI register documentation
[not found] ` <1387885248-28425-2-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
@ 2013-12-30 23:31 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:31 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:41 Geert Uytterhoeven wrote:
> Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 1/8] spi: rspi: Add more RSPI register documentation
@ 2013-12-30 23:31 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:31 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:41 Geert Uytterhoeven wrote:
> Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Acked-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
--
Regards,
Laurent Pinchart
--
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 [flat|nested] 36+ messages in thread
* Re: [PATCH 2/8] spi: rspi: Add more QSPI register documentation
[not found] ` <1387885248-28425-3-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
@ 2013-12-30 23:31 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:31 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:42 Geert Uytterhoeven wrote:
> Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 2/8] spi: rspi: Add more QSPI register documentation
@ 2013-12-30 23:31 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:31 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:42 Geert Uytterhoeven wrote:
> Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Acked-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
--
Regards,
Laurent Pinchart
--
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 [flat|nested] 36+ messages in thread
* Re: [PATCH 3/8] spi: rspi: Add support for more than one interrupt
[not found] ` <1387885248-28425-4-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
@ 2013-12-30 23:38 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:38 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:43 Geert Uytterhoeven wrote:
> 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@linux-m68k.org>
> ---
> drivers/spi/spi-rspi.c | 57 +++++++++++++++++++++++++++----------------
> include/linux/spi/rspi.h | 2 +-
> 2 files changed, 37 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
> index 46232e3b6e8c..c7bbc54ef785 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.
> @@ -167,6 +167,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;
> @@ -178,12 +179,13 @@ struct rspi_data {
> spinlock_t lock;
> struct clk *clk;
> u8 spsr;
> + int irq[MAX_NUM_IRQ];
Should this field be called irqs ?
> + unsigned int numirq;
This driver seems to use underscores to separate words in variable names,
maybe you could use num_irq (or num_irqs) instead.
> 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;
> @@ -462,7 +464,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct
> spi_transfer *t) const void *buf = NULL;
> struct dma_async_tx_descriptor *desc;
> unsigned len;
> - int ret = 0;
> + int i, ret = 0;
i is an unsigned loop index, could you please make it an unsigned int ?
> if (rspi->dma_width_16bit) {
> void *tmp;
> @@ -499,7 +501,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->numirq; i++)
> + disable_irq(rspi->irq[i]);
>
> rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
> rspi_enable_irq(rspi, SPCR_SPTIE);
> @@ -518,7 +521,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->numirq; i++)
> + enable_irq(rspi->irq[i]);
>
> end:
> rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
> @@ -628,7 +632,7 @@ static int rspi_receive_dma(struct rspi_data *rspi,
> struct spi_transfer *t) void *dummy = NULL, *rx_buf = NULL;
> struct dma_async_tx_descriptor *desc, *desc_dummy;
> unsigned len;
> - int ret = 0;
> + int i, ret = 0;
Same here.
> if (rspi->dma_width_16bit) {
> /*
> @@ -685,7 +689,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->numirq; i++)
> + disable_irq(rspi->irq[i]);
>
> rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
> rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
> @@ -708,7 +713,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->numirq; i++)
> + enable_irq(rspi->irq[i]);
>
> end:
> rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
> @@ -918,7 +924,7 @@ static int rspi_probe(struct platform_device *pdev)
> struct resource *res;
> struct spi_master *master;
> struct rspi_data *rspi;
> - int ret, irq;
> + int i, ret, irq;
Same here.
> char clk_name[16];
> const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
> const struct spi_ops *ops;
> @@ -931,12 +937,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");
> @@ -948,6 +948,19 @@ static int rspi_probe(struct platform_device *pdev)
> rspi->ops = ops;
> rspi->master = master;
>
> + for (i = 0; i < MAX_NUM_IRQ; i++) {
> + irq = platform_get_irq(pdev, i);
> + if (irq < 0) {
> + if (rspi->numirq)
> + break;
> + dev_err(&pdev->dev, "platform_get_irq error\n");
> + ret = -ENODEV;
> + goto error1;
> + }
> + rspi->irq[i] = irq;
> + rspi->numirq++;
> + }
> +
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> rspi->addr = devm_ioremap_resource(&pdev->dev, res);
> if (IS_ERR(rspi->addr)) {
> @@ -979,14 +992,16 @@ 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 < rspi->numirq; i++) {
> + ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
> + dev_name(&pdev->dev), rspi);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "request_irq %d error\n",
> + rspi->irq[i]);
> + goto error1;
> + }
> }
Just an idea, what about combining the two loops ?
> - rspi->irq = irq;
> ret = rspi_request_dma(rspi, pdev);
> if (ret < 0) {
> dev_err(&pdev->dev, "rspi_request_dma failed.\n");
> diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
> index a25bd6f65e7f..3f55232f74ff 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
This change seems to be unrelated. You might want to squash it into patch 1/8.
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 3/8] spi: rspi: Add support for more than one interrupt
@ 2013-12-30 23:38 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:38 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:43 Geert Uytterhoeven wrote:
> 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>
> ---
> drivers/spi/spi-rspi.c | 57 +++++++++++++++++++++++++++----------------
> include/linux/spi/rspi.h | 2 +-
> 2 files changed, 37 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
> index 46232e3b6e8c..c7bbc54ef785 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.
> @@ -167,6 +167,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;
> @@ -178,12 +179,13 @@ struct rspi_data {
> spinlock_t lock;
> struct clk *clk;
> u8 spsr;
> + int irq[MAX_NUM_IRQ];
Should this field be called irqs ?
> + unsigned int numirq;
This driver seems to use underscores to separate words in variable names,
maybe you could use num_irq (or num_irqs) instead.
> 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;
> @@ -462,7 +464,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct
> spi_transfer *t) const void *buf = NULL;
> struct dma_async_tx_descriptor *desc;
> unsigned len;
> - int ret = 0;
> + int i, ret = 0;
i is an unsigned loop index, could you please make it an unsigned int ?
> if (rspi->dma_width_16bit) {
> void *tmp;
> @@ -499,7 +501,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->numirq; i++)
> + disable_irq(rspi->irq[i]);
>
> rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
> rspi_enable_irq(rspi, SPCR_SPTIE);
> @@ -518,7 +521,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->numirq; i++)
> + enable_irq(rspi->irq[i]);
>
> end:
> rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
> @@ -628,7 +632,7 @@ static int rspi_receive_dma(struct rspi_data *rspi,
> struct spi_transfer *t) void *dummy = NULL, *rx_buf = NULL;
> struct dma_async_tx_descriptor *desc, *desc_dummy;
> unsigned len;
> - int ret = 0;
> + int i, ret = 0;
Same here.
> if (rspi->dma_width_16bit) {
> /*
> @@ -685,7 +689,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->numirq; i++)
> + disable_irq(rspi->irq[i]);
>
> rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
> rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
> @@ -708,7 +713,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->numirq; i++)
> + enable_irq(rspi->irq[i]);
>
> end:
> rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
> @@ -918,7 +924,7 @@ static int rspi_probe(struct platform_device *pdev)
> struct resource *res;
> struct spi_master *master;
> struct rspi_data *rspi;
> - int ret, irq;
> + int i, ret, irq;
Same here.
> char clk_name[16];
> const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
> const struct spi_ops *ops;
> @@ -931,12 +937,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");
> @@ -948,6 +948,19 @@ static int rspi_probe(struct platform_device *pdev)
> rspi->ops = ops;
> rspi->master = master;
>
> + for (i = 0; i < MAX_NUM_IRQ; i++) {
> + irq = platform_get_irq(pdev, i);
> + if (irq < 0) {
> + if (rspi->numirq)
> + break;
> + dev_err(&pdev->dev, "platform_get_irq error\n");
> + ret = -ENODEV;
> + goto error1;
> + }
> + rspi->irq[i] = irq;
> + rspi->numirq++;
> + }
> +
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> rspi->addr = devm_ioremap_resource(&pdev->dev, res);
> if (IS_ERR(rspi->addr)) {
> @@ -979,14 +992,16 @@ 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 < rspi->numirq; i++) {
> + ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
> + dev_name(&pdev->dev), rspi);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "request_irq %d error\n",
> + rspi->irq[i]);
> + goto error1;
> + }
> }
Just an idea, what about combining the two loops ?
> - rspi->irq = irq;
> ret = rspi_request_dma(rspi, pdev);
> if (ret < 0) {
> dev_err(&pdev->dev, "rspi_request_dma failed.\n");
> diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
> index a25bd6f65e7f..3f55232f74ff 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
This change seems to be unrelated. You might want to squash it into patch 1/8.
--
Regards,
Laurent Pinchart
--
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 [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] spi: rspi: Add support for 8-bit Data Register access
[not found] ` <1387885248-28425-5-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
@ 2013-12-30 23:47 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:47 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:44 Geert Uytterhoeven wrote:
> 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@linux-m68k.org>
> ---
> drivers/spi/spi-rspi.c | 90 ++++++++++++++++++++++++++++++++++++-------
> include/linux/spi/rspi.h | 2 ++
> 2 files changed, 79 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
> index c7bbc54ef785..00788091fc16 100644
> --- a/drivers/spi/spi-rspi.c
> +++ b/drivers/spi/spi-rspi.c
> @@ -179,6 +179,8 @@ struct rspi_data {
> spinlock_t lock;
> struct clk *clk;
> u8 spsr;
> + u8 spdcr;
> + u8 data_width;
> int irq[MAX_NUM_IRQ];
> unsigned int numirq;
> const struct spi_ops *ops;
> @@ -216,8 +218,27 @@ 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 if (rspi->data_width = 16)
> + rspi_write16(rspi, data, RSPI_SPDR);
As the driver only handles 8-bits and 16-bits data, replacing the else if with
an else should be more efficient.
> +}
> +
> +static u16 rspi_read_data(const struct rspi_data *rspi)
> +{
> + if (rspi->data_width = 8)
> + return rspi_read8(rspi, RSPI_SPDR);
> + else if (rspi->data_width = 16)
> + return rspi_read16(rspi, RSPI_SPDR);
Same here.
> + return 0;
> +}
> +
> /* 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,
> @@ -230,6 +251,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 -1;
Shouldn't you return a defined error code (-EINVAL maybe) ?
> + }
> + } 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)
> {
> @@ -243,7 +291,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);
> @@ -266,6 +314,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)
> {
> @@ -280,7 +338,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);
> @@ -365,7 +423,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--;
> }
> @@ -392,14 +450,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--;
> }
> @@ -539,7 +597,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);
> @@ -564,15 +622,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--;
> @@ -587,7 +644,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);
> }
> @@ -609,15 +666,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--;
> }
>
> @@ -1002,6 +1058,12 @@ static int rspi_probe(struct platform_device *pdev)
> }
> }
>
> + ret = ops->parse_platform_data(rspi, rspi_pd);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "rspi invalid platform data.\n");
> + goto error1;
> + }
> +
> ret = rspi_request_dma(rspi, pdev);
> if (ret < 0) {
> dev_err(&pdev->dev, "rspi_request_dma failed.\n");
> @@ -1027,12 +1089,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 3f55232f74ff..7316dd9c7ba9 100644
> --- a/include/linux/spi/rspi.h
> +++ b/include/linux/spi/rspi.h
> @@ -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;
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] spi: rspi: Add support for 8-bit Data Register access
@ 2013-12-30 23:47 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:47 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:44 Geert Uytterhoeven wrote:
> 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>
> ---
> drivers/spi/spi-rspi.c | 90 ++++++++++++++++++++++++++++++++++++-------
> include/linux/spi/rspi.h | 2 ++
> 2 files changed, 79 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
> index c7bbc54ef785..00788091fc16 100644
> --- a/drivers/spi/spi-rspi.c
> +++ b/drivers/spi/spi-rspi.c
> @@ -179,6 +179,8 @@ struct rspi_data {
> spinlock_t lock;
> struct clk *clk;
> u8 spsr;
> + u8 spdcr;
> + u8 data_width;
> int irq[MAX_NUM_IRQ];
> unsigned int numirq;
> const struct spi_ops *ops;
> @@ -216,8 +218,27 @@ 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 if (rspi->data_width == 16)
> + rspi_write16(rspi, data, RSPI_SPDR);
As the driver only handles 8-bits and 16-bits data, replacing the else if with
an else should be more efficient.
> +}
> +
> +static u16 rspi_read_data(const struct rspi_data *rspi)
> +{
> + if (rspi->data_width == 8)
> + return rspi_read8(rspi, RSPI_SPDR);
> + else if (rspi->data_width == 16)
> + return rspi_read16(rspi, RSPI_SPDR);
Same here.
> + return 0;
> +}
> +
> /* 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,
> @@ -230,6 +251,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 -1;
Shouldn't you return a defined error code (-EINVAL maybe) ?
> + }
> + } 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)
> {
> @@ -243,7 +291,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);
> @@ -266,6 +314,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)
> {
> @@ -280,7 +338,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);
> @@ -365,7 +423,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--;
> }
> @@ -392,14 +450,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--;
> }
> @@ -539,7 +597,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);
> @@ -564,15 +622,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--;
> @@ -587,7 +644,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);
> }
> @@ -609,15 +666,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--;
> }
>
> @@ -1002,6 +1058,12 @@ static int rspi_probe(struct platform_device *pdev)
> }
> }
>
> + ret = ops->parse_platform_data(rspi, rspi_pd);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "rspi invalid platform data.\n");
> + goto error1;
> + }
> +
> ret = rspi_request_dma(rspi, pdev);
> if (ret < 0) {
> dev_err(&pdev->dev, "rspi_request_dma failed.\n");
> @@ -1027,12 +1089,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 3f55232f74ff..7316dd9c7ba9 100644
> --- a/include/linux/spi/rspi.h
> +++ b/include/linux/spi/rspi.h
> @@ -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;
--
Regards,
Laurent Pinchart
--
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 [flat|nested] 36+ messages in thread
* Re: [PATCH 6/8] spi: rspi: Add support for missing SPCR2 register
[not found] ` <1387885248-28425-7-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
@ 2013-12-30 23:52 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:52 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:46 Geert Uytterhoeven wrote:
> Add support for RSPI variants lacking the RSPI Control Register 2, based on
> the SDK reference code. This is needed for RZ/A1H.
>
> The availability of this register is passed using platform data, defaulting
> to true for legacy RSPI. QSPI never has this register.
>
> If the register is not available, it should not be touched.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> drivers/spi/spi-rspi.c | 17 ++++++++++++-----
> include/linux/spi/rspi.h | 1 +
> 2 files changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
> index 92aaa1eac5a9..34674fe6df5d 100644
> --- a/drivers/spi/spi-rspi.c
> +++ b/drivers/spi/spi-rspi.c
> @@ -192,6 +192,7 @@ struct rspi_data {
> unsigned dma_width_16bit:1;
> unsigned dma_callbacked:1;
> unsigned txmode:1;
> + unsigned spcr2:1;
> };
>
> static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
> @@ -290,10 +291,14 @@ static int rspi_parse_platform_data(struct rspi_data
> *rspi, rspi->spdcr = 0;
> }
>
> - if (rspi_pd)
> + if (rspi_pd) {
> rspi->txmode = rspi_pd->txmode;
> - else
> - rspi->txmode = 1; /* legacy RSPI defaults to true */
> + rspi->spcr2 = rspi_pd->spcr2;
> + } else {
> + /* legacy RSPI defaults to true */
> + rspi->txmode = 1;
> + rspi->spcr2 = 1;
> + }
>
> return 0;
> }
> @@ -319,7 +324,8 @@ static int rspi_set_config_register(const struct
> rspi_data *rspi, rspi_write8(rspi, 0x00, RSPI_SPND);
>
> /* Sets parity, interrupt mask */
> - rspi_write8(rspi, 0x00, RSPI_SPCR2);
> + if (rspi->spcr2)
> + rspi_write8(rspi, 0x00, RSPI_SPCR2);
>
> /* Sets SPCMD */
> rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP,
> @@ -341,8 +347,9 @@ static int qspi_parse_platform_data(struct rspi_data
> *rspi, rspi->data_width = 8;
> rspi->spdcr = 0;
>
> - /* No TX only mode */
> + /* No TX only mode, no parity register */
> rspi->txmode = 0;
> + rspi->spcr2 = 0;
>
> return 0;
> }
> diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
> index 0f5f612f0092..08d217f25413 100644
> --- a/include/linux/spi/rspi.h
> +++ b/include/linux/spi/rspi.h
> @@ -29,6 +29,7 @@ struct rspi_plat_data {
>
> unsigned dma_width_16bit:1; /* DMAC read/write width = 16-bit */
> unsigned txmode:1; /* TX only mode */
> + unsigned spcr2:1; /* Set parity register */
>
> u16 num_chipselect;
> };
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 6/8] spi: rspi: Add support for missing SPCR2 register
@ 2013-12-30 23:52 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:52 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:46 Geert Uytterhoeven wrote:
> Add support for RSPI variants lacking the RSPI Control Register 2, based on
> the SDK reference code. This is needed for RZ/A1H.
>
> The availability of this register is passed using platform data, defaulting
> to true for legacy RSPI. QSPI never has this register.
>
> If the register is not available, it should not be touched.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Acked-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
> ---
> drivers/spi/spi-rspi.c | 17 ++++++++++++-----
> include/linux/spi/rspi.h | 1 +
> 2 files changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
> index 92aaa1eac5a9..34674fe6df5d 100644
> --- a/drivers/spi/spi-rspi.c
> +++ b/drivers/spi/spi-rspi.c
> @@ -192,6 +192,7 @@ struct rspi_data {
> unsigned dma_width_16bit:1;
> unsigned dma_callbacked:1;
> unsigned txmode:1;
> + unsigned spcr2:1;
> };
>
> static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
> @@ -290,10 +291,14 @@ static int rspi_parse_platform_data(struct rspi_data
> *rspi, rspi->spdcr = 0;
> }
>
> - if (rspi_pd)
> + if (rspi_pd) {
> rspi->txmode = rspi_pd->txmode;
> - else
> - rspi->txmode = 1; /* legacy RSPI defaults to true */
> + rspi->spcr2 = rspi_pd->spcr2;
> + } else {
> + /* legacy RSPI defaults to true */
> + rspi->txmode = 1;
> + rspi->spcr2 = 1;
> + }
>
> return 0;
> }
> @@ -319,7 +324,8 @@ static int rspi_set_config_register(const struct
> rspi_data *rspi, rspi_write8(rspi, 0x00, RSPI_SPND);
>
> /* Sets parity, interrupt mask */
> - rspi_write8(rspi, 0x00, RSPI_SPCR2);
> + if (rspi->spcr2)
> + rspi_write8(rspi, 0x00, RSPI_SPCR2);
>
> /* Sets SPCMD */
> rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP,
> @@ -341,8 +347,9 @@ static int qspi_parse_platform_data(struct rspi_data
> *rspi, rspi->data_width = 8;
> rspi->spdcr = 0;
>
> - /* No TX only mode */
> + /* No TX only mode, no parity register */
> rspi->txmode = 0;
> + rspi->spcr2 = 0;
>
> return 0;
> }
> diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h
> index 0f5f612f0092..08d217f25413 100644
> --- a/include/linux/spi/rspi.h
> +++ b/include/linux/spi/rspi.h
> @@ -29,6 +29,7 @@ struct rspi_plat_data {
>
> unsigned dma_width_16bit:1; /* DMAC read/write width = 16-bit */
> unsigned txmode:1; /* TX only mode */
> + unsigned spcr2:1; /* Set parity register */
>
> u16 num_chipselect;
> };
--
Regards,
Laurent Pinchart
--
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 [flat|nested] 36+ messages in thread
* Re: [PATCH 7/8] spi: rspi: Add support for specifying CPHA/CPOL
[not found] ` <1387885248-28425-8-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
@ 2013-12-30 23:53 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:53 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:47 Geert Uytterhoeven wrote:
> Add support for specifying the SPI clock phase and polarity, based on the
> SDK reference code.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> 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 34674fe6df5d..850025278519 100644
> --- a/drivers/spi/spi-rspi.c
> +++ b/drivers/spi/spi-rspi.c
> @@ -181,6 +181,7 @@ struct rspi_data {
> u8 spsr;
> u8 spdcr;
> u8 data_width;
> + u16 spcmd;
> int irq[MAX_NUM_IRQ];
> unsigned int numirq;
> const struct spi_ops *ops;
> @@ -328,7 +329,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 */
> @@ -383,7 +384,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);
> @@ -903,6 +904,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;
> @@ -1092,6 +1099,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;
>
> for (i = 0; i < rspi->numirq; i++) {
> ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 7/8] spi: rspi: Add support for specifying CPHA/CPOL
@ 2013-12-30 23:53 ` Laurent Pinchart
0 siblings, 0 replies; 36+ messages in thread
From: Laurent Pinchart @ 2013-12-30 23:53 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, linux-sh-u79uwXL29TY76Z2rM5mHXA
Hi Geert,
Thank you for the patch.
On Tuesday 24 December 2013 12:40:47 Geert Uytterhoeven wrote:
> 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>
> ---
> 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 34674fe6df5d..850025278519 100644
> --- a/drivers/spi/spi-rspi.c
> +++ b/drivers/spi/spi-rspi.c
> @@ -181,6 +181,7 @@ struct rspi_data {
> u8 spsr;
> u8 spdcr;
> u8 data_width;
> + u16 spcmd;
> int irq[MAX_NUM_IRQ];
> unsigned int numirq;
> const struct spi_ops *ops;
> @@ -328,7 +329,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 */
> @@ -383,7 +384,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);
> @@ -903,6 +904,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;
> @@ -1092,6 +1099,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;
>
> for (i = 0; i < rspi->numirq; i++) {
> ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
--
Regards,
Laurent Pinchart
--
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 [flat|nested] 36+ messages in thread
* Re: [PATCH 3/8] spi: rspi: Add support for more than one interrupt
2013-12-30 23:38 ` Laurent Pinchart
@ 2014-01-02 10:25 ` Geert Uytterhoeven
-1 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2014-01-02 10:25 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: Geert Uytterhoeven, linux-spi, Linux-sh list
Hi Laurent,
On Tue, Dec 31, 2013 at 12:38 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Tuesday 24 December 2013 12:40:43 Geert Uytterhoeven wrote:
>> + int irq[MAX_NUM_IRQ];
>
> Should this field be called irqs ?
OK.
>> + unsigned int numirq;
>
> This driver seems to use underscores to separate words in variable names,
> maybe you could use num_irq (or num_irqs) instead.
OK.
>> + int i, ret = 0;
>
> i is an unsigned loop index, could you please make it an unsigned int ?
OK.
>> @@ -948,6 +948,19 @@ static int rspi_probe(struct platform_device *pdev)
>> rspi->ops = ops;
>> rspi->master = master;
>>
>> + for (i = 0; i < MAX_NUM_IRQ; i++) {
>> + irq = platform_get_irq(pdev, i);
>> + if (irq < 0) {
>> + if (rspi->numirq)
>> + break;
>> + dev_err(&pdev->dev, "platform_get_irq error\n");
>> + ret = -ENODEV;
>> + goto error1;
>> + }
>> + rspi->irq[i] = irq;
>> + rspi->numirq++;
>> + }
>> +
>> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> rspi->addr = devm_ioremap_resource(&pdev->dev, res);
>> if (IS_ERR(rspi->addr)) {
>> @@ -979,14 +992,16 @@ 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 < rspi->numirq; i++) {
>> + ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
>> + dev_name(&pdev->dev), rspi);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "request_irq %d error\n",
>> + rspi->irq[i]);
>> + goto error1;
>> + }
>> }
>
> Just an idea, what about combining the two loops ?
I was a bit concerned about dependencies and cleanup, but indeed, it seems
to be possible.
>> --- 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
>
> This change seems to be unrelated. You might want to squash it into patch 1/8.
I'll move it to the first patch that actually adds code to rspi.h.
Thanks for your comments!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 3/8] spi: rspi: Add support for more than one interrupt
@ 2014-01-02 10:25 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2014-01-02 10:25 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: Geert Uytterhoeven, linux-spi, Linux-sh list
Hi Laurent,
On Tue, Dec 31, 2013 at 12:38 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Tuesday 24 December 2013 12:40:43 Geert Uytterhoeven wrote:
>> + int irq[MAX_NUM_IRQ];
>
> Should this field be called irqs ?
OK.
>> + unsigned int numirq;
>
> This driver seems to use underscores to separate words in variable names,
> maybe you could use num_irq (or num_irqs) instead.
OK.
>> + int i, ret = 0;
>
> i is an unsigned loop index, could you please make it an unsigned int ?
OK.
>> @@ -948,6 +948,19 @@ static int rspi_probe(struct platform_device *pdev)
>> rspi->ops = ops;
>> rspi->master = master;
>>
>> + for (i = 0; i < MAX_NUM_IRQ; i++) {
>> + irq = platform_get_irq(pdev, i);
>> + if (irq < 0) {
>> + if (rspi->numirq)
>> + break;
>> + dev_err(&pdev->dev, "platform_get_irq error\n");
>> + ret = -ENODEV;
>> + goto error1;
>> + }
>> + rspi->irq[i] = irq;
>> + rspi->numirq++;
>> + }
>> +
>> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> rspi->addr = devm_ioremap_resource(&pdev->dev, res);
>> if (IS_ERR(rspi->addr)) {
>> @@ -979,14 +992,16 @@ 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 < rspi->numirq; i++) {
>> + ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0,
>> + dev_name(&pdev->dev), rspi);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "request_irq %d error\n",
>> + rspi->irq[i]);
>> + goto error1;
>> + }
>> }
>
> Just an idea, what about combining the two loops ?
I was a bit concerned about dependencies and cleanup, but indeed, it seems
to be possible.
>> --- 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
>
> This change seems to be unrelated. You might want to squash it into patch 1/8.
I'll move it to the first patch that actually adds code to rspi.h.
Thanks for your comments!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] spi: rspi: Add support for 8-bit Data Register access
2013-12-30 23:47 ` Laurent Pinchart
@ 2014-01-02 10:47 ` Geert Uytterhoeven
-1 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2014-01-02 10:47 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Geert Uytterhoeven, linux-spi-u79uwXL29TY76Z2rM5mHXA, Linux-sh list
Hi Laurent,
On Tue, Dec 31, 2013 at 12:47 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Tuesday 24 December 2013 12:40:44 Geert Uytterhoeven wrote:
>> +static void rspi_write_data(const struct rspi_data *rspi, u16 data)
>> +{
>> + if (rspi->data_width = 8)
>> + rspi_write8(rspi, data, RSPI_SPDR);
>> + else if (rspi->data_width = 16)
>> + rspi_write16(rspi, data, RSPI_SPDR);
>
> As the driver only handles 8-bits and 16-bits data, replacing the else if with
> an else should be more efficient.
Sure, will add a comment "/* 16 bit only */", though.
>> +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 -1;
>
> Shouldn't you return a defined error code (-EINVAL maybe) ?
Sure.
Thanks for your comments!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] spi: rspi: Add support for 8-bit Data Register access
@ 2014-01-02 10:47 ` Geert Uytterhoeven
0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2014-01-02 10:47 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Geert Uytterhoeven, linux-spi-u79uwXL29TY76Z2rM5mHXA, Linux-sh list
Hi Laurent,
On Tue, Dec 31, 2013 at 12:47 AM, Laurent Pinchart
<laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org> wrote:
> On Tuesday 24 December 2013 12:40:44 Geert Uytterhoeven wrote:
>> +static void rspi_write_data(const struct rspi_data *rspi, u16 data)
>> +{
>> + if (rspi->data_width == 8)
>> + rspi_write8(rspi, data, RSPI_SPDR);
>> + else if (rspi->data_width == 16)
>> + rspi_write16(rspi, data, RSPI_SPDR);
>
> As the driver only handles 8-bits and 16-bits data, replacing the else if with
> an else should be more efficient.
Sure, will add a comment "/* 16 bit only */", though.
>> +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 -1;
>
> Shouldn't you return a defined error code (-EINVAL maybe) ?
Sure.
Thanks for your comments!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
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 [flat|nested] 36+ messages in thread
end of thread, other threads:[~2014-01-02 10:47 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-24 11:40 [PATCH 0/8] spi: rspi: Add prelimary support for RZ/A1H Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
[not found] ` <1387885248-28425-1-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2013-12-24 11:40 ` [PATCH 1/8] spi: rspi: Add more RSPI register documentation Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
[not found] ` <1387885248-28425-2-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2013-12-30 23:31 ` Laurent Pinchart
2013-12-30 23:31 ` Laurent Pinchart
2013-12-24 11:40 ` [PATCH 4/8] spi: rspi: Add support for 8-bit Data Register access Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
[not found] ` <1387885248-28425-5-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2013-12-30 23:47 ` Laurent Pinchart
2013-12-30 23:47 ` Laurent Pinchart
2014-01-02 10:47 ` Geert Uytterhoeven
2014-01-02 10:47 ` Geert Uytterhoeven
2013-12-24 11:40 ` [PATCH 2/8] spi: rspi: Add more QSPI register documentation Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
[not found] ` <1387885248-28425-3-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2013-12-30 23:31 ` Laurent Pinchart
2013-12-30 23:31 ` Laurent Pinchart
2013-12-24 11:40 ` [PATCH 3/8] spi: rspi: Add support for more than one interrupt Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
[not found] ` <1387885248-28425-4-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2013-12-30 23:38 ` Laurent Pinchart
2013-12-30 23:38 ` Laurent Pinchart
2014-01-02 10:25 ` Geert Uytterhoeven
2014-01-02 10:25 ` Geert Uytterhoeven
2013-12-24 11:40 ` [PATCH 5/8] spi: rspi: Add support for no TX only mode Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
2013-12-24 11:40 ` [PATCH 6/8] spi: rspi: Add support for missing SPCR2 register Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
[not found] ` <1387885248-28425-7-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2013-12-30 23:52 ` Laurent Pinchart
2013-12-30 23:52 ` Laurent Pinchart
2013-12-24 11:40 ` [PATCH 7/8] spi: rspi: Add support for specifying CPHA/CPOL Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
[not found] ` <1387885248-28425-8-git-send-email-geert+renesas-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
2013-12-30 23:53 ` Laurent Pinchart
2013-12-30 23:53 ` Laurent Pinchart
2013-12-24 11:40 ` [PATCH 8/8] spi: rspi: Add support for loopback mode Geert Uytterhoeven
2013-12-24 11:40 ` Geert Uytterhoeven
2013-12-27 19:22 ` [PATCH 0/8] spi: rspi: Add prelimary support for RZ/A1H Geert Uytterhoeven
2013-12-27 19:22 ` Geert Uytterhoeven
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.