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 <i2c.h>
29#include <asm/errno.h>
30#include <asm/io.h>
31
32
33
34
35
36
37#if defined(CONFIG_ORION5X)
38#include <asm/arch/orion5x.h>
39#elif defined(CONFIG_KIRKWOOD)
40#include <asm/arch/kirkwood.h>
41#else
42#error Driver mvtwsi not supported by SoC or board
43#endif
44
45
46
47
48
49struct mvtwsi_registers {
50 u32 slave_address;
51 u32 data;
52 u32 control;
53 union {
54 u32 status;
55 u32 baudrate;
56 };
57 u32 xtnd_slave_addr;
58 u32 reserved[2];
59 u32 soft_reset;
60};
61
62
63
64
65
66#define MVTWSI_CONTROL_ACK 0x00000004
67#define MVTWSI_CONTROL_IFLG 0x00000008
68#define MVTWSI_CONTROL_STOP 0x00000010
69#define MVTWSI_CONTROL_START 0x00000020
70#define MVTWSI_CONTROL_TWSIEN 0x00000040
71#define MVTWSI_CONTROL_INTEN 0x00000080
72
73
74
75
76
77
78
79
80
81#define MVTWSI_STATUS_START 0x08
82#define MVTWSI_STATUS_REPEATED_START 0x10
83#define MVTWSI_STATUS_ADDR_W_ACK 0x18
84#define MVTWSI_STATUS_DATA_W_ACK 0x28
85#define MVTWSI_STATUS_ADDR_R_ACK 0x40
86#define MVTWSI_STATUS_ADDR_R_NAK 0x48
87#define MVTWSI_STATUS_DATA_R_ACK 0x50
88#define MVTWSI_STATUS_DATA_R_NAK 0x58
89#define MVTWSI_STATUS_IDLE 0xF8
90
91
92
93
94
95static struct mvtwsi_registers *twsi =
96 (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE;
97
98
99
100
101
102
103
104
105
106
107
108#define MVTWSI_ERROR_WRONG_STATUS 0x01
109#define MVTWSI_ERROR_TIMEOUT 0x02
110
111#define MVTWSI_ERROR(ec, lc, ls, es) (((ec << 24) & 0xFF000000) | \
112 ((lc << 16) & 0x00FF0000) | ((ls<<8) & 0x0000FF00) | (es & 0xFF))
113
114
115
116
117
118static int twsi_wait(int expected_status)
119{
120 int control, status;
121 int timeout = 1000;
122
123 do {
124 control = readl(&twsi->control);
125 if (control & MVTWSI_CONTROL_IFLG) {
126 status = readl(&twsi->status);
127 if (status == expected_status)
128 return 0;
129 else
130 return MVTWSI_ERROR(
131 MVTWSI_ERROR_WRONG_STATUS,
132 control, status, expected_status);
133 }
134 udelay(10);
135 } while (timeout--);
136 status = readl(&twsi->status);
137 return MVTWSI_ERROR(
138 MVTWSI_ERROR_TIMEOUT, control, status, expected_status);
139}
140
141
142
143
144
145
146
147
148static u8 twsi_control_flags = MVTWSI_CONTROL_TWSIEN;
149
150
151
152
153
154static int twsi_start(int expected_status)
155{
156
157 twsi_control_flags |= MVTWSI_CONTROL_TWSIEN;
158
159 writel(twsi_control_flags | MVTWSI_CONTROL_START, &twsi->control);
160
161 return twsi_wait(expected_status);
162}
163
164
165
166
167static int twsi_send(u8 byte, int expected_status)
168{
169
170 writel(byte, &twsi->data);
171
172 writel(twsi_control_flags, &twsi->control);
173
174 return twsi_wait(expected_status);
175}
176
177
178
179
180
181static int twsi_recv(u8 *byte)
182{
183 int expected_status, status;
184
185
186 if (twsi_control_flags & MVTWSI_CONTROL_ACK)
187 expected_status = MVTWSI_STATUS_DATA_R_ACK;
188 else
189 expected_status = MVTWSI_STATUS_DATA_R_NAK;
190
191 writel(twsi_control_flags, &twsi->control);
192
193 status = twsi_wait(expected_status);
194
195 if (status == 0)
196 *byte = readl(&twsi->data);
197
198 return status;
199}
200
201
202
203
204
205static int twsi_stop(int status)
206{
207 int control, stop_status;
208 int timeout = 1000;
209
210
211 control = MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_STOP;
212 writel(control, &twsi->control);
213
214 do {
215 stop_status = readl(&twsi->status);
216 if (stop_status == MVTWSI_STATUS_IDLE)
217 break;
218 udelay(10);
219 } while (timeout--);
220 control = readl(&twsi->control);
221 if (stop_status != MVTWSI_STATUS_IDLE)
222 if (status == 0)
223 status = MVTWSI_ERROR(
224 MVTWSI_ERROR_TIMEOUT,
225 control, status, MVTWSI_STATUS_IDLE);
226 return status;
227}
228
229
230
231
232
233
234#define TWSI_FREQUENCY(m, n) \
235 ((u8) (CONFIG_SYS_TCLK / (10 * (m + 1) * 2 * (1 << n))))
236
237
238
239
240
241
242
243
244
245static u8 twsi_baud_rate = 0x44;
246
247static u8 twsi_actual_speed = TWSI_FREQUENCY(4, 4);
248
249static u8 twsi_slave_address;
250
251
252
253
254
255
256
257static void twsi_reset(void)
258{
259
260 twsi_control_flags = MVTWSI_CONTROL_TWSIEN;
261
262 writel(0, &twsi->soft_reset);
263
264 udelay(20000);
265
266 writel(twsi_baud_rate, &twsi->baudrate);
267
268 writel(twsi_slave_address, &twsi->slave_address);
269 writel(0, &twsi->xtnd_slave_addr);
270
271 (void) twsi_stop(0);
272}
273
274
275
276
277
278void i2c_init(int requested_speed, int slaveadd)
279{
280 int tmp_speed, highest_speed, n, m;
281 int baud = 0x44;
282
283
284 highest_speed = 0;
285
286 for (n = 0; n < 8; n++) {
287 for (m = 0; m < 16; m++) {
288 tmp_speed = TWSI_FREQUENCY(m, n);
289 if ((tmp_speed <= requested_speed)
290 && (tmp_speed > highest_speed)) {
291 highest_speed = tmp_speed;
292 baud = (m << 3) | n;
293 }
294 }
295 }
296
297 twsi_baud_rate = baud;
298 twsi_actual_speed = highest_speed;
299 twsi_slave_address = slaveadd;
300
301 twsi_reset();
302}
303
304
305
306
307
308
309static int i2c_begin(int expected_start_status, u8 addr)
310{
311 int status, expected_addr_status;
312
313
314 if (addr & 1)
315 expected_addr_status = MVTWSI_STATUS_ADDR_R_ACK;
316 else
317 expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
318
319 status = twsi_start(expected_start_status);
320
321 if (status == 0)
322 status = twsi_send(addr, expected_addr_status);
323
324 return status;
325}
326
327
328
329
330
331int i2c_probe(uchar chip)
332{
333 u8 dummy_byte;
334 int status;
335
336
337 status = i2c_begin(MVTWSI_STATUS_START, (chip << 1) | 1);
338
339 if (status == 0)
340 status = twsi_recv(&dummy_byte);
341
342 twsi_stop(0);
343
344 return status;
345}
346
347
348
349
350
351
352
353
354
355
356
357int i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
358{
359 int status;
360
361
362 status = i2c_begin(MVTWSI_STATUS_START, (dev << 1));
363
364 while ((status == 0) && alen--)
365 status = twsi_send(addr >> (8*alen),
366 MVTWSI_STATUS_DATA_W_ACK);
367
368 if (status == 0)
369 status = i2c_begin(
370 MVTWSI_STATUS_REPEATED_START, (dev << 1) | 1);
371
372 if (length > 0)
373 twsi_control_flags |= MVTWSI_CONTROL_ACK;
374
375 while ((status == 0) && length--) {
376
377 if (length == 0)
378 twsi_control_flags &= ~MVTWSI_CONTROL_ACK;
379
380 status = twsi_recv(data++);
381 }
382
383 status = twsi_stop(status);
384
385 return status;
386}
387
388
389
390
391
392int i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
393{
394 int status;
395
396
397 status = i2c_begin(MVTWSI_STATUS_START, (dev << 1));
398
399 while ((status == 0) && alen--)
400 status = twsi_send(addr >> (8*alen),
401 MVTWSI_STATUS_DATA_W_ACK);
402
403 while ((status == 0) && (length-- > 0))
404 status = twsi_send(*(data++), MVTWSI_STATUS_DATA_W_ACK);
405
406 status = twsi_stop(status);
407
408 return status;
409}
410
411
412
413
414int i2c_set_bus_num(unsigned int bus)
415{
416 if (bus > 0) {
417 return -1;
418 }
419 return 0;
420}
421
422
423
424
425unsigned int i2c_get_bus_num(void)
426{
427 return 0;
428}
429