]> git.ipfire.org Git - people/ms/u-boot.git/blob - board/esd/cpci750/i2c.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[people/ms/u-boot.git] / board / esd / cpci750 / i2c.c
1 /*
2 * (C) Copyright 2000
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 *
7 * Hacked for the DB64360 board by Ingo.Assmus@keymile.com
8 * extra improvments by Brain Waite
9 * for cpci750 by reinhard.arlt@esd-electronics.com
10 */
11 #include <common.h>
12 #include <mpc8xx.h>
13 #include <malloc.h>
14 #include <i2c.h>
15 #include "../../Marvell/include/mv_gen_reg.h"
16 #include "../../Marvell/include/core.h"
17
18 #define I2C_DELAY 100
19 #undef DEBUG_I2C
20
21 #ifdef DEBUG_I2C
22 #define DP(x) x
23 #else
24 #define DP(x)
25 #endif
26
27 /* Assuming that there is only one master on the bus (us) */
28
29 void i2c_init (int speed, int slaveaddr)
30 {
31 unsigned int n, m, freq, margin, power;
32 unsigned int actualN = 0, actualM = 0;
33 unsigned int minMargin = 0xffffffff;
34 unsigned int tclk = CONFIG_SYS_TCLK;
35 unsigned int i2cFreq = speed; /* 100000 max. Fast mode not supported */
36
37 DP (puts ("i2c_init\n"));
38 /* gtI2cMasterInit */
39 for (n = 0; n < 8; n++) {
40 for (m = 0; m < 16; m++) {
41 power = 2 << n; /* power = 2^(n+1) */
42 freq = tclk / (10 * (m + 1) * power);
43 if (i2cFreq > freq)
44 margin = i2cFreq - freq;
45 else
46 margin = freq - i2cFreq;
47 if (margin < minMargin) {
48 minMargin = margin;
49 actualN = n;
50 actualM = m;
51 }
52 }
53 }
54
55 DP (puts ("setup i2c bus\n"));
56
57 /* Setup bus */
58 /* gtI2cReset */
59 GT_REG_WRITE (I2C_SOFT_RESET, 0);
60 asm(" sync");
61 GT_REG_WRITE (I2C_CONTROL, 0);
62 asm(" sync");
63
64 DP (puts ("set baudrate\n"));
65
66 GT_REG_WRITE (I2C_STATUS_BAUDE_RATE, (actualM << 3) | actualN);
67 asm(" sync");
68
69 DP (puts ("udelay...\n"));
70
71 udelay (I2C_DELAY);
72
73 GT_REG_WRITE (I2C_CONTROL, (0x1 << 2) | (0x1 << 6));
74 asm(" sync");
75 }
76
77
78 static uchar i2c_select_device (uchar dev_addr, uchar read, int ten_bit)
79 {
80 unsigned int status, data, bits = 7;
81 unsigned int control;
82 int count = 0;
83
84 DP (puts ("i2c_select_device\n"));
85
86 /* Output slave address */
87
88 if (ten_bit) {
89 bits = 10;
90 }
91
92 GT_REG_READ (I2C_CONTROL, &control);
93 control |= (0x1 << 2);
94 GT_REG_WRITE (I2C_CONTROL, control);
95 asm(" sync");
96
97 GT_REG_READ (I2C_CONTROL, &control);
98 control |= (0x1 << 5); /* generate the I2C_START_BIT */
99 GT_REG_WRITE (I2C_CONTROL, control);
100 asm(" sync");
101 RESET_REG_BITS (I2C_CONTROL, (0x01 << 3));
102 asm(" sync");
103
104 GT_REG_READ (I2C_CONTROL, &status);
105 while ((status & 0x08) != 0x08) {
106 GT_REG_READ (I2C_CONTROL, &status);
107 }
108
109
110 count = 0;
111
112 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
113 while (((status & 0xff) != 0x08) && ((status & 0xff) != 0x10)){
114 if (count > 200) {
115 #ifdef DEBUG_I2C
116 printf ("Failed to set startbit: 0x%02x\n", status);
117 #endif
118 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
119 asm(" sync");
120 return (status);
121 }
122 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
123 count++;
124 }
125
126 DP (puts ("i2c_select_device:write addr byte\n"));
127
128 /* assert the address */
129
130 data = (dev_addr << 1);
131 /* set the read bit */
132 data |= read;
133 GT_REG_WRITE (I2C_DATA, data);
134 asm(" sync");
135 RESET_REG_BITS (I2C_CONTROL, BIT3);
136 asm(" sync");
137
138 GT_REG_READ (I2C_CONTROL, &status);
139 while ((status & 0x08) != 0x08) {
140 GT_REG_READ (I2C_CONTROL, &status);
141 }
142
143 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
144 count = 0;
145 while (((status & 0xff) != 0x40) && ((status & 0xff) != 0x18)) {
146 if (count > 200) {
147 #ifdef DEBUG_I2C
148 printf ("Failed to write address: 0x%02x\n", status);
149 #endif
150 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
151 return (status);
152 }
153 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
154 asm(" sync");
155 count++;
156 }
157
158 if (bits == 10) {
159 printf ("10 bit I2C addressing not yet implemented\n");
160 return (0xff);
161 }
162
163 return (0);
164 }
165
166 static uchar i2c_get_data (uchar * return_data, int len)
167 {
168
169 unsigned int data, status;
170 int count = 0;
171
172 DP (puts ("i2c_get_data\n"));
173
174 while (len) {
175
176 RESET_REG_BITS (I2C_CONTROL, BIT3);
177 asm(" sync");
178
179 /* Get and return the data */
180
181 GT_REG_READ (I2C_CONTROL, &status);
182 while ((status & 0x08) != 0x08) {
183 GT_REG_READ (I2C_CONTROL, &status);
184 }
185
186 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
187 count++;
188 while ((status & 0xff) != 0x50) {
189 if (count > 20) {
190 #ifdef DEBUG_I2C
191 printf ("Failed to get data len status: 0x%02x\n", status);
192 #endif
193 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
194 asm(" sync");
195 return 0;
196 }
197 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
198 count++;
199 }
200 GT_REG_READ (I2C_DATA, &data);
201 len--;
202 *return_data = (uchar) data;
203 return_data++;
204
205 }
206 RESET_REG_BITS (I2C_CONTROL, BIT2 | BIT3);
207 asm(" sync");
208 count = 0;
209
210 GT_REG_READ (I2C_CONTROL, &status);
211 while ((status & 0x08) != 0x08) {
212 GT_REG_READ (I2C_CONTROL, &status);
213 }
214
215 while ((status & 0xff) != 0x58) {
216 if (count > 2000) {
217 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
218 return (status);
219 }
220 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
221 count++;
222 }
223 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /* stop */
224 asm(" sync");
225 RESET_REG_BITS (I2C_CONTROL, (0x1 << 3));
226 asm(" sync");
227
228 return (0);
229 }
230
231
232 static uchar i2c_write_data (unsigned int *data, int len)
233 {
234 unsigned int status;
235 int count;
236 unsigned int temp;
237 unsigned int *temp_ptr = data;
238
239 DP (puts ("i2c_write_data\n"));
240
241 while (len) {
242 count = 0;
243 temp = (unsigned int) (*temp_ptr);
244 GT_REG_WRITE (I2C_DATA, temp);
245 asm(" sync");
246 RESET_REG_BITS (I2C_CONTROL, (0x1 << 3));
247 asm(" sync");
248
249 GT_REG_READ (I2C_CONTROL, &status);
250 while ((status & 0x08) != 0x08) {
251 GT_REG_READ (I2C_CONTROL, &status);
252 }
253
254 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
255 count++;
256 while ((status & 0xff) != 0x28) {
257 if (count > 200) {
258 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
259 asm(" sync");
260 return (status);
261 }
262 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
263 count++;
264 }
265 len--;
266 temp_ptr++;
267 }
268 return (0);
269 }
270
271
272 static uchar i2c_write_byte (unsigned char *data, int len)
273 {
274 unsigned int status;
275 int count;
276 unsigned int temp;
277 unsigned char *temp_ptr = data;
278
279 DP (puts ("i2c_write_byte\n"));
280
281 while (len) {
282 count = 0;
283 /* Set and assert the data */
284 temp = *temp_ptr;
285 GT_REG_WRITE (I2C_DATA, temp);
286 asm(" sync");
287 RESET_REG_BITS (I2C_CONTROL, (0x1 << 3));
288 asm(" sync");
289
290
291 GT_REG_READ (I2C_CONTROL, &status);
292 while ((status & 0x08) != 0x08) {
293 GT_REG_READ (I2C_CONTROL, &status);
294 }
295
296 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
297 count++;
298 while ((status & 0xff) != 0x28) {
299 if (count > 200) {
300 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
301 asm(" sync");
302 return (status);
303 }
304 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
305 count++;
306 }
307 len--;
308 temp_ptr++;
309 }
310 return (0);
311 }
312
313 static uchar
314 i2c_set_dev_offset (uchar dev_addr, unsigned int offset, int ten_bit,
315 int alen)
316 {
317 uchar status;
318 unsigned int table[2];
319
320 table[1] = (offset ) & 0x0ff; /* low byte */
321 table[0] = (offset >> 8) & 0x0ff; /* high byte */
322
323 DP (puts ("i2c_set_dev_offset\n"));
324
325 status = i2c_select_device (dev_addr, 0, ten_bit);
326 if (status) {
327 #ifdef DEBUG_I2C
328 22 printf ("Failed to select device setting offset: 0x%02x\n",
329 status);
330 #endif
331 return status;
332 }
333 /* check the address offset length */
334 if (alen == 0)
335 /* no address offset */
336 return (0);
337 else if (alen == 1) {
338 /* 1 byte address offset */
339 status = i2c_write_data (&offset, 1);
340 if (status) {
341 #ifdef DEBUG_I2C
342 printf ("Failed to write data: 0x%02x\n", status);
343 #endif
344 return status;
345 }
346 } else if (alen == 2) {
347 /* 2 bytes address offset */
348 status = i2c_write_data (table, 2);
349 if (status) {
350 #ifdef DEBUG_I2C
351 printf ("Failed to write data: 0x%02x\n", status);
352 #endif
353 return status;
354 }
355 } else {
356 /* address offset unknown or not supported */
357 printf ("Address length offset %d is not supported\n", alen);
358 return 1;
359 }
360 return 0; /* sucessful completion */
361 }
362
363 int
364 i2c_read (uchar dev_addr, unsigned int offset, int alen, uchar * data,
365 int len)
366 {
367 uchar status = 0;
368 unsigned int i2cFreq = CONFIG_SYS_I2C_SPEED;
369
370 DP (puts ("i2c_read\n"));
371
372 /* set the i2c frequency */
373 i2c_init (i2cFreq, CONFIG_SYS_I2C_SLAVE);
374
375 status = i2c_set_dev_offset (dev_addr, offset, 0, alen); /* send the slave address + offset */
376 if (status) {
377 #ifdef DEBUG_I2C
378 printf ("Failed to set slave address & offset: 0x%02x\n",
379 status);
380 #endif
381 return status;
382 }
383
384 status = i2c_select_device (dev_addr, 1, 0);
385 if (status) {
386 #ifdef DEBUG_I2C
387 printf ("Failed to select device for data read: 0x%02x\n",
388 status);
389 #endif
390 return status;
391 }
392
393 status = i2c_get_data (data, len);
394 if (status) {
395 #ifdef DEBUG_I2C
396 printf ("Data not read: 0x%02x\n", status);
397 #endif
398 return status;
399 }
400
401 return 0;
402 }
403
404
405 void i2c_stop (void)
406 {
407 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4));
408 asm(" sync");
409 }
410
411
412 int
413 i2c_write (uchar dev_addr, unsigned int offset, int alen, uchar * data,
414 int len)
415 {
416 uchar status = 0;
417 unsigned int i2cFreq = CONFIG_SYS_I2C_SPEED;
418
419 DP (puts ("i2c_write\n"));
420
421 /* set the i2c frequency */
422 i2c_init (i2cFreq, CONFIG_SYS_I2C_SLAVE);
423
424 status = i2c_set_dev_offset (dev_addr, offset, 0, alen); /* send the slave address + offset */
425 if (status) {
426 #ifdef DEBUG_I2C
427 printf ("Failed to set slave address & offset: 0x%02x\n",
428 status);
429 #endif
430 return status;
431 }
432
433
434 status = i2c_write_byte (data, len); /* write the data */
435 if (status) {
436 #ifdef DEBUG_I2C
437 printf ("Data not written: 0x%02x\n", status);
438 #endif
439 return status;
440 }
441 /* issue a stop bit */
442 i2c_stop ();
443 return 0;
444 }
445
446
447 int i2c_probe (uchar chip)
448 {
449
450 #ifdef DEBUG_I2C
451 unsigned int i2c_status;
452 #endif
453 uchar status = 0;
454 unsigned int i2cFreq = CONFIG_SYS_I2C_SPEED;
455
456 DP (puts ("i2c_probe\n"));
457
458 /* set the i2c frequency */
459 i2c_init (i2cFreq, CONFIG_SYS_I2C_SLAVE);
460
461 status = i2c_set_dev_offset (chip, 0, 0, 0); /* send the slave address + no offset */
462 if (status) {
463 #ifdef DEBUG_I2C
464 printf ("Failed to set slave address: 0x%02x\n", status);
465 #endif
466 return (int) status;
467 }
468 #ifdef DEBUG_I2C
469 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &i2c_status);
470 printf ("address %#x returned %#x\n", chip, i2c_status);
471 #endif
472 /* issue a stop bit */
473 i2c_stop ();
474 return 0; /* successful completion */
475 }