blob: 4ecfe60115b83bbad925305847e969306971327a [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +09002/*
3 * SH SPI driver
4 *
Yoshihiro Shimoda41153eb2012-03-05 19:27:13 +00005 * Copyright (C) 2011-2012 Renesas Solutions Corp.
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +09006 */
7
8#include <common.h>
Simon Glassa73bda42015-11-08 23:47:45 -07009#include <console.h>
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +090010#include <malloc.h>
11#include <spi.h>
12#include <asm/io.h>
Simon Glassdbd79542020-05-10 11:40:11 -060013#include <linux/delay.h>
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +090014#include "sh_spi.h"
15
16static void sh_spi_write(unsigned long data, unsigned long *reg)
17{
18 writel(data, reg);
19}
20
21static unsigned long sh_spi_read(unsigned long *reg)
22{
23 return readl(reg);
24}
25
26static void sh_spi_set_bit(unsigned long val, unsigned long *reg)
27{
28 unsigned long tmp;
29
30 tmp = sh_spi_read(reg);
31 tmp |= val;
32 sh_spi_write(tmp, reg);
33}
34
35static void sh_spi_clear_bit(unsigned long val, unsigned long *reg)
36{
37 unsigned long tmp;
38
39 tmp = sh_spi_read(reg);
40 tmp &= ~val;
41 sh_spi_write(tmp, reg);
42}
43
44static void clear_fifo(struct sh_spi *ss)
45{
46 sh_spi_set_bit(SH_SPI_RSTF, &ss->regs->cr2);
47 sh_spi_clear_bit(SH_SPI_RSTF, &ss->regs->cr2);
48}
49
50static int recvbuf_wait(struct sh_spi *ss)
51{
52 while (sh_spi_read(&ss->regs->cr1) & SH_SPI_RBE) {
53 if (ctrlc())
54 return 1;
55 udelay(10);
56 }
57 return 0;
58}
59
60static int write_fifo_empty_wait(struct sh_spi *ss)
61{
62 while (!(sh_spi_read(&ss->regs->cr1) & SH_SPI_TBE)) {
63 if (ctrlc())
64 return 1;
65 udelay(10);
66 }
67 return 0;
68}
69
Yoshihiro Shimoda41153eb2012-03-05 19:27:13 +000070static void sh_spi_set_cs(struct sh_spi *ss, unsigned int cs)
71{
72 unsigned long val = 0;
73
74 if (cs & 0x01)
75 val |= SH_SPI_SSS0;
76 if (cs & 0x02)
77 val |= SH_SPI_SSS1;
78
79 sh_spi_clear_bit(SH_SPI_SSS0 | SH_SPI_SSS1, &ss->regs->cr4);
80 sh_spi_set_bit(val, &ss->regs->cr4);
81}
82
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +090083struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
84 unsigned int max_hz, unsigned int mode)
85{
86 struct sh_spi *ss;
87
88 if (!spi_cs_is_valid(bus, cs))
89 return NULL;
90
Simon Glassd034a952013-03-18 19:23:40 +000091 ss = spi_alloc_slave(struct sh_spi, bus, cs);
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +090092 if (!ss)
93 return NULL;
94
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +090095 ss->regs = (struct sh_spi_regs *)CONFIG_SH_SPI_BASE;
96
97 /* SPI sycle stop */
98 sh_spi_write(0xfe, &ss->regs->cr1);
99 /* CR1 init */
100 sh_spi_write(0x00, &ss->regs->cr1);
101 /* CR3 init */
102 sh_spi_write(0x00, &ss->regs->cr3);
Yoshihiro Shimoda41153eb2012-03-05 19:27:13 +0000103 sh_spi_set_cs(ss, cs);
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +0900104
105 clear_fifo(ss);
106
107 /* 1/8 clock */
108 sh_spi_write(sh_spi_read(&ss->regs->cr2) | 0x07, &ss->regs->cr2);
109 udelay(10);
110
111 return &ss->slave;
112}
113
114void spi_free_slave(struct spi_slave *slave)
115{
116 struct sh_spi *spi = to_sh_spi(slave);
117
118 free(spi);
119}
120
121int spi_claim_bus(struct spi_slave *slave)
122{
123 return 0;
124}
125
126void spi_release_bus(struct spi_slave *slave)
127{
128 struct sh_spi *ss = to_sh_spi(slave);
129
130 sh_spi_write(sh_spi_read(&ss->regs->cr1) &
131 ~(SH_SPI_SSA | SH_SPI_SSDB | SH_SPI_SSD), &ss->regs->cr1);
132}
133
134static int sh_spi_send(struct sh_spi *ss, const unsigned char *tx_data,
135 unsigned int len, unsigned long flags)
136{
137 int i, cur_len, ret = 0;
138 int remain = (int)len;
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +0900139
140 if (len >= SH_SPI_FIFO_SIZE)
141 sh_spi_set_bit(SH_SPI_SSA, &ss->regs->cr1);
142
143 while (remain > 0) {
144 cur_len = (remain < SH_SPI_FIFO_SIZE) ?
145 remain : SH_SPI_FIFO_SIZE;
146 for (i = 0; i < cur_len &&
147 !(sh_spi_read(&ss->regs->cr4) & SH_SPI_WPABRT) &&
148 !(sh_spi_read(&ss->regs->cr1) & SH_SPI_TBF);
149 i++)
150 sh_spi_write(tx_data[i], &ss->regs->tbr_rbr);
151
152 cur_len = i;
153
154 if (sh_spi_read(&ss->regs->cr4) & SH_SPI_WPABRT) {
155 /* Abort the transaction */
156 flags |= SPI_XFER_END;
157 sh_spi_set_bit(SH_SPI_WPABRT, &ss->regs->cr4);
158 ret = 1;
159 break;
160 }
161
162 remain -= cur_len;
163 tx_data += cur_len;
164
165 if (remain > 0)
166 write_fifo_empty_wait(ss);
167 }
168
169 if (flags & SPI_XFER_END) {
Axel Linc3936de2013-12-27 13:51:55 +0800170 sh_spi_clear_bit(SH_SPI_SSD | SH_SPI_SSDB, &ss->regs->cr1);
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +0900171 sh_spi_set_bit(SH_SPI_SSA, &ss->regs->cr1);
172 udelay(100);
173 write_fifo_empty_wait(ss);
174 }
175
176 return ret;
177}
178
179static int sh_spi_receive(struct sh_spi *ss, unsigned char *rx_data,
180 unsigned int len, unsigned long flags)
181{
182 int i;
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +0900183
184 if (len > SH_SPI_MAX_BYTE)
185 sh_spi_write(SH_SPI_MAX_BYTE, &ss->regs->cr3);
186 else
187 sh_spi_write(len, &ss->regs->cr3);
188
Axel Linc3936de2013-12-27 13:51:55 +0800189 sh_spi_clear_bit(SH_SPI_SSD | SH_SPI_SSDB, &ss->regs->cr1);
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +0900190 sh_spi_set_bit(SH_SPI_SSA, &ss->regs->cr1);
191
192 for (i = 0; i < len; i++) {
193 if (recvbuf_wait(ss))
194 return 0;
195
196 rx_data[i] = (unsigned char)sh_spi_read(&ss->regs->tbr_rbr);
197 }
198 sh_spi_write(0, &ss->regs->cr3);
199
200 return 0;
201}
202
203int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
204 void *din, unsigned long flags)
205{
206 struct sh_spi *ss = to_sh_spi(slave);
207 const unsigned char *tx_data = dout;
208 unsigned char *rx_data = din;
209 unsigned int len = bitlen / 8;
210 int ret = 0;
211
212 if (flags & SPI_XFER_BEGIN)
213 sh_spi_write(sh_spi_read(&ss->regs->cr1) & ~SH_SPI_SSA,
214 &ss->regs->cr1);
215
216 if (tx_data)
217 ret = sh_spi_send(ss, tx_data, len, flags);
218
219 if (ret == 0 && rx_data)
220 ret = sh_spi_receive(ss, rx_data, len, flags);
221
222 if (flags & SPI_XFER_END) {
223 sh_spi_set_bit(SH_SPI_SSD, &ss->regs->cr1);
224 udelay(100);
225
226 sh_spi_clear_bit(SH_SPI_SSA | SH_SPI_SSDB | SH_SPI_SSD,
227 &ss->regs->cr1);
228 clear_fifo(ss);
229 }
230
231 return ret;
232}
233
234int spi_cs_is_valid(unsigned int bus, unsigned int cs)
235{
Yoshihiro Shimoda41153eb2012-03-05 19:27:13 +0000236 if (!bus && cs < SH_SPI_NUM_CS)
Yoshihiro Shimoda65bd9b42011-01-31 16:50:43 +0900237 return 1;
238 else
239 return 0;
240}
241
242void spi_cs_activate(struct spi_slave *slave)
243{
244
245}
246
247void spi_cs_deactivate(struct spi_slave *slave)
248{
249
250}