1 /* I2cCore.c - MPC8220 PPC I2C Library */
2 
3 /* Copyright 2004      Freescale Semiconductor, Inc. */
4 
5 /*
6 modification history
7 --------------------
8 01c,29jun04,tcl	 1.3	removed CR. Added two bytes offset support.
9 01b,19jan04,tcl	 1.2	removed i2cMsDelay and sysDecGet. renamed i2cMsDelay
10 			back to sysMsDelay
11 01a,19jan04,tcl	 1.1	created and seperated from i2c.c
12 */
13 
14 /*
15 DESCRIPTION
16 This file contain I2C low level handling library functions
17 */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <vxWorks.h>
23 #include <sysLib.h>
24 #include <iosLib.h>
25 #include <logLib.h>
26 #include <tickLib.h>
27 
28 /* BSP Includes */
29 #include "config.h"
30 #include "mpc8220.h"
31 #include "i2cCore.h"
32 
33 #ifdef DEBUG_I2CCORE
34 int I2CCDbg = 0;
35 #endif
36 
37 #define ABS(x)	((x < 0)? -x : x)
38 
39 char *I2CERR[16] = {
40 	"Transfer in Progress\n",	/* 0 */
41 	"Transfer complete\n",
42 	"Not Addressed\n",		/* 2 */
43 	"Addressed as a slave\n",
44 	"Bus is Idle\n",		/* 4 */
45 	"Bus is busy\n",
46 	"Arbitration Lost\n",		/* 6 */
47 	"Arbitration on Track\n",
48 	"Slave receive, master writing to slave\n",	/* 8 */
49 	"Slave transmit, master reading from slave\n",
50 	"Interrupt is pending\n",	/* 10 */
51 	"Interrupt complete\n",
52 	"Acknowledge received\n",	/* 12 */
53 	"No acknowledge received\n",
54 	"Unknown status\n",		/* 14 */
55 	"\n"
56 };
57 
58 /******************************************************************************
59  *
60  * chk_status - Check I2C status bit
61  *
62  * RETURNS: OK, or ERROR if the bit encounter
63  *
64  */
65 
chk_status(PSI2C pi2c,UINT8 sta_bit,UINT8 truefalse)66 STATUS chk_status (PSI2C pi2c, UINT8 sta_bit, UINT8 truefalse)
67 {
68 	int i, status = 0;
69 
70 	for (i = 0; i < I2C_POLL_COUNT; i++) {
71 		if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0))
72 			return (OK);
73 	}
74 
75 	I2CCDBG (L2, ("--- sr %x stabit %x truefalse %d\n",
76 		      pi2c->sr, sta_bit, truefalse, 0, 0, 0));
77 
78 	if (i == I2C_POLL_COUNT) {
79 		switch (sta_bit) {
80 		case I2C_STA_CF:
81 			status = 0;
82 			break;
83 		case I2C_STA_AAS:
84 			status = 2;
85 			break;
86 		case I2C_STA_BB:
87 			status = 4;
88 			break;
89 		case I2C_STA_AL:
90 			status = 6;
91 			break;
92 		case I2C_STA_SRW:
93 			status = 8;
94 			break;
95 		case I2C_STA_IF:
96 			status = 10;
97 			break;
98 		case I2C_STA_RXAK:
99 			status = 12;
100 			break;
101 		default:
102 			status = 14;
103 			break;
104 		}
105 
106 		if (!truefalse)
107 			status++;
108 
109 		I2CCDBG (NO, ("--- status %d\n", status, 0, 0, 0, 0, 0));
110 		I2CCDBG (NO, (I2CERR[status], 0, 0, 0, 0, 0, 0));
111 	}
112 
113 	return (ERROR);
114 }
115 
116 /******************************************************************************
117  *
118  * I2C Enable - Enable the I2C Controller
119  *
120  */
i2c_enable(SI2C * pi2c,PI2CSET pi2cSet)121 STATUS i2c_enable (SI2C * pi2c, PI2CSET pi2cSet)
122 {
123 	int fdr = pi2cSet->bit_rate;
124 	UINT8 adr = pi2cSet->i2c_adr;
125 
126 	I2CCDBG (L2, ("i2c_enable fdr %d adr %x\n", fdr, adr, 0, 0, 0, 0));
127 
128 	i2c_clear (pi2c);	/* Clear FDR, ADR, SR and CR reg */
129 
130 	SetI2cFDR (pi2c, fdr);	/* Frequency			*/
131 	pi2c->adr = adr;
132 
133 	pi2c->cr = I2C_CTL_EN;	/* Set Enable			*/
134 
135 	/*
136 	   The I2C bus should be in Idle state. If the bus is busy,
137 	   clear the STA bit in control register
138 	 */
139 	if (chk_status (pi2c, I2C_STA_BB, 0) != OK) {
140 		if ((pi2c->cr & I2C_CTL_STA) == I2C_CTL_STA)
141 			pi2c->cr &= ~I2C_CTL_STA;
142 
143 		/* Check again if it is still busy, return error if found */
144 		if (chk_status (pi2c, I2C_STA_BB, 1) == OK)
145 			return ERROR;
146 	}
147 
148 	return (OK);
149 }
150 
151 /******************************************************************************
152  *
153  * I2C Disable - Disable the I2C Controller
154  *
155  */
i2c_disable(PSI2C pi2c)156 STATUS i2c_disable (PSI2C pi2c)
157 {
158 	i2c_clear (pi2c);
159 
160 	pi2c->cr &= I2C_CTL_EN; /* Disable I2c			*/
161 
162 	if ((pi2c->cr & I2C_CTL_STA) == I2C_CTL_STA)
163 		pi2c->cr &= ~I2C_CTL_STA;
164 
165 	if (chk_status (pi2c, I2C_STA_BB, 0) != OK)
166 		return ERROR;
167 
168 	return (OK);
169 }
170 
171 /******************************************************************************
172  *
173  * I2C Clear - Clear the I2C Controller
174  *
175  */
i2c_clear(PSI2C pi2c)176 STATUS i2c_clear (PSI2C pi2c)
177 {
178 	pi2c->adr = 0;
179 	pi2c->fdr = 0;
180 	pi2c->cr = 0;
181 	pi2c->sr = 0;
182 
183 	return (OK);
184 }
185 
186 
i2c_start(PSI2C pi2c,PI2CSET pi2cSet)187 STATUS i2c_start (PSI2C pi2c, PI2CSET pi2cSet)
188 {
189 #ifdef TWOBYTES
190 	UINT16 ByteOffset = pi2cSet->str_adr;
191 #else
192 	UINT8 ByteOffset = pi2cSet->str_adr;
193 #endif
194 #if 1
195 	UINT8 tmp = 0;
196 #endif
197 	UINT8 Addr = pi2cSet->slv_adr;
198 
199 	pi2c->cr |= I2C_CTL_STA;	/* Generate start signal	*/
200 
201 	if (chk_status (pi2c, I2C_STA_BB, 1) != OK)
202 		return ERROR;
203 
204 	/* Write slave address */
205 	if (i2c_writebyte (pi2c, &Addr) != OK) {
206 		i2c_stop (pi2c);	/* Disable I2c			*/
207 		return ERROR;
208 	}
209 #ifdef TWOBYTES
210 #   if 0
211 	/* Issue the offset to start */
212 	if (i2c_write2byte (pi2c, &ByteOffset) != OK) {
213 		i2c_stop (pi2c);	/* Disable I2c			*/
214 		return ERROR;
215 	}
216 #endif
217 	tmp = (ByteOffset >> 8) & 0xff;
218 	if (i2c_writebyte (pi2c, &tmp) != OK) {
219 		i2c_stop (pi2c);	/* Disable I2c			*/
220 		return ERROR;
221 	}
222 	tmp = ByteOffset & 0xff;
223 	if (i2c_writebyte (pi2c, &tmp) != OK) {
224 		i2c_stop (pi2c);	/* Disable I2c			*/
225 		return ERROR;
226 	}
227 #else
228 	if (i2c_writebyte (pi2c, &ByteOffset) != OK) {
229 		i2c_stop (pi2c);	/* Disable I2c			*/
230 		return ERROR;
231 	}
232 #endif
233 
234 	return (OK);
235 }
236 
i2c_stop(PSI2C pi2c)237 STATUS i2c_stop (PSI2C pi2c)
238 {
239 	pi2c->cr &= ~I2C_CTL_STA;	/* Generate stop signal		*/
240 	if (chk_status (pi2c, I2C_STA_BB, 0) != OK)
241 		return ERROR;
242 
243 	return (OK);
244 }
245 
246 /******************************************************************************
247  *
248  * Read Len bytes to the location pointed to by *Data from the device
249  * with address Addr.
250  */
i2c_readblock(SI2C * pi2c,PI2CSET pi2cSet,UINT8 * Data)251 int i2c_readblock (SI2C * pi2c, PI2CSET pi2cSet, UINT8 * Data)
252 {
253 	int i = 0;
254 	UINT8 Tmp;
255 
256 /*    UINT8 ByteOffset = pi2cSet->str_adr; not used? */
257 	UINT8 Addr = pi2cSet->slv_adr;
258 	int Length = pi2cSet->xfer_size;
259 
260 	I2CCDBG (L1, ("i2c_readblock addr %x data 0x%08x len %d offset %d\n",
261 		      Addr, (int) Data, Length, ByteOffset, 0, 0));
262 
263 	if (pi2c->sr & I2C_STA_AL) {	/* Check if Arbitration lost	*/
264 		I2CCDBG (FN, ("Arbitration lost\n", 0, 0, 0, 0, 0, 0));
265 		pi2c->sr &= ~I2C_STA_AL;	/* Clear Arbitration status bit */
266 		return ERROR;
267 	}
268 
269 	pi2c->cr |= I2C_CTL_TX; /* Enable the I2c for TX, Ack	*/
270 
271 	if (i2c_start (pi2c, pi2cSet) == ERROR)
272 		return ERROR;
273 
274 	pi2c->cr |= I2C_CTL_RSTA;	/* Repeat Start */
275 
276 	Tmp = Addr | 1;
277 
278 	if (i2c_writebyte (pi2c, &Tmp) != OK) {
279 		i2c_stop (pi2c);	/* Disable I2c	*/
280 		return ERROR;
281 	}
282 
283 	if (((pi2c->sr & 0x07) == 0x07) || (pi2c->sr & 0x01))
284 		return ERROR;
285 
286 	pi2c->cr &= ~I2C_CTL_TX;	/* Set receive mode	*/
287 
288 	if (((pi2c->sr & 0x07) == 0x07) || (pi2c->sr & 0x01))
289 		return ERROR;
290 
291 	/* Dummy Read */
292 	if (i2c_readbyte (pi2c, &Tmp, &i) != OK) {
293 		i2c_stop (pi2c);	/* Disable I2c	*/
294 		return ERROR;
295 	}
296 
297 	i = 0;
298 	while (Length) {
299 		if (Length == 2)
300 			pi2c->cr |= I2C_CTL_TXAK;
301 
302 		if (Length == 1)
303 			pi2c->cr &= ~I2C_CTL_STA;
304 
305 		if (i2c_readbyte (pi2c, Data, &Length) != OK) {
306 			return i2c_stop (pi2c);
307 		}
308 		i++;
309 		Length--;
310 		Data++;
311 	}
312 
313 	if (i2c_stop (pi2c) == ERROR)
314 		return ERROR;
315 
316 	return i;
317 }
318 
i2c_writeblock(SI2C * pi2c,PI2CSET pi2cSet,UINT8 * Data)319 STATUS i2c_writeblock (SI2C * pi2c, PI2CSET pi2cSet, UINT8 * Data)
320 {
321 	int Length = pi2cSet->xfer_size;
322 
323 #ifdef TWOBYTES
324 	UINT16 ByteOffset = pi2cSet->str_adr;
325 #else
326 	UINT8 ByteOffset = pi2cSet->str_adr;
327 #endif
328 	int j, k;
329 
330 	I2CCDBG (L2, ("i2c_writeblock\n", 0, 0, 0, 0, 0, 0));
331 
332 	if (pi2c->sr & I2C_STA_AL) {
333 		/* Check if arbitration lost */
334 		I2CCDBG (L2, ("Arbitration lost\n", 0, 0, 0, 0, 0, 0));
335 		pi2c->sr &= ~I2C_STA_AL;	/* Clear the condition	*/
336 		return ERROR;
337 	}
338 
339 	pi2c->cr |= I2C_CTL_TX; /* Enable the I2c for TX, Ack	*/
340 
341 	/* Do the not even offset first */
342 	if ((ByteOffset % 8) != 0) {
343 		int remain;
344 
345 		if (Length > 8) {
346 			remain = 8 - (ByteOffset % 8);
347 			Length -= remain;
348 
349 			pi2cSet->str_adr = ByteOffset;
350 
351 			if (i2c_start (pi2c, pi2cSet) == ERROR)
352 				return ERROR;
353 
354 			for (j = ByteOffset; j < remain; j++) {
355 				if (i2c_writebyte (pi2c, Data++) != OK)
356 					return ERROR;
357 			}
358 
359 			if (i2c_stop (pi2c) == ERROR)
360 				return ERROR;
361 
362 			sysMsDelay (32);
363 
364 			/* Update the new ByteOffset */
365 			ByteOffset += remain;
366 		}
367 	}
368 
369 	for (j = ByteOffset, k = 0; j < (Length + ByteOffset); j++) {
370 		if ((j % 8) == 0) {
371 			pi2cSet->str_adr = j;
372 			if (i2c_start (pi2c, pi2cSet) == ERROR)
373 				return ERROR;
374 		}
375 
376 		k++;
377 
378 		if (i2c_writebyte (pi2c, Data++) != OK)
379 			return ERROR;
380 
381 		if ((j == (Length - 1)) || ((k % 8) == 0)) {
382 			if (i2c_stop (pi2c) == ERROR)
383 				return ERROR;
384 
385 			sysMsDelay (50);
386 		}
387 
388 	}
389 
390 	return k;
391 }
392 
i2c_readbyte(SI2C * pi2c,UINT8 * readb,int * index)393 STATUS i2c_readbyte (SI2C * pi2c, UINT8 * readb, int *index)
394 {
395 	pi2c->sr &= ~I2C_STA_IF;	/* Clear Interrupt Bit	*/
396 	*readb = pi2c->dr;		/* Read a byte		*/
397 
398 	/*
399 	   Set I2C_CTRL_TXAK will cause Transfer pending and
400 	   set I2C_CTRL_STA will cause Interrupt pending
401 	 */
402 	if (*index != 2) {
403 		if (chk_status (pi2c, I2C_STA_CF, 1) != OK)	/* Transfer not complete?	*/
404 			return ERROR;
405 	}
406 
407 	if (*index != 1) {
408 		if (chk_status (pi2c, I2C_STA_IF, 1) != OK)
409 			return ERROR;
410 	}
411 
412 	return (OK);
413 }
414 
415 
i2c_writebyte(SI2C * pi2c,UINT8 * writeb)416 STATUS i2c_writebyte (SI2C * pi2c, UINT8 * writeb)
417 {
418 	pi2c->sr &= ~I2C_STA_IF;	/* Clear Interrupt	*/
419 	pi2c->dr = *writeb;		/* Write a byte		*/
420 
421 	if (chk_status (pi2c, I2C_STA_CF, 1) != OK)	/* Transfer not complete?	*/
422 		return ERROR;
423 
424 	if (chk_status (pi2c, I2C_STA_IF, 1) != OK)
425 		return ERROR;
426 
427 	return OK;
428 }
429 
i2c_write2byte(SI2C * pi2c,UINT16 * writeb)430 STATUS i2c_write2byte (SI2C * pi2c, UINT16 * writeb)
431 {
432 	UINT8 data;
433 
434 	data = (UINT8) ((*writeb >> 8) & 0xff);
435 	if (i2c_writebyte (pi2c, &data) != OK)
436 		return ERROR;
437 	data = (UINT8) (*writeb & 0xff);
438 	if (i2c_writebyte (pi2c, &data) != OK)
439 		return ERROR;
440 	return OK;
441 }
442 
443 /* FDR table base on 33MHz - more detail please refer to Odini2c_dividers.xls
444 FDR FDR scl sda scl2tap2
445 510 432 tap tap tap tap scl_per	    sda_hold	I2C Freq    0	1   2	3   4	5
446 000 000 9   3	4   1	28 Clocks   9 Clocks	1190 KHz    0	0   0	0   0	0
447 000 001 9   3	4   2	44 Clocks   11 Clocks	758 KHz	    0	0   1	0   0	0
448 000 010 9   3	6   4	80 Clocks   17 Clocks	417 KHz	    0	0   0	1   0	0
449 000 011 9   3	6   8	144 Clocks  25 Clocks	231 KHz	    0	0   1	1   0	0
450 000 100 9   3	14  16	288 Clocks  49 Clocks	116 KHz	    0	0   0	0   1	0
451 000 101 9   3	30  32	576 Clocks  97 Clocks	58 KHz	    0	0   1	0   1	0
452 000 110 9   3	62  64	1152 Clocks 193 Clocks	29 KHz	    0	0   0	1   1	0
453 000 111 9   3	126 128 2304 Clocks 385 Clocks	14 KHz	    0	0   1	1   1	0
454 001 000 10  3	4   1	30 Clocks   9 Clocks	1111 KHz1   0	0   0	0   0
455 001 001 10  3	4   2	48 Clocks   11 Clocks	694 KHz	    1	0   1	0   0	0
456 001 010 10  3	6   4	88 Clocks   17 Clocks	379 KHz	    1	0   0	1   0	0
457 001 011 10  3	6   8	160 Clocks  25 Clocks	208 KHz	    1	0   1	1   0	0
458 001 100 10  3	14  16	320 Clocks  49 Clocks	104 KHz	    1	0   0	0   1	0
459 001 101 10  3	30  32	640 Clocks  97 Clocks	52 KHz	    1	0   1	0   1	0
460 001 110 10  3	62  64	1280 Clocks 193 Clocks	26 KHz	    1	0   0	1   1	0
461 001 111 10  3	126 128 2560 Clocks 385 Clocks	13 KHz	    1	0   1	1   1	0
462 010 000 12  4	4   1	34 Clocks   10 Clocks	980 KHz	    0	1   0	0   0	0
463 010 001 12  4	4   2	56 Clocks   13 Clocks	595 KHz	    0	1   1	0   0	0
464 010 010 12  4	6   4	104 Clocks  21 Clocks	321 KHz	    0	1   0	1   0	0
465 010 011 12  4	6   8	192 Clocks  33 Clocks	174 KHz	    0	1   1	1   0	0
466 010 100 12  4	14  16	384 Clocks  65 Clocks	87 KHz	    0	1   0	0   1	0
467 010 101 12  4	30  32	768 Clocks  129 Clocks	43 KHz	    0	1   1	0   1	0
468 010 110 12  4	62  64	1536 Clocks 257 Clocks	22 KHz	    0	1   0	1   1	0
469 010 111 12  4	126 128 3072 Clocks 513 Clocks	11 KHz	    0	1   1	1   1	0
470 011 000 15  4	4   1	40 Clocks   10 Clocks	833 KHz	    1	1   0	0   0	0
471 011 001 15  4	4   2	68 Clocks   13 Clocks	490 KHz	    1	1   1	0   0	0
472 011 010 15  4	6   4	128 Clocks  21 Clocks	260 KHz	    1	1   0	1   0	0
473 011 011 15  4	6   8	240 Clocks  33 Clocks	139 KHz	    1	1   1	1   0	0
474 011 100 15  4	14  16	480 Clocks  65 Clocks	69 KHz	    1	1   0	0   1	0
475 011 101 15  4	30  32	960 Clocks  129 Clocks	35 KHz	    1	1   1	0   1	0
476 011 110 15  4	62  64	1920 Clocks 257 Clocks	17 KHz	    1	1   0	1   1	0
477 011 111 15  4	126 128 3840 Clocks 513 Clocks	9 KHz	    1	1   1	1   1	0
478 100 000 5   1	4   1	20 Clocks   7 Clocks	1667 KHz    0	0   0	0   0	1
479 100 001 5   1	4   2	28 Clocks   7 Clocks	1190 KHz    0	0   1	0   0	1
480 100 010 5   1	6   4	48 Clocks   9 Clocks	694 KHz	    0	0   0	1   0	1
481 100 011 5   1	6   8	80 Clocks   9 Clocks	417 KHz	    0	0   1	1   0	1
482 100 100 5   1	14  16	160 Clocks  17 Clocks	208 KHz	    0	0   0	0   1	1
483 100 101 5   1	30  32	320 Clocks  33 Clocks	104 KHz	    0	0   1	0   1	1
484 100 110 5   1	62  64	640 Clocks  65 Clocks	52 KHz	    0	0   0	1   1	1
485 100 111 5   1	126 128 1280 Clocks 129 Clocks	26 KHz	    0	0   1	1   1	1
486 101 000 6   1	4   1	22 Clocks   7 Clocks	1515 KHz    1	0   0	0   0	1
487 101 001 6   1	4   2	32 Clocks   7 Clocks	1042 KHz    1	0   1	0   0	1
488 101 010 6   1	6   4	56 Clocks   9 Clocks	595 KHz	    1	0   0	1   0	1
489 101 011 6   1	6   8	96 Clocks   9 Clocks	347 KHz	    1	0   1	1   0	1
490 101 100 6   1	14  16	192 Clocks  17 Clocks	174 KHz	    1	0   0	0   1	1
491 101 101 6   1	30  32	384 Clocks  33 Clocks	87 KHz	    1	0   1	0   1	1
492 101 110 6   1	62  64	768 Clocks  65 Clocks	43 KHz	    1	0   0	1   1	1
493 101 111 6   1	126 128 1536 Clocks 129 Clocks	22 KHz	    1	0   1	1   1	1
494 110 000 7   2	4   1	24 Clocks   8 Clocks	1389 KHz    0	1   0	0   0	1
495 110 001 7   2	4   2	36 Clocks   9 Clocks	926 KHz	    0	1   1	0   0	1
496 110 010 7   2	6   4	64 Clocks   13 Clocks	521 KHz	    0	1   0	1   0	1
497 110 011 7   2	6   8	112 Clocks  17 Clocks	298 KHz	    0	1   1	1   0	1
498 110 100 7   2	14  16	224 Clocks  33 Clocks	149 KHz	    0	1   0	0   1	1
499 110 101 7   2	30  32	448 Clocks  65 Clocks	74 KHz	    0	1   1	0   1	1
500 110 110 7   2	62  64	896 Clocks  129 Clocks	37 KHz	    0	1   0	1   1	1
501 110 111 7   2	126 128 1792 Clocks 257 Clocks	19 KHz	    0	1   1	1   1	1
502 111 000 8   2	4   1	26 Clocks   8 Clocks	1282 KHz    1	1   0	0   0	1
503 111 001 8   2	4   2	40 Clocks   9 Clocks	833 KHz	    1	1   1	0   0	1
504 111 010 8   2	6   4	72 Clocks   13 Clocks	463 KHz	    1	1   0	1   0	1
505 111 011 8   2	6   8	128 Clocks  17 Clocks	260 KHz	    1	1   1	1   0	1
506 111 100 8   2	14  16	256 Clocks  33 Clocks	130 KHz	    1	1   0	0   1	1
507 111 101 8   2	30  32	512 Clocks  65 Clocks	65 KHz	    1	1   1	0   1	1
508 111 110 8   2	62  64	1024 Clocks 129 Clocks	33 KHz	    1	1   0	1   1	1
509 111 111 8   2	126 128 2048 Clocks 257 Clocks	16 KHz	    1	1   1	1   1	1
510 */
SetI2cFDR(PSI2C pi2cRegs,int bitrate)511 STATUS SetI2cFDR (PSI2C pi2cRegs, int bitrate)
512 {
513 /* Constants */
514 	const UINT8 div_hold[8][3] = { {9, 3}, {10, 3},
515 	{12, 4}, {15, 4},
516 	{5, 1}, {6, 1},
517 	{7, 2}, {8, 2}
518 	};
519 
520 	const UINT8 scl_tap[8][2] = { {4, 1}, {4, 2},
521 	{6, 4}, {6, 8},
522 	{14, 16}, {30, 32},
523 	{62, 64}, {126, 128}
524 	};
525 
526 	UINT8 mfdr_bits;
527 
528 	int i = 0;
529 	int j = 0;
530 
531 	int Diff, min;
532 	int WhichFreq, iRec, jRec;
533 	int SCL_Period;
534 	int SCL_Hold;
535 	int I2C_Freq;
536 
537 	I2CCDBG (L2, ("Entering getBitRate: bitrate %d pi2cRegs 0x%08x\n",
538 		      bitrate, (int) pi2cRegs, 0, 0, 0, 0));
539 
540 	if (bitrate < 0) {
541 		I2CCDBG (NO, ("Invalid bitrate\n", 0, 0, 0, 0, 0, 0));
542 		return ERROR;
543 	}
544 
545 	/* Initialize */
546 	mfdr_bits = 0;
547 	min = 0x7fffffff;
548 	WhichFreq = iRec = jRec = 0;
549 
550 	for (i = 0; i < 8; i++) {
551 		for (j = 0; j < 8; j++) {
552 			/* SCL Period = 2 * (scl2tap + [(SCL_Tap - 1) * tap2tap] + 2)
553 			 * SCL Hold   = scl2tap + ((SDA_Tap - 1) * tap2tap) + 3
554 			 * Bit Rate (I2C Freq) = System Freq / SCL Period
555 			 */
556 			SCL_Period =
557 				2 * (scl_tap[i][0] +
558 				     ((div_hold[j][0] - 1) * scl_tap[i][1]) +
559 				     2);
560 
561 			/* Now get the I2C Freq */
562 			I2C_Freq = DEV_CLOCK_FREQ / SCL_Period;
563 
564 			/* Take equal or slower */
565 			if (I2C_Freq > bitrate)
566 				continue;
567 
568 			/* Take the differences */
569 			Diff = I2C_Freq - bitrate;
570 
571 			Diff = ABS (Diff);
572 
573 			/* Find the closer value */
574 			if (Diff < min) {
575 				min = Diff;
576 				WhichFreq = I2C_Freq;
577 				iRec = i;
578 				jRec = j;
579 			}
580 
581 			I2CCDBG (L2,
582 				 ("--- (%d,%d) I2C_Freq %d minDiff %d min %d\n",
583 				  i, j, I2C_Freq, Diff, min, 0));
584 		}
585 	}
586 
587 	SCL_Period =
588 		2 * (scl_tap[iRec][0] +
589 		     ((div_hold[jRec][0] - 1) * scl_tap[iRec][1]) + 2);
590 
591 	I2CCDBG (L2, ("\nmin %d WhichFreq %d iRec %d jRec %d\n",
592 		      min, WhichFreq, iRec, jRec, 0, 0));
593 	I2CCDBG (L2, ("--- scl2tap %d SCL_Tap %d tap2tap %d\n",
594 		      scl_tap[iRec][0], div_hold[jRec][0], scl_tap[iRec][1],
595 		      0, 0, 0));
596 
597 	/* This may no require */
598 	SCL_Hold =
599 		scl_tap[iRec][0] +
600 		((div_hold[jRec][1] - 1) * scl_tap[iRec][1]) + 3;
601 	I2CCDBG (L2,
602 		 ("--- SCL_Period %d SCL_Hold %d\n", SCL_Period, SCL_Hold, 0,
603 		  0, 0, 0));
604 
605 	I2CCDBG (L2, ("--- mfdr_bits %x\n", mfdr_bits, 0, 0, 0, 0, 0));
606 
607 	/* FDR 4,3,2 */
608 	if ((iRec & 1) == 1)
609 		mfdr_bits |= 0x04;	/* FDR 2 */
610 	if ((iRec & 2) == 2)
611 		mfdr_bits |= 0x08;	/* FDR 3 */
612 	if ((iRec & 4) == 4)
613 		mfdr_bits |= 0x10;	/* FDR 4 */
614 	/* FDR 5,1,0 */
615 	if ((jRec & 1) == 1)
616 		mfdr_bits |= 0x01;	/* FDR 0 */
617 	if ((jRec & 2) == 2)
618 		mfdr_bits |= 0x02;	/* FDR 1 */
619 	if ((jRec & 4) == 4)
620 		mfdr_bits |= 0x20;	/* FDR 5 */
621 
622 	I2CCDBG (L2, ("--- mfdr_bits %x\n", mfdr_bits, 0, 0, 0, 0, 0));
623 
624 	pi2cRegs->fdr = mfdr_bits;
625 
626 	return OK;
627 }
628