1
2
3
4
5
6
7
8#include <common.h>
9
10#include <malloc.h>
11#include <spi.h>
12#include <asm/mpc8xxx_spi.h>
13
14#define SPI_EV_NE (0x80000000 >> 22)
15#define SPI_EV_NF (0x80000000 >> 23)
16
17#define SPI_MODE_LOOP (0x80000000 >> 1)
18#define SPI_MODE_REV (0x80000000 >> 5)
19#define SPI_MODE_MS (0x80000000 >> 6)
20#define SPI_MODE_EN (0x80000000 >> 7)
21
22#define SPI_TIMEOUT 1000
23
24struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
25 unsigned int max_hz, unsigned int mode)
26{
27 struct spi_slave *slave;
28
29 if (!spi_cs_is_valid(bus, cs))
30 return NULL;
31
32 slave = spi_alloc_slave_base(bus, cs);
33 if (!slave)
34 return NULL;
35
36
37
38
39
40
41 return slave;
42}
43
44void spi_free_slave(struct spi_slave *slave)
45{
46 free(slave);
47}
48
49void spi_init(void)
50{
51 volatile spi8xxx_t *spi = &((immap_t *) (CONFIG_SYS_IMMR))->spi;
52
53
54
55
56
57 spi->mode = SPI_MODE_REV | SPI_MODE_MS | SPI_MODE_EN;
58 spi->mode = (spi->mode & 0xfff0ffff) | BIT(16);
59
60 spi->event = 0xffffffff;
61 spi->mask = 0x00000000;
62 spi->com = 0;
63}
64
65int spi_claim_bus(struct spi_slave *slave)
66{
67 return 0;
68}
69
70void spi_release_bus(struct spi_slave *slave)
71{
72
73}
74
75int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
76 void *din, unsigned long flags)
77{
78 volatile spi8xxx_t *spi = &((immap_t *) (CONFIG_SYS_IMMR))->spi;
79 unsigned int tmpdout, tmpdin, event;
80 int numBlks = DIV_ROUND_UP(bitlen, 32);
81 int tm, isRead = 0;
82 unsigned char charSize = 32;
83
84 debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
85 slave->bus, slave->cs, *(uint *) dout, *(uint *) din, bitlen);
86
87 if (flags & SPI_XFER_BEGIN)
88 spi_cs_activate(slave);
89
90 spi->event = 0xffffffff;
91
92
93 while (numBlks--) {
94 tmpdout = 0;
95 charSize = (bitlen >= 32 ? 32 : bitlen);
96
97
98 tmpdout = *(u32 *) dout >> (32 - charSize);
99
100
101
102
103
104
105
106
107
108 spi->mode &= ~SPI_MODE_EN;
109
110 if (bitlen <= 16) {
111 if (bitlen <= 4)
112 spi->mode = (spi->mode & 0xff0fffff) |
113 (3 << 20);
114 else
115 spi->mode = (spi->mode & 0xff0fffff) |
116 ((bitlen - 1) << 20);
117 } else {
118 spi->mode = (spi->mode & 0xff0fffff);
119
120 bitlen -= 32;
121 dout += 4;
122 }
123
124 spi->mode |= SPI_MODE_EN;
125
126 spi->tx = tmpdout;
127 debug("*** spi_xfer: ... %08x written\n", tmpdout);
128
129
130
131
132
133
134 for (tm = 0, isRead = 0; tm < SPI_TIMEOUT; ++tm) {
135 event = spi->event;
136 if (event & SPI_EV_NE) {
137 tmpdin = spi->rx;
138 spi->event |= SPI_EV_NE;
139 isRead = 1;
140
141 *(u32 *) din = (tmpdin << (32 - charSize));
142 if (charSize == 32) {
143
144 din += 4;
145 }
146 }
147
148
149
150
151
152
153 if (isRead && (event & SPI_EV_NF))
154 break;
155 }
156 if (tm >= SPI_TIMEOUT)
157 puts("*** spi_xfer: Time out during SPI transfer");
158
159 debug("*** spi_xfer: transfer ended. Value=%08x\n", tmpdin);
160 }
161
162 if (flags & SPI_XFER_END)
163 spi_cs_deactivate(slave);
164
165 return 0;
166}
167