diff options
author | Geert Uytterhoeven <geert+renesas@linux-m68k.org> | 2014-01-24 03:43:59 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-01-27 15:07:07 -0500 |
commit | 862d357f84f009fdcba22be8d6a2f82ff80ab740 (patch) | |
tree | d9b52cb46935f48629a3fcff1a0c3cac1a9d8315 /drivers | |
parent | 9372220678cd4c62992f7637b2ee36b47fa58d37 (diff) |
spi: rspi: Add support for RSPI on RZ/A1H
Add support for the RSPI variant in the RZ/A1H (r7s72100) SoC.
Main differences with RSPI on SH are:
- Lack of TX only mode, hence we always have to use full duplex
transfers,
- The Data Register must be accessed used 8-bit operations.
RSPI on RZ is matched using the new "rspi-rz" platform device name.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/spi-rspi.c | 101 |
1 files changed, 92 insertions, 9 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index d2ade5e09f58..0c7556978d2e 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #define RSPI_SPCKD 0x0c /* Clock Delay Register */ | 47 | #define RSPI_SPCKD 0x0c /* Clock Delay Register */ |
48 | #define RSPI_SSLND 0x0d /* Slave Select Negation Delay Register */ | 48 | #define RSPI_SSLND 0x0d /* Slave Select Negation Delay Register */ |
49 | #define RSPI_SPND 0x0e /* Next-Access Delay Register */ | 49 | #define RSPI_SPND 0x0e /* Next-Access Delay Register */ |
50 | #define RSPI_SPCR2 0x0f /* Control Register 2 */ | 50 | #define RSPI_SPCR2 0x0f /* Control Register 2 (SH only) */ |
51 | #define RSPI_SPCMD0 0x10 /* Command Register 0 */ | 51 | #define RSPI_SPCMD0 0x10 /* Command Register 0 */ |
52 | #define RSPI_SPCMD1 0x12 /* Command Register 1 */ | 52 | #define RSPI_SPCMD1 0x12 /* Command Register 1 */ |
53 | #define RSPI_SPCMD2 0x14 /* Command Register 2 */ | 53 | #define RSPI_SPCMD2 0x14 /* Command Register 2 */ |
@@ -56,10 +56,12 @@ | |||
56 | #define RSPI_SPCMD5 0x1a /* Command Register 5 */ | 56 | #define RSPI_SPCMD5 0x1a /* Command Register 5 */ |
57 | #define RSPI_SPCMD6 0x1c /* Command Register 6 */ | 57 | #define RSPI_SPCMD6 0x1c /* Command Register 6 */ |
58 | #define RSPI_SPCMD7 0x1e /* Command Register 7 */ | 58 | #define RSPI_SPCMD7 0x1e /* Command Register 7 */ |
59 | |||
60 | /* RSPI on RZ only */ | ||
59 | #define RSPI_SPBFCR 0x20 /* Buffer Control Register */ | 61 | #define RSPI_SPBFCR 0x20 /* Buffer Control Register */ |
60 | #define RSPI_SPBFDR 0x22 /* Buffer Data Count Setting Register */ | 62 | #define RSPI_SPBFDR 0x22 /* Buffer Data Count Setting Register */ |
61 | 63 | ||
62 | /*qspi only */ | 64 | /* QSPI only */ |
63 | #define QSPI_SPBFCR 0x18 /* Buffer Control Register */ | 65 | #define QSPI_SPBFCR 0x18 /* Buffer Control Register */ |
64 | #define QSPI_SPBDCR 0x1a /* Buffer Data Count Register */ | 66 | #define QSPI_SPBDCR 0x1a /* Buffer Data Count Register */ |
65 | #define QSPI_SPBMUL0 0x1c /* Transfer Data Length Multiplier Setting Register 0 */ | 67 | #define QSPI_SPBMUL0 0x1c /* Transfer Data Length Multiplier Setting Register 0 */ |
@@ -102,7 +104,7 @@ | |||
102 | #define SPSR_PERF 0x08 /* Parity Error Flag */ | 104 | #define SPSR_PERF 0x08 /* Parity Error Flag */ |
103 | #define SPSR_MODF 0x04 /* Mode Fault Error Flag */ | 105 | #define SPSR_MODF 0x04 /* Mode Fault Error Flag */ |
104 | #define SPSR_IDLNF 0x02 /* RSPI Idle Flag */ | 106 | #define SPSR_IDLNF 0x02 /* RSPI Idle Flag */ |
105 | #define SPSR_OVRF 0x01 /* Overrun Error Flag */ | 107 | #define SPSR_OVRF 0x01 /* Overrun Error Flag (RSPI only) */ |
106 | 108 | ||
107 | /* SPSCR - Sequence Control Register */ | 109 | /* SPSCR - Sequence Control Register */ |
108 | #define SPSCR_SPSLN_MASK 0x07 /* Sequence Length Specification */ | 110 | #define SPSCR_SPSLN_MASK 0x07 /* Sequence Length Specification */ |
@@ -119,13 +121,13 @@ | |||
119 | #define SPDCR_SPLWORD SPDCR_SPLW1 | 121 | #define SPDCR_SPLWORD SPDCR_SPLW1 |
120 | #define SPDCR_SPLBYTE SPDCR_SPLW0 | 122 | #define SPDCR_SPLBYTE SPDCR_SPLW0 |
121 | #define SPDCR_SPLW 0x20 /* Access Width Specification (SH) */ | 123 | #define SPDCR_SPLW 0x20 /* Access Width Specification (SH) */ |
122 | #define SPDCR_SPRDTD 0x10 /* Receive Transmit Data Select */ | 124 | #define SPDCR_SPRDTD 0x10 /* Receive Transmit Data Select (SH) */ |
123 | #define SPDCR_SLSEL1 0x08 | 125 | #define SPDCR_SLSEL1 0x08 |
124 | #define SPDCR_SLSEL0 0x04 | 126 | #define SPDCR_SLSEL0 0x04 |
125 | #define SPDCR_SLSEL_MASK 0x0c /* SSL1 Output Select */ | 127 | #define SPDCR_SLSEL_MASK 0x0c /* SSL1 Output Select (SH) */ |
126 | #define SPDCR_SPFC1 0x02 | 128 | #define SPDCR_SPFC1 0x02 |
127 | #define SPDCR_SPFC0 0x01 | 129 | #define SPDCR_SPFC0 0x01 |
128 | #define SPDCR_SPFC_MASK 0x03 /* Frame Count Setting (1-4) */ | 130 | #define SPDCR_SPFC_MASK 0x03 /* Frame Count Setting (1-4) (SH) */ |
129 | 131 | ||
130 | /* SPCKD - Clock Delay Register */ | 132 | /* SPCKD - Clock Delay Register */ |
131 | #define SPCKD_SCKDL_MASK 0x07 /* Clock Delay Setting (1-8) */ | 133 | #define SPCKD_SCKDL_MASK 0x07 /* Clock Delay Setting (1-8) */ |
@@ -168,8 +170,8 @@ | |||
168 | #define SPCMD_CPHA 0x0001 /* Clock Phase Setting */ | 170 | #define SPCMD_CPHA 0x0001 /* Clock Phase Setting */ |
169 | 171 | ||
170 | /* SPBFCR - Buffer Control Register */ | 172 | /* SPBFCR - Buffer Control Register */ |
171 | #define SPBFCR_TXRST 0x80 /* Transmit Buffer Data Reset (qspi only) */ | 173 | #define SPBFCR_TXRST 0x80 /* Transmit Buffer Data Reset */ |
172 | #define SPBFCR_RXRST 0x40 /* Receive Buffer Data Reset (qspi only) */ | 174 | #define SPBFCR_RXRST 0x40 /* Receive Buffer Data Reset */ |
173 | #define SPBFCR_TXTRG_MASK 0x30 /* Transmit Buffer Data Triggering Number */ | 175 | #define SPBFCR_TXTRG_MASK 0x30 /* Transmit Buffer Data Triggering Number */ |
174 | #define SPBFCR_RXTRG_MASK 0x07 /* Receive Buffer Data Triggering Number */ | 176 | #define SPBFCR_RXTRG_MASK 0x07 /* Receive Buffer Data Triggering Number */ |
175 | 177 | ||
@@ -244,7 +246,7 @@ struct spi_ops { | |||
244 | }; | 246 | }; |
245 | 247 | ||
246 | /* | 248 | /* |
247 | * functions for RSPI | 249 | * functions for RSPI on legacy SH |
248 | */ | 250 | */ |
249 | static int rspi_set_config_register(struct rspi_data *rspi, int access_size) | 251 | static int rspi_set_config_register(struct rspi_data *rspi, int access_size) |
250 | { | 252 | { |
@@ -280,6 +282,39 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size) | |||
280 | } | 282 | } |
281 | 283 | ||
282 | /* | 284 | /* |
285 | * functions for RSPI on RZ | ||
286 | */ | ||
287 | static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size) | ||
288 | { | ||
289 | int spbr; | ||
290 | |||
291 | /* Sets output mode */ | ||
292 | rspi_write8(rspi, 0x00, RSPI_SPPCR); | ||
293 | |||
294 | /* Sets transfer bit rate */ | ||
295 | spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1; | ||
296 | rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); | ||
297 | |||
298 | /* Disable dummy transmission, set byte access */ | ||
299 | rspi_write8(rspi, SPDCR_SPLBYTE, RSPI_SPDCR); | ||
300 | rspi->byte_access = 1; | ||
301 | |||
302 | /* Sets RSPCK, SSL, next-access delay value */ | ||
303 | rspi_write8(rspi, 0x00, RSPI_SPCKD); | ||
304 | rspi_write8(rspi, 0x00, RSPI_SSLND); | ||
305 | rspi_write8(rspi, 0x00, RSPI_SPND); | ||
306 | |||
307 | /* Sets SPCMD */ | ||
308 | rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size); | ||
309 | rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); | ||
310 | |||
311 | /* Sets RSPI mode */ | ||
312 | rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | /* | ||
283 | * functions for QSPI | 318 | * functions for QSPI |
284 | */ | 319 | */ |
285 | static int qspi_set_config_register(struct rspi_data *rspi, int access_size) | 320 | static int qspi_set_config_register(struct rspi_data *rspi, int access_size) |
@@ -520,6 +555,13 @@ static void rspi_receive_init(const struct rspi_data *rspi) | |||
520 | RSPI_SPSR); | 555 | RSPI_SPSR); |
521 | } | 556 | } |
522 | 557 | ||
558 | static void rspi_rz_receive_init(const struct rspi_data *rspi) | ||
559 | { | ||
560 | rspi_receive_init(rspi); | ||
561 | rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, RSPI_SPBFCR); | ||
562 | rspi_write8(rspi, 0, RSPI_SPBFCR); | ||
563 | } | ||
564 | |||
523 | static void qspi_receive_init(const struct rspi_data *rspi) | 565 | static void qspi_receive_init(const struct rspi_data *rspi) |
524 | { | 566 | { |
525 | u8 spsr; | 567 | u8 spsr; |
@@ -706,6 +748,41 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi, | |||
706 | return 0; | 748 | return 0; |
707 | } | 749 | } |
708 | 750 | ||
751 | static int rspi_rz_transfer_out_in(struct rspi_data *rspi, | ||
752 | struct spi_transfer *xfer) | ||
753 | { | ||
754 | int remain = xfer->len, ret; | ||
755 | const u8 *tx_buf = xfer->tx_buf; | ||
756 | u8 *rx_buf = xfer->rx_buf; | ||
757 | u8 data; | ||
758 | |||
759 | rspi_rz_receive_init(rspi); | ||
760 | |||
761 | while (remain > 0) { | ||
762 | data = tx_buf ? *tx_buf++ : DUMMY_DATA; | ||
763 | ret = rspi_data_out_in(rspi, data); | ||
764 | if (ret < 0) | ||
765 | return ret; | ||
766 | if (rx_buf) | ||
767 | *rx_buf++ = ret; | ||
768 | remain--; | ||
769 | } | ||
770 | |||
771 | /* Wait for the last transmission */ | ||
772 | rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE); | ||
773 | |||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | static int rspi_rz_transfer_one(struct spi_master *master, | ||
778 | struct spi_device *spi, | ||
779 | struct spi_transfer *xfer) | ||
780 | { | ||
781 | struct rspi_data *rspi = spi_master_get_devdata(master); | ||
782 | |||
783 | return rspi_rz_transfer_out_in(rspi, xfer); | ||
784 | } | ||
785 | |||
709 | static int qspi_transfer_out_in(struct rspi_data *rspi, | 786 | static int qspi_transfer_out_in(struct rspi_data *rspi, |
710 | struct spi_transfer *xfer) | 787 | struct spi_transfer *xfer) |
711 | { | 788 | { |
@@ -1041,6 +1118,11 @@ static struct spi_ops rspi_ops = { | |||
1041 | .transfer_one = rspi_transfer_one, | 1118 | .transfer_one = rspi_transfer_one, |
1042 | }; | 1119 | }; |
1043 | 1120 | ||
1121 | static struct spi_ops rspi_rz_ops = { | ||
1122 | .set_config_register = rspi_rz_set_config_register, | ||
1123 | .transfer_one = rspi_rz_transfer_one, | ||
1124 | }; | ||
1125 | |||
1044 | static struct spi_ops qspi_ops = { | 1126 | static struct spi_ops qspi_ops = { |
1045 | .set_config_register = qspi_set_config_register, | 1127 | .set_config_register = qspi_set_config_register, |
1046 | .transfer_one = qspi_transfer_one, | 1128 | .transfer_one = qspi_transfer_one, |
@@ -1048,6 +1130,7 @@ static struct spi_ops qspi_ops = { | |||
1048 | 1130 | ||
1049 | static struct platform_device_id spi_driver_ids[] = { | 1131 | static struct platform_device_id spi_driver_ids[] = { |
1050 | { "rspi", (kernel_ulong_t)&rspi_ops }, | 1132 | { "rspi", (kernel_ulong_t)&rspi_ops }, |
1133 | { "rspi-rz", (kernel_ulong_t)&rspi_rz_ops }, | ||
1051 | { "qspi", (kernel_ulong_t)&qspi_ops }, | 1134 | { "qspi", (kernel_ulong_t)&qspi_ops }, |
1052 | {}, | 1135 | {}, |
1053 | }; | 1136 | }; |