]> git.sur5r.net Git - u-boot/blob - drivers/spi/bfin_spi6xx.c
xtensa: add support for the 'xtfpga' evaluation board
[u-boot] / drivers / spi / bfin_spi6xx.c
1 /*
2  * Analog Devices SPI3 controller driver
3  *
4  * Copyright (c) 2011 Analog Devices Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include <common.h>
21 #include <console.h>
22 #include <malloc.h>
23 #include <spi.h>
24
25 #include <asm/blackfin.h>
26 #include <asm/clock.h>
27 #include <asm/gpio.h>
28 #include <asm/portmux.h>
29 #include <asm/mach-common/bits/spi6xx.h>
30
31 struct bfin_spi_slave {
32         struct spi_slave slave;
33         u32 control, clock;
34         struct bfin_spi_regs *regs;
35         int cs_pol;
36 };
37
38 #define to_bfin_spi_slave(s) container_of(s, struct bfin_spi_slave, slave)
39
40 #define gpio_cs(cs) ((cs) - MAX_CTRL_CS)
41 #ifdef CONFIG_BFIN_SPI_GPIO_CS
42 # define is_gpio_cs(cs) ((cs) > MAX_CTRL_CS)
43 #else
44 # define is_gpio_cs(cs) 0
45 #endif
46
47 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
48 {
49         if (is_gpio_cs(cs))
50                 return gpio_is_valid(gpio_cs(cs));
51         else
52                 return (cs >= 1 && cs <= MAX_CTRL_CS);
53 }
54
55 void spi_cs_activate(struct spi_slave *slave)
56 {
57         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
58
59         if (is_gpio_cs(slave->cs)) {
60                 unsigned int cs = gpio_cs(slave->cs);
61                 gpio_set_value(cs, bss->cs_pol);
62         } else {
63                 u32 ssel;
64                 ssel = bfin_read32(&bss->regs->ssel);
65                 ssel |= 1 << slave->cs;
66                 if (bss->cs_pol)
67                         ssel |= BIT(8) << slave->cs;
68                 else
69                         ssel &= ~(BIT(8) << slave->cs);
70                 bfin_write32(&bss->regs->ssel, ssel);
71         }
72
73         SSYNC();
74 }
75
76 void spi_cs_deactivate(struct spi_slave *slave)
77 {
78         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
79
80         if (is_gpio_cs(slave->cs)) {
81                 unsigned int cs = gpio_cs(slave->cs);
82                 gpio_set_value(cs, !bss->cs_pol);
83         } else {
84                 u32 ssel;
85                 ssel = bfin_read32(&bss->regs->ssel);
86                 if (bss->cs_pol)
87                         ssel &= ~(BIT(8) << slave->cs);
88                 else
89                         ssel |= BIT(8) << slave->cs;
90                 /* deassert cs */
91                 bfin_write32(&bss->regs->ssel, ssel);
92                 SSYNC();
93                 /* disable cs */
94                 ssel &= ~(1 << slave->cs);
95                 bfin_write32(&bss->regs->ssel, ssel);
96         }
97
98         SSYNC();
99 }
100
101 void spi_init()
102 {
103 }
104
105 #define SPI_PINS(n) \
106         { 0, P_SPI##n##_SCK, P_SPI##n##_MISO, P_SPI##n##_MOSI, 0 }
107 static unsigned short pins[][5] = {
108 #ifdef SPI0_REGBASE
109         [0] = SPI_PINS(0),
110 #endif
111 #ifdef SPI1_REGBASE
112         [1] = SPI_PINS(1),
113 #endif
114 #ifdef SPI2_REGBASE
115         [2] = SPI_PINS(2),
116 #endif
117 };
118
119 #define SPI_CS_PINS(n) \
120         { \
121                 P_SPI##n##_SSEL1, P_SPI##n##_SSEL2, P_SPI##n##_SSEL3, \
122                 P_SPI##n##_SSEL4, P_SPI##n##_SSEL5, P_SPI##n##_SSEL6, \
123                 P_SPI##n##_SSEL7, \
124         }
125 static const unsigned short cs_pins[][7] = {
126 #ifdef SPI0_REGBASE
127         [0] = SPI_CS_PINS(0),
128 #endif
129 #ifdef SPI1_REGBASE
130         [1] = SPI_CS_PINS(1),
131 #endif
132 #ifdef SPI2_REGBASE
133         [2] = SPI_CS_PINS(2),
134 #endif
135 };
136
137 void spi_set_speed(struct spi_slave *slave, uint hz)
138 {
139         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
140         ulong clk;
141         u32 clock;
142
143         clk = get_spi_clk();
144         clock = clk / hz;
145         if (clock)
146                 clock--;
147         bss->clock = clock;
148 }
149
150 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
151                 unsigned int max_hz, unsigned int mode)
152 {
153         struct bfin_spi_slave *bss;
154         u32 reg_base;
155
156         if (!spi_cs_is_valid(bus, cs))
157                 return NULL;
158
159         switch (bus) {
160 #ifdef SPI0_REGBASE
161         case 0:
162                 reg_base = SPI0_REGBASE;
163                 break;
164 #endif
165 #ifdef SPI1_REGBASE
166         case 1:
167                 reg_base = SPI1_REGBASE;
168                 break;
169 #endif
170 #ifdef SPI2_REGBASE
171         case 2:
172                 reg_base = SPI2_REGBASE;
173                 break;
174 #endif
175         default:
176                 debug("%s: invalid bus %u\n", __func__, bus);
177                 return NULL;
178         }
179
180         bss = spi_alloc_slave(struct bfin_spi_slave, bus, cs);
181         if (!bss)
182                 return NULL;
183
184         bss->regs = (struct bfin_spi_regs *)reg_base;
185         bss->control = SPI_CTL_EN | SPI_CTL_MSTR;
186         if (mode & SPI_CPHA)
187                 bss->control |= SPI_CTL_CPHA;
188         if (mode & SPI_CPOL)
189                 bss->control |= SPI_CTL_CPOL;
190         if (mode & SPI_LSB_FIRST)
191                 bss->control |= SPI_CTL_LSBF;
192         bss->control &= ~SPI_CTL_ASSEL;
193         bss->cs_pol = mode & SPI_CS_HIGH ? 1 : 0;
194         spi_set_speed(&bss->slave, max_hz);
195
196         return &bss->slave;
197 }
198
199 void spi_free_slave(struct spi_slave *slave)
200 {
201         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
202         free(bss);
203 }
204
205 int spi_claim_bus(struct spi_slave *slave)
206 {
207         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
208
209         debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
210
211         if (is_gpio_cs(slave->cs)) {
212                 unsigned int cs = gpio_cs(slave->cs);
213                 gpio_request(cs, "bfin-spi");
214                 gpio_direction_output(cs, !bss->cs_pol);
215                 pins[slave->bus][0] = P_DONTCARE;
216         } else
217                 pins[slave->bus][0] = cs_pins[slave->bus][slave->cs - 1];
218         peripheral_request_list(pins[slave->bus], "bfin-spi");
219
220         bfin_write32(&bss->regs->control, bss->control);
221         bfin_write32(&bss->regs->clock, bss->clock);
222         bfin_write32(&bss->regs->delay, 0x0);
223         bfin_write32(&bss->regs->rx_control, SPI_RXCTL_REN);
224         bfin_write32(&bss->regs->tx_control, SPI_TXCTL_TEN | SPI_TXCTL_TTI);
225         SSYNC();
226
227         return 0;
228 }
229
230 void spi_release_bus(struct spi_slave *slave)
231 {
232         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
233
234         debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
235
236         peripheral_free_list(pins[slave->bus]);
237         if (is_gpio_cs(slave->cs))
238                 gpio_free(gpio_cs(slave->cs));
239
240         bfin_write32(&bss->regs->rx_control, 0x0);
241         bfin_write32(&bss->regs->tx_control, 0x0);
242         bfin_write32(&bss->regs->control, 0x0);
243         SSYNC();
244 }
245
246 #ifndef CONFIG_BFIN_SPI_IDLE_VAL
247 # define CONFIG_BFIN_SPI_IDLE_VAL 0xff
248 #endif
249
250 static int spi_pio_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx,
251                         uint bytes)
252 {
253         /* discard invalid rx data and empty rfifo */
254         while (!(bfin_read32(&bss->regs->status) & SPI_STAT_RFE))
255                 bfin_read32(&bss->regs->rfifo);
256
257         while (bytes--) {
258                 u8 value = (tx ? *tx++ : CONFIG_BFIN_SPI_IDLE_VAL);
259                 debug("%s: tx:%x ", __func__, value);
260                 bfin_write32(&bss->regs->tfifo, value);
261                 SSYNC();
262                 while (bfin_read32(&bss->regs->status) & SPI_STAT_RFE)
263                         if (ctrlc())
264                                 return -1;
265                 value = bfin_read32(&bss->regs->rfifo);
266                 if (rx)
267                         *rx++ = value;
268                 debug("rx:%x\n", value);
269         }
270
271         return 0;
272 }
273
274 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
275                 void *din, unsigned long flags)
276 {
277         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
278         const u8 *tx = dout;
279         u8 *rx = din;
280         uint bytes = bitlen / 8;
281         int ret = 0;
282
283         debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
284                 slave->bus, slave->cs, bitlen, bytes, flags);
285
286         if (bitlen == 0)
287                 goto done;
288
289         /* we can only do 8 bit transfers */
290         if (bitlen % 8) {
291                 flags |= SPI_XFER_END;
292                 goto done;
293         }
294
295         if (flags & SPI_XFER_BEGIN)
296                 spi_cs_activate(slave);
297
298         ret = spi_pio_xfer(bss, tx, rx, bytes);
299
300  done:
301         if (flags & SPI_XFER_END)
302                 spi_cs_deactivate(slave);
303
304         return ret;
305 }