]> git.sur5r.net Git - u-boot/blob - cpu/mcf5227x/dspi.c
Merge branch 'master' of git://git.denx.de/u-boot-at91
[u-boot] / cpu / mcf5227x / dspi.c
1 /*
2  *
3  * (C) Copyright 2000-2003
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  *
6  * Copyright (C) 2004-2008 Freescale Semiconductor, Inc.
7  * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27
28 #include <common.h>
29 #include <spi.h>
30 #include <malloc.h>
31
32 #if defined(CONFIG_CF_DSPI)
33 #include <asm/immap.h>
34
35 void dspi_init(void)
36 {
37         volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO;
38         volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
39
40         gpio->par_dspi =
41             GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT |
42             GPIO_PAR_DSPI_SCK_SCK;
43
44         dspi->dmcr = DSPI_DMCR_MSTR | DSPI_DMCR_CSIS7 | DSPI_DMCR_CSIS6 |
45             DSPI_DMCR_CSIS5 | DSPI_DMCR_CSIS4 | DSPI_DMCR_CSIS3 |
46             DSPI_DMCR_CSIS2 | DSPI_DMCR_CSIS1 | DSPI_DMCR_CSIS0 |
47             DSPI_DMCR_CRXF | DSPI_DMCR_CTXF;
48
49 #ifdef CONFIG_SYS_DSPI_DCTAR0
50         dspi->dctar0 = CONFIG_SYS_DSPI_DCTAR0;
51 #endif
52 #ifdef CONFIG_SYS_DSPI_DCTAR1
53         dspi->dctar1 = CONFIG_SYS_DSPI_DCTAR1;
54 #endif
55 #ifdef CONFIG_SYS_DSPI_DCTAR2
56         dspi->dctar2 = CONFIG_SYS_DSPI_DCTAR2;
57 #endif
58 #ifdef CONFIG_SYS_DSPI_DCTAR3
59         dspi->dctar3 = CONFIG_SYS_DSPI_DCTAR3;
60 #endif
61 #ifdef CONFIG_SYS_DSPI_DCTAR4
62         dspi->dctar4 = CONFIG_SYS_DSPI_DCTAR4;
63 #endif
64 #ifdef CONFIG_SYS_DSPI_DCTAR5
65         dspi->dctar5 = CONFIG_SYS_DSPI_DCTAR5;
66 #endif
67 #ifdef CONFIG_SYS_DSPI_DCTAR6
68         dspi->dctar6 = CONFIG_SYS_DSPI_DCTAR6;
69 #endif
70 #ifdef CONFIG_SYS_DSPI_DCTAR7
71         dspi->dctar7 = CONFIG_SYS_DSPI_DCTAR7;
72 #endif
73 }
74
75 void dspi_tx(int chipsel, u8 attrib, u16 data)
76 {
77         volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
78
79         while ((dspi->dsr & 0x0000F000) >= 4) ;
80
81         dspi->dtfr = (attrib << 24) | ((1 << chipsel) << 16) | data;
82 }
83
84 u16 dspi_rx(void)
85 {
86         volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
87
88         while ((dspi->dsr & 0x000000F0) == 0) ;
89
90         return (dspi->drfr & 0xFFFF);
91 }
92
93 #if defined(CONFIG_CMD_SPI)
94 void spi_init_f(void)
95 {
96 }
97
98 void spi_init_r(void)
99 {
100 }
101
102 void spi_init(void)
103 {
104         dspi_init();
105 }
106
107 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
108                                   unsigned int max_hz, unsigned int mode)
109 {
110         volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO;
111         struct spi_slave *slave;
112
113         slave = malloc(sizeof(struct spi_slave));
114         if (!slave)
115                 return NULL;
116
117         switch (cs) {
118         case 0:
119                 gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0;
120                 gpio->par_dspi |= GPIO_PAR_DSPI_PCS0_PCS0;
121                 break;
122         case 2:
123                 gpio->par_timer &= GPIO_PAR_TIMER_T2IN_MASK;
124                 gpio->par_timer |= GPIO_PAR_TIMER_T2IN_DSPIPCS2;
125                 break;
126         }
127
128         slave->bus = bus;
129         slave->cs = cs;
130
131         return slave;
132 }
133
134 void spi_free_slave(struct spi_slave *slave)
135 {
136         volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO;
137
138         switch (slave->cs) {
139         case 0:
140                 gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0;
141                 break;
142         case 2:
143                 gpio->par_timer &= GPIO_PAR_TIMER_T2IN_MASK;
144                 break;
145         }
146
147         free(slave);
148 }
149
150 int spi_claim_bus(struct spi_slave *slave)
151 {
152         return 0;
153 }
154
155 void spi_release_bus(struct spi_slave *slave)
156 {
157 }
158
159 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
160              void *din, unsigned long flags)
161 {
162         static int bWrite = 0;
163         u8 *spi_rd, *spi_wr;
164         int len = bitlen >> 3;
165
166         spi_rd = (u8 *) din;
167         spi_wr = (u8 *) dout;
168
169         /* command handling */
170         if (((len == 4) || (len == 1) || (len == 5)) && (dout != NULL)) {
171                 switch (*spi_wr) {
172                 case 0x02:      /* Page Prog */
173                         bWrite = 1;
174                         dspi_tx(slave->cs, 0x80, spi_wr[0]);
175                         dspi_rx();
176                         dspi_tx(slave->cs, 0x80, spi_wr[1]);
177                         dspi_rx();
178                         dspi_tx(slave->cs, 0x80, spi_wr[2]);
179                         dspi_rx();
180                         dspi_tx(slave->cs, 0x80, spi_wr[3]);
181                         dspi_rx();
182                         return 0;
183                 case 0x05:      /* Read Status */
184                         if (len == 4)
185                                 if ((spi_wr[1] == 0xFF) && (spi_wr[2] == 0xFF)
186                                     && (spi_wr[3] == 0xFF)) {
187                                         dspi_tx(slave->cs, 0x80, *spi_wr);
188                                         dspi_rx();
189                                 }
190                         return 0;
191                 case 0x06:      /* WREN */
192                         dspi_tx(slave->cs, 0x00, *spi_wr);
193                         dspi_rx();
194                         return 0;
195                 case 0x0B:      /* Fast read */
196                         if ((len == 5) && (spi_wr[4] == 0)) {
197                                 dspi_tx(slave->cs, 0x80, spi_wr[0]);
198                                 dspi_rx();
199                                 dspi_tx(slave->cs, 0x80, spi_wr[1]);
200                                 dspi_rx();
201                                 dspi_tx(slave->cs, 0x80, spi_wr[2]);
202                                 dspi_rx();
203                                 dspi_tx(slave->cs, 0x80, spi_wr[3]);
204                                 dspi_rx();
205                                 dspi_tx(slave->cs, 0x80, spi_wr[4]);
206                                 dspi_rx();
207                         }
208                         return 0;
209                 case 0x9F:      /* RDID */
210                         dspi_tx(slave->cs, 0x80, *spi_wr);
211                         dspi_rx();
212                         return 0;
213                 case 0xD8:      /* Sector erase */
214                         if (len == 4)
215                                 if ((spi_wr[2] == 0) && (spi_wr[3] == 0)) {
216                                         dspi_tx(slave->cs, 0x80, spi_wr[0]);
217                                         dspi_rx();
218                                         dspi_tx(slave->cs, 0x80, spi_wr[1]);
219                                         dspi_rx();
220                                         dspi_tx(slave->cs, 0x80, spi_wr[2]);
221                                         dspi_rx();
222                                         dspi_tx(slave->cs, 0x00, spi_wr[3]);
223                                         dspi_rx();
224                                 }
225                         return 0;
226                 }
227         }
228
229         if (bWrite)
230                 len--;
231
232         while (len--) {
233                 if (dout != NULL) {
234                         dspi_tx(slave->cs, 0x80, *spi_wr);
235                         dspi_rx();
236                         spi_wr++;
237                 }
238
239                 if (din != NULL) {
240                         dspi_tx(slave->cs, 0x80, 0);
241                         *spi_rd = dspi_rx();
242                         spi_rd++;
243                 }
244         }
245
246         if (flags == SPI_XFER_END) {
247                 if (bWrite) {
248                         dspi_tx(slave->cs, 0x00, *spi_wr);
249                         dspi_rx();
250                         bWrite = 0;
251                 } else {
252                         dspi_tx(slave->cs, 0x00, 0);
253                         dspi_rx();
254                 }
255         }
256
257         return 0;
258 }
259 #endif                          /* CONFIG_CMD_SPI */
260
261 #endif                          /* CONFIG_CF_DSPI */