]> 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 = malloc(sizeof(*bss));
182         if (!bss)
183                 return NULL;
184
185         bss->slave.bus = bus;
186         bss->slave.cs = cs;
187         bss->regs = (struct bfin_spi_regs *)reg_base;
188         bss->control = SPI_CTL_EN | SPI_CTL_MSTR;
189         if (mode & SPI_CPHA)
190                 bss->control |= SPI_CTL_CPHA;
191         if (mode & SPI_CPOL)
192                 bss->control |= SPI_CTL_CPOL;
193         if (mode & SPI_LSB_FIRST)
194                 bss->control |= SPI_CTL_LSBF;
195         bss->control &= ~SPI_CTL_ASSEL;
196         bss->cs_pol = mode & SPI_CS_HIGH ? 1 : 0;
197         spi_set_speed(&bss->slave, max_hz);
198
199         return &bss->slave;
200 }
201
202 void spi_free_slave(struct spi_slave *slave)
203 {
204         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
205         free(bss);
206 }
207
208 int spi_claim_bus(struct spi_slave *slave)
209 {
210         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
211
212         debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
213
214         if (is_gpio_cs(slave->cs)) {
215                 unsigned int cs = gpio_cs(slave->cs);
216                 gpio_request(cs, "bfin-spi");
217                 gpio_direction_output(cs, !bss->cs_pol);
218                 pins[slave->bus][0] = P_DONTCARE;
219         } else
220                 pins[slave->bus][0] = cs_pins[slave->bus][slave->cs - 1];
221         peripheral_request_list(pins[slave->bus], "bfin-spi");
222
223         bfin_write32(&bss->regs->control, bss->control);
224         bfin_write32(&bss->regs->clock, bss->clock);
225         bfin_write32(&bss->regs->delay, 0x0);
226         bfin_write32(&bss->regs->rx_control, SPI_RXCTL_REN);
227         bfin_write32(&bss->regs->tx_control, SPI_TXCTL_TEN | SPI_TXCTL_TTI);
228         SSYNC();
229
230         return 0;
231 }
232
233 void spi_release_bus(struct spi_slave *slave)
234 {
235         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
236
237         debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
238
239         peripheral_free_list(pins[slave->bus]);
240         if (is_gpio_cs(slave->cs))
241                 gpio_free(gpio_cs(slave->cs));
242
243         bfin_write32(&bss->regs->rx_control, 0x0);
244         bfin_write32(&bss->regs->tx_control, 0x0);
245         bfin_write32(&bss->regs->control, 0x0);
246         SSYNC();
247 }
248
249 #ifndef CONFIG_BFIN_SPI_IDLE_VAL
250 # define CONFIG_BFIN_SPI_IDLE_VAL 0xff
251 #endif
252
253 static int spi_pio_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx,
254                         uint bytes)
255 {
256         /* discard invalid rx data and empty rfifo */
257         while (!(bfin_read32(&bss->regs->status) & SPI_STAT_RFE))
258                 bfin_read32(&bss->regs->rfifo);
259
260         while (bytes--) {
261                 u8 value = (tx ? *tx++ : CONFIG_BFIN_SPI_IDLE_VAL);
262                 debug("%s: tx:%x ", __func__, value);
263                 bfin_write32(&bss->regs->tfifo, value);
264                 SSYNC();
265                 while (bfin_read32(&bss->regs->status) & SPI_STAT_RFE)
266                         if (ctrlc())
267                                 return -1;
268                 value = bfin_read32(&bss->regs->rfifo);
269                 if (rx)
270                         *rx++ = value;
271                 debug("rx:%x\n", value);
272         }
273
274         return 0;
275 }
276
277 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
278                 void *din, unsigned long flags)
279 {
280         struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
281         const u8 *tx = dout;
282         u8 *rx = din;
283         uint bytes = bitlen / 8;
284         int ret = 0;
285
286         debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
287                 slave->bus, slave->cs, bitlen, bytes, flags);
288
289         if (bitlen == 0)
290                 goto done;
291
292         /* we can only do 8 bit transfers */
293         if (bitlen % 8) {
294                 flags |= SPI_XFER_END;
295                 goto done;
296         }
297
298         if (flags & SPI_XFER_BEGIN)
299                 spi_cs_activate(slave);
300
301         ret = spi_pio_xfer(bss, tx, rx, bytes);
302
303  done:
304         if (flags & SPI_XFER_END)
305                 spi_cs_deactivate(slave);
306
307         return ret;
308 }