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
28
29#include <common.h>
30#include <asm/io.h>
31#include <i2c.h>
32#include <asm/errno.h>
33#include <asm/arch/hardware.h>
34
35
36struct zynq_i2c_registers {
37 u32 control;
38 u32 status;
39 u32 address;
40 u32 data;
41 u32 interrupt_status;
42 u32 transfer_size;
43 u32 slave_mon_pause;
44 u32 time_out;
45 u32 interrupt_mask;
46 u32 interrupt_enable;
47 u32 interrupt_disable;
48};
49
50
51#define ZYNQ_I2C_CONTROL_RW 0x00000001
52#define ZYNQ_I2C_CONTROL_MS 0x00000002
53#define ZYNQ_I2C_CONTROL_NEA 0x00000004
54#define ZYNQ_I2C_CONTROL_ACKEN 0x00000008
55#define ZYNQ_I2C_CONTROL_HOLD 0x00000010
56#define ZYNQ_I2C_CONTROL_SLVMON 0x00000020
57#define ZYNQ_I2C_CONTROL_CLR_FIFO 0x00000040
58#define ZYNQ_I2C_CONTROL_DIV_B_SHIFT 8
59#define ZYNQ_I2C_CONTROL_DIV_B_MASK 0x00003F00
60#define ZYNQ_I2C_CONTROL_DIV_A_SHIFT 14
61#define ZYNQ_I2C_CONTROL_DIV_A_MASK 0x0000C000
62
63
64#define ZYNQ_I2C_STATUS_RXDV 0x00000020
65#define ZYNQ_I2C_STATUS_TXDV 0x00000040
66#define ZYNQ_I2C_STATUS_RXOVF 0x00000080
67#define ZYNQ_I2C_STATUS_BA 0x00000100
68
69
70#define ZYNQ_I2C_INTERRUPT_COMP 0x00000001
71#define ZYNQ_I2C_INTERRUPT_DATA 0x00000002
72#define ZYNQ_I2C_INTERRUPT_NACK 0x00000004
73#define ZYNQ_I2C_INTERRUPT_TO 0x00000008
74#define ZYNQ_I2C_INTERRUPT_SLVRDY 0x00000010
75#define ZYNQ_I2C_INTERRUPT_RXOVF 0x00000020
76#define ZYNQ_I2C_INTERRUPT_TXOVF 0x00000040
77#define ZYNQ_I2C_INTERRUPT_RXUNF 0x00000080
78#define ZYNQ_I2C_INTERRUPT_ARBLOST 0x00000200
79
80#define ZYNQ_I2C_FIFO_DEPTH 16
81#define ZYNQ_I2C_TRANSFERT_SIZE_MAX 255
82
83#if defined(CONFIG_ZYNQ_I2C0)
84# define ZYNQ_I2C_BASE ZYNQ_I2C_BASEADDR0
85#else
86# define ZYNQ_I2C_BASE ZYNQ_I2C_BASEADDR1
87#endif
88
89static struct zynq_i2c_registers *zynq_i2c =
90 (struct zynq_i2c_registers *)ZYNQ_I2C_BASE;
91
92
93void i2c_init(int requested_speed, int slaveadd)
94{
95
96 writel((16 << ZYNQ_I2C_CONTROL_DIV_B_SHIFT) |
97 (2 << ZYNQ_I2C_CONTROL_DIV_A_SHIFT), &zynq_i2c->control);
98
99
100 setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_MS |
101 ZYNQ_I2C_CONTROL_ACKEN | ZYNQ_I2C_CONTROL_NEA);
102}
103
104#ifdef DEBUG
105static void zynq_i2c_debug_status(void)
106{
107 int int_status;
108 int status;
109 int_status = readl(&zynq_i2c->interrupt_status);
110
111 status = readl(&zynq_i2c->status);
112 if (int_status || status) {
113 debug("Status: ");
114 if (int_status & ZYNQ_I2C_INTERRUPT_COMP)
115 debug("COMP ");
116 if (int_status & ZYNQ_I2C_INTERRUPT_DATA)
117 debug("DATA ");
118 if (int_status & ZYNQ_I2C_INTERRUPT_NACK)
119 debug("NACK ");
120 if (int_status & ZYNQ_I2C_INTERRUPT_TO)
121 debug("TO ");
122 if (int_status & ZYNQ_I2C_INTERRUPT_SLVRDY)
123 debug("SLVRDY ");
124 if (int_status & ZYNQ_I2C_INTERRUPT_RXOVF)
125 debug("RXOVF ");
126 if (int_status & ZYNQ_I2C_INTERRUPT_TXOVF)
127 debug("TXOVF ");
128 if (int_status & ZYNQ_I2C_INTERRUPT_RXUNF)
129 debug("RXUNF ");
130 if (int_status & ZYNQ_I2C_INTERRUPT_ARBLOST)
131 debug("ARBLOST ");
132 if (status & ZYNQ_I2C_STATUS_RXDV)
133 debug("RXDV ");
134 if (status & ZYNQ_I2C_STATUS_TXDV)
135 debug("TXDV ");
136 if (status & ZYNQ_I2C_STATUS_RXOVF)
137 debug("RXOVF ");
138 if (status & ZYNQ_I2C_STATUS_BA)
139 debug("BA ");
140 debug("TS%d ", readl(&zynq_i2c->transfer_size));
141 debug("\n");
142 }
143}
144#endif
145
146
147static u32 zynq_i2c_wait(u32 mask)
148{
149 int timeout, int_status;
150
151 for (timeout = 0; timeout < 100; timeout++) {
152 udelay(100);
153 int_status = readl(&zynq_i2c->interrupt_status);
154 if (int_status & mask)
155 break;
156 }
157#ifdef DEBUG
158 zynq_i2c_debug_status();
159#endif
160
161 writel(int_status & mask, &zynq_i2c->interrupt_status);
162
163 return int_status & mask;
164}
165
166
167
168
169
170int i2c_probe(u8 dev)
171{
172
173 setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
174 ZYNQ_I2C_CONTROL_RW);
175 clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
176 writel(0xFF, &zynq_i2c->interrupt_status);
177 writel(dev, &zynq_i2c->address);
178 writel(1, &zynq_i2c->transfer_size);
179
180 return (zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP |
181 ZYNQ_I2C_INTERRUPT_NACK) &
182 ZYNQ_I2C_INTERRUPT_COMP) ? 0 : -ETIMEDOUT;
183}
184
185
186
187
188
189int i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
190{
191 u32 status;
192 u32 i = 0;
193 u8 *cur_data = data;
194
195
196 if ((length < 0) || (length > ZYNQ_I2C_TRANSFERT_SIZE_MAX))
197 return -EINVAL;
198
199
200 setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
201 ZYNQ_I2C_CONTROL_HOLD);
202
203
204
205
206 clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW |
207 ZYNQ_I2C_CONTROL_HOLD);
208 writel(0xFF, &zynq_i2c->interrupt_status);
209 while (alen--)
210 writel(addr >> (8*alen), &zynq_i2c->data);
211 writel(dev, &zynq_i2c->address);
212
213
214 if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
215
216 clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
217 return -ETIMEDOUT;
218 }
219 debug("Device acked address\n");
220
221 setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
222 ZYNQ_I2C_CONTROL_RW);
223
224 writel(dev, &zynq_i2c->address);
225 writel(length, &zynq_i2c->transfer_size);
226
227
228 do {
229 status = zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP |
230 ZYNQ_I2C_INTERRUPT_DATA);
231 if (!status) {
232
233 clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
234 return -ETIMEDOUT;
235 }
236 debug("Read %d bytes\n",
237 length - readl(&zynq_i2c->transfer_size));
238 for (; i < length - readl(&zynq_i2c->transfer_size); i++)
239 *(cur_data++) = readl(&zynq_i2c->data);
240 } while (readl(&zynq_i2c->transfer_size) != 0);
241
242 clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
243
244#ifdef DEBUG
245 zynq_i2c_debug_status();
246#endif
247 return 0;
248}
249
250
251
252
253
254int i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
255{
256 u8 *cur_data = data;
257
258
259 setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
260 ZYNQ_I2C_CONTROL_HOLD);
261 clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW);
262 writel(0xFF, &zynq_i2c->interrupt_status);
263 while (alen--)
264 writel(addr >> (8*alen), &zynq_i2c->data);
265
266 writel(dev, &zynq_i2c->address);
267 if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
268
269 clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
270 return -ETIMEDOUT;
271 }
272
273 debug("Device acked address\n");
274 while (length--) {
275 writel(*(cur_data++), &zynq_i2c->data);
276 if (readl(&zynq_i2c->transfer_size) == ZYNQ_I2C_FIFO_DEPTH) {
277 if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
278
279 clrbits_le32(&zynq_i2c->control,
280 ZYNQ_I2C_CONTROL_HOLD);
281 return -ETIMEDOUT;
282 }
283 }
284 }
285
286
287 clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
288
289 if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP))
290 return -ETIMEDOUT;
291 return 0;
292}
293
294int i2c_set_bus_num(unsigned int bus)
295{
296
297 if (bus > 0)
298 return -1;
299 return 0;
300}
301
302unsigned int i2c_get_bus_num(void)
303{
304
305 return 0;
306}
307