1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <common.h>
28#include <malloc.h>
29#include <spi.h>
30#include <asm/arch/kirkwood.h>
31#include <asm/arch/spi.h>
32#include <asm/arch/mpp.h>
33
34static struct kwspi_registers *spireg = (struct kwspi_registers *)KW_SPI_BASE;
35
36struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
37 unsigned int max_hz, unsigned int mode)
38{
39 struct spi_slave *slave;
40 u32 data;
41 u32 kwspi_mpp_config[] = {
42 MPP0_GPIO,
43 MPP7_SPI_SCn,
44 0
45 };
46
47 if (!spi_cs_is_valid(bus, cs))
48 return NULL;
49
50 slave = malloc(sizeof(struct spi_slave));
51 if (!slave)
52 return NULL;
53
54 slave->bus = bus;
55 slave->cs = cs;
56
57 writel(~KWSPI_CSN_ACT | KWSPI_SMEMRDY, &spireg->ctrl);
58
59
60 data = ((CONFIG_SYS_TCLK / 2) / max_hz) & KWSPI_CLKPRESCL_MASK;
61 data |= 0x10;
62
63
64 writel(KWSPI_ADRLEN_3BYTE | data, &spireg->cfg);
65 debug("data = 0x%08x \n", data);
66
67 writel(KWSPI_SMEMRDIRQ, &spireg->irq_cause);
68 writel(KWSPI_IRQMASK, spireg->irq_mask);
69
70
71 if (cs) {
72 kwspi_mpp_config[0] = MPP0_GPIO;
73 kwspi_mpp_config[1] = MPP7_SPI_SCn;
74 } else {
75 kwspi_mpp_config[0] = MPP0_SPI_SCn;
76 kwspi_mpp_config[1] = MPP7_GPO;
77 }
78 kirkwood_mpp_conf(kwspi_mpp_config);
79
80 return slave;
81}
82
83void spi_free_slave(struct spi_slave *slave)
84{
85 free(slave);
86}
87
88int spi_claim_bus(struct spi_slave *slave)
89{
90 return 0;
91}
92
93void spi_release_bus(struct spi_slave *slave)
94{
95}
96
97#ifndef CONFIG_SPI_CS_IS_VALID
98
99
100
101
102
103int spi_cs_is_valid(unsigned int bus, unsigned int cs)
104{
105 return (bus == 0 && (cs == 0 || cs == 1));
106}
107#endif
108
109void spi_cs_activate(struct spi_slave *slave)
110{
111 writel(readl(&spireg->ctrl) | KWSPI_IRQUNMASK, &spireg->ctrl);
112}
113
114void spi_cs_deactivate(struct spi_slave *slave)
115{
116 writel(readl(&spireg->ctrl) & KWSPI_IRQMASK, &spireg->ctrl);
117}
118
119int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
120 void *din, unsigned long flags)
121{
122 unsigned int tmpdout, tmpdin;
123 int tm, isread = 0;
124
125 debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
126 slave->bus, slave->cs, dout, din, bitlen);
127
128 if (flags & SPI_XFER_BEGIN)
129 spi_cs_activate(slave);
130
131
132
133
134
135 writel(((readl(&spireg->cfg) & ~KWSPI_XFERLEN_MASK) |
136 KWSPI_XFERLEN_1BYTE), &spireg->cfg);
137
138 while (bitlen > 4) {
139 debug("loopstart bitlen %d\n", bitlen);
140 tmpdout = 0;
141
142
143 if (dout)
144 tmpdout = *(u32 *) dout & 0x0ff;
145
146 writel(~KWSPI_SMEMRDIRQ, &spireg->irq_cause);
147 writel(tmpdout, &spireg->dout);
148 debug("*** spi_xfer: ... %08x written, bitlen %d\n",
149 tmpdout, bitlen);
150
151
152
153
154
155
156 for (tm = 0, isread = 0; tm < KWSPI_TIMEOUT; ++tm) {
157 if (readl(&spireg->irq_cause) & KWSPI_SMEMRDIRQ) {
158 isread = 1;
159 tmpdin = readl(&spireg->din);
160 debug
161 ("spi_xfer: din %08x..%08x read\n",
162 din, tmpdin);
163
164 if (din) {
165 *((u8 *) din) = (u8) tmpdin;
166 din += 1;
167 }
168 if (dout)
169 dout += 1;
170 bitlen -= 8;
171 }
172 if (isread)
173 break;
174 }
175 if (tm >= KWSPI_TIMEOUT)
176 printf("*** spi_xfer: Time out during SPI transfer\n");
177
178 debug("loopend bitlen %d\n", bitlen);
179 }
180
181 if (flags & SPI_XFER_END)
182 spi_cs_deactivate(slave);
183
184 return 0;
185}
186