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