make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / drivers / i2c / xilinx_iic / xiic_master.c
1 /* $Id: xiic_master.c,v 1.1.1.1 2005/04/11 02:50:21 jack Exp $ */
2 /******************************************************************************
3 *
4 *     Author: Xilinx, Inc.
5 *     
6 *     
7 *     This program is free software; you can redistribute it and/or modify it
8 *     under the terms of the GNU General Public License as published by the
9 *     Free Software Foundation; either version 2 of the License, or (at your
10 *     option) any later version.
11 *     
12 *     
13 *     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
14 *     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
15 *     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
16 *     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
17 *     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR
18 *     OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
19 *     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
20 *     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
21 *     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
22 *     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
23 *     FITNESS FOR A PARTICULAR PURPOSE.
24 *     
25 *     
26 *     Xilinx products are not intended for use in life support appliances,
27 *     devices, or systems. Use in such applications is expressly prohibited.
28 *     
29 *     
30 *     (c) Copyright 2002 Xilinx Inc.
31 *     All rights reserved.
32 *     
33 *     
34 *     You should have received a copy of the GNU General Public License along
35 *     with this program; if not, write to the Free Software Foundation, Inc.,
36 *     675 Mass Ave, Cambridge, MA 02139, USA.
37 *
38 ******************************************************************************/
39 /*****************************************************************************/
40 /**
41 *
42 * @file xiic_master.c
43 *
44 * Contains master functions for the XIic component. This file is necessary to
45 * send or receive as a master on the IIC bus.
46 *
47 * <pre>
48 * MODIFICATION HISTORY:
49 *
50 * Ver   Who  Date     Changes
51 * ----- --- ------- -----------------------------------------------
52 * 1.01b jhl 3/27/02 Reparitioned the driver
53 * </pre>
54 *
55 ****************************************************************************/
56
57 /***************************** Include Files *******************************/
58
59 #include "xiic.h"
60 #include "xiic_i.h"
61 #include "xio.h"
62
63 /************************** Constant Definitions ***************************/
64
65 /**************************** Type Definitions *****************************/
66
67 /***************** Macros (Inline Functions) Definitions *******************/
68
69 /*****************************************************************************
70 *
71 * This macro includes master code such that master operations, sending
72 * and receiving data, may be used.  This function hooks the master processing
73 * to the driver such that events are handled properly and allows master
74 * processing to be optional.  It must be called before any functions which
75 * are contained in this file are called, such as after the driver is
76 * initialized.
77 *
78 * @note
79 *
80 * None
81 *
82 ******************************************************************************/
83 #define XIIC_MASTER_INCLUDE                                             \
84 {                                                                       \
85     XIic_RecvMasterFuncPtr = RecvMasterData;                            \
86     XIic_SendMasterFuncPtr = SendMasterData;                            \
87 }
88
89 /************************** Function Prototypes ****************************/
90
91 static void SendSlaveAddr(XIic * InstancePtr);
92 static void RecvMasterData(XIic * InstancePtr);
93 static void SendMasterData(XIic * InstancePtr);
94 static u32 IsBusBusy(XIic * InstancePtr);
95
96 /************************** Variable Definitions **************************/
97
98 /****************************************************************************/
99 /**
100 * This function sends data as a master on the IIC bus. If the bus is busy, it
101 * will indicate so and then enable an interrupt such that the status handler
102 * will be called when the bus is no longer busy.  The slave address which has
103 * been set with the XIic_SetAddress() function is the address to which the
104 * specific data is sent.  Sending data on the bus performs a write operation.
105 *
106 * @param    InstancePtr points to the Iic instance to be worked on.
107 * @param    TxMsgPtr points to the data to be transmitted
108 * @param    ByteCount is the number of message bytes to be sent
109 *
110 * @return
111 *
112 * - XST_SUCCESS indicates the message transmission has been initiated.
113 * - XST_IIC_BUS_BUSY indicates the bus was in use and that the BusNotBusy
114 *   interrupt is enabled which will update the EventStatus when the bus is no
115 *   longer busy.
116 *
117 * @note
118 *
119 * None
120 *
121 ******************************************************************************/
122 XStatus
123 XIic_MasterSend(XIic * InstancePtr, u8 * TxMsgPtr, int ByteCount)
124 {
125         u8 CntlReg;
126
127         XIic_mEnterCriticalRegion(InstancePtr->BaseAddress);
128
129         /* Ensure that the master processing has been included such that events
130          * will be properly handled
131          */
132         XIIC_MASTER_INCLUDE;
133
134         /*
135          * If the busy is busy, then exit the critical region and wait for the
136          * bus to not be busy, the function enables the bus not busy interrupt
137          */
138         if (IsBusBusy(InstancePtr)) {
139                 XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
140
141                 return XST_IIC_BUS_BUSY;
142         }
143
144         /* If it is already a master on the bus (repeated start), the direction was
145          * set to tx which is throttling bus.  The control register needs to be set
146          * before putting data into the FIFO
147          */
148         CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
149
150         if (CntlReg & XIIC_CR_MSMS_MASK) {
151                 CntlReg &= ~XIIC_CR_NO_ACK_MASK;
152                 CntlReg |=
153                     (XIIC_CR_DIR_IS_TX_MASK | XIIC_CR_REPEATED_START_MASK);
154
155                 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
156                          CntlReg);
157                 InstancePtr->Stats.RepeatedStarts++;
158         }
159
160         /* Save message state
161          */
162         InstancePtr->SendByteCount = ByteCount;
163         InstancePtr->SendBufferPtr = TxMsgPtr;
164
165         /* Put the address into the FIFO to be sent and indicate that the operation
166          * to be performed on the bus is a write operation, a general call address
167          * handled the same as a 7 bit address even if 10 bit address is selected
168          * Set the transmit address state to indicate the address has been sent
169          */
170         if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) &&
171             (InstancePtr->AddrOfSlave != 0)) {
172                 XIic_mSend10BitAddrByte1(InstancePtr->AddrOfSlave,
173                                          XIIC_WRITE_OPERATION);
174                 XIic_mSend10BitAddrByte2(InstancePtr->AddrOfSlave);
175         } else {
176                 XIic_mSend7BitAddr(InstancePtr->AddrOfSlave,
177                                    XIIC_WRITE_OPERATION);
178         }
179         /* Set the transmit address state to indicate the address has been sent
180          * for communication with event driven processing
181          */
182         InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
183
184         /* Fill remaining available FIFO with message data
185          */
186         if (InstancePtr->SendByteCount > 1) {
187                 XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
188         }
189
190         /* After filling fifo, if data yet to send > 1, enable Tx ½ empty interrupt
191          */
192         if (InstancePtr->SendByteCount > 1) {
193                 XIic_mClearEnableIntr(InstancePtr->BaseAddress,
194                                       XIIC_INTR_TX_HALF_MASK);
195         }
196
197         /* Clear any pending Tx empty, Tx Error and then enable them.
198          */
199         XIic_mClearEnableIntr(InstancePtr->BaseAddress,
200                               XIIC_INTR_TX_ERROR_MASK |
201                               XIIC_INTR_TX_EMPTY_MASK);
202
203         /* When repeated start not used, MSMS must be set after putting data into
204          * transmit FIFO, start the transmitter
205          */
206
207         if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
208                 CntlReg &= ~XIIC_CR_NO_ACK_MASK;
209                 CntlReg |= XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK;
210                 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
211                          CntlReg);
212         }
213
214         XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
215
216         return XST_SUCCESS;
217 }
218
219 /*****************************************************************************/
220 /**
221 * This function receives data as a master from a slave device on the IIC bus.
222 * If the bus is busy, it will indicate so and then enable an interrupt such
223 * that the status handler will be called when the bus is no longer busy.  The
224 * slave address which has been set with the XIic_SetAddress() function is the
225 * address from which data is received. Receiving data on the bus performs a
226 * read operation.
227 *
228 * @param    InstancePtr is a pointer to the Iic instance to be worked on.
229 * @param    RxMsgPtr is a pointer to the data to be transmitted
230 * @param    ByteCount is the number of message bytes to be sent
231 *
232 * @return
233 *
234 * - XST_SUCCESS indicates the message reception processes has been initiated.
235 * - XST_IIC_BUS_BUSY indicates the bus was in use and that the BusNotBusy
236 *   interrupt is enabled which will update the EventStatus when the bus is no
237 *   longer busy.
238 * - XST_IIC_GENERAL_CALL_ADDRESS indicates the slave address is set to the
239 *   the general call address. This is not allowed for Master receive mode.
240 *
241 * @internal
242 *
243 * The receive FIFO threshold is a zero based count such that 1 must be
244 * subtracted from the desired count to get the correct value. When receiving
245 * data it is also necessary to not receive the last byte with the prior bytes
246 * because the acknowledge must be setup before the last byte is received.
247 *
248 ******************************************************************************/
249 XStatus
250 XIic_MasterRecv(XIic * InstancePtr, u8 * RxMsgPtr, int ByteCount)
251 {
252         u8 CntlReg;
253         u8 Temp;
254
255         /* If the slave address is zero (general call) the master can't perform
256          * receive operations, indicate an error
257          */
258         if (InstancePtr->AddrOfSlave == 0) {
259                 return XST_IIC_GENERAL_CALL_ADDRESS;
260         }
261
262         XIic_mEnterCriticalRegion(InstancePtr->BaseAddress);
263
264         /* Ensure that the master processing has been included such that events
265          * will be properly handled
266          */
267         XIIC_MASTER_INCLUDE;
268         /*
269          * If the busy is busy, then exit the critical region and wait for the
270          * bus to not be busy, the function enables the bus not busy interrupt
271          */
272         if (IsBusBusy(InstancePtr)) {
273                 XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
274
275                 return XST_IIC_BUS_BUSY;
276         }
277
278         /* Save message state for event driven processing
279          */
280         InstancePtr->RecvByteCount = ByteCount;
281         InstancePtr->RecvBufferPtr = RxMsgPtr;
282
283         /* Clear and enable Rx full interrupt if using 7 bit, If 10 bit, wait until
284          * last address byte sent incase arbitration gets lost while sending out
285          * address.
286          */
287         if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) == 0) {
288                 XIic_mClearEnableIntr(InstancePtr->BaseAddress,
289                                       XIIC_INTR_RX_FULL_MASK);
290         }
291
292         /* If already a master on the bus, the direction was set by Rx Interrupt
293          * routine to tx which is throttling bus because during Rxing, Tx reg is
294          * empty = throttle. CR needs setting before putting data or the address
295          * written will go out as Tx instead of receive. Start Master Rx by setting
296          * CR Bits MSMS to Master and msg direction.
297          */
298         CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
299
300         if (CntlReg & XIIC_CR_MSMS_MASK) {
301                 CntlReg |= XIIC_CR_REPEATED_START_MASK;
302                 XIic_mSetControlRegister(InstancePtr, CntlReg, ByteCount);
303
304                 InstancePtr->Stats.RepeatedStarts++;    /* increment stats counts */
305                 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
306                          CntlReg);
307         }
308
309         /* Set receive FIFO occupancy depth which must be done prior to writing the
310          * address in the FIFO because the transmitter will immediatedly start when
311          * in repeated start mode followed by the receiver such that the number of
312          * bytes to receive should be set 1st.
313          */
314         if (ByteCount == 1) {
315                 Temp = 0;
316         } else {
317                 if (ByteCount < IIC_RX_FIFO_DEPTH) {
318                         Temp = ByteCount - 2;
319                 } else {
320                         Temp = IIC_RX_FIFO_DEPTH - 1;
321                 }
322         }
323         XIo_Out8(InstancePtr->BaseAddress + XIIC_RFD_REG_OFFSET, Temp);
324
325         if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) {
326                 /* Send the 1st and 2nd byte of the 10 bit address of a write
327                  * operation, write because it's a 10 bit address
328                  */
329                 XIic_mSend10BitAddrByte1(InstancePtr->AddrOfSlave,
330                                          XIIC_WRITE_OPERATION);
331                 XIic_mSend10BitAddrByte2(InstancePtr->AddrOfSlave);
332
333                 /* Set flag to indicate the next byte of the address needs to be
334                  * send, clear and enable tx empty interrupt
335                  */
336                 InstancePtr->TxAddrMode = XIIC_TX_ADDR_MSTR_RECV_MASK;
337                 XIic_mClearEnableIntr(InstancePtr->BaseAddress,
338                                       XIIC_INTR_TX_EMPTY_MASK);
339         } else {
340                 /* 7 bit slave address, send the address for a read operation
341                  * and set the state to indicate the address has been sent
342                  */
343                 XIic_mSend7BitAddr(InstancePtr->AddrOfSlave,
344                                    XIIC_READ_OPERATION);
345                 InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
346         }
347
348         /* Tx error is enabled incase the address (7 or 10) has no device to answer
349          * with Ack. When only one byte of data, must set NO ACK before address goes
350          * out therefore Tx error must not be enabled as it will go off immediately
351          * and the Rx full interrupt will be checked.  If full, then the one byte
352          * was received and the Tx error will be disabled without sending an error
353          * callback msg.
354          */
355         XIic_mClearEnableIntr(InstancePtr->BaseAddress,
356                               XIIC_INTR_TX_ERROR_MASK);
357
358         /*  When repeated start not used, MSMS gets set after putting data
359          *  in Tx reg. Start Master Rx by setting CR Bits MSMS to Master and
360          *  msg direction.
361          */
362         if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
363                 CntlReg |= XIIC_CR_MSMS_MASK;
364                 XIic_mSetControlRegister(InstancePtr, CntlReg, ByteCount);
365                 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
366                          CntlReg);
367         }
368
369         XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
370
371         return XST_SUCCESS;
372 }
373
374 /*****************************************************************************
375 *
376 * This function checks to see if the IIC bus is busy.  If so, it will enable
377 * the bus not busy interrupt such that the driver is notified when the bus
378 * is no longer busy.
379 *
380 * @param    InstancePtr points to the Iic instance to be worked on.
381 *
382 * @return
383 *
384 * - FALSE indicates the IIC bus is not busy.
385 * - TRUE indicates the bus was in use and that the BusNotBusy
386 *   interrupt is enabled which will update the EventStatus when the bus is no
387 *   longer busy.
388 *
389 * @note
390 *
391 * None
392 *
393 ******************************************************************************/
394 static u32
395 IsBusBusy(XIic * InstancePtr)
396 {
397         u8 ControlReg;
398         u8 StatusReg;
399
400         ControlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
401         StatusReg = XIo_In8(InstancePtr->BaseAddress + XIIC_SR_REG_OFFSET);
402
403         /* If this device is already master of the bus as when using the repeated
404          * start and the bus is busy setup to wait for it to not be busy
405          */
406         if (((ControlReg & XIIC_CR_MSMS_MASK) == 0) &&  /* not master */
407             (StatusReg & XIIC_SR_BUS_BUSY_MASK)) {      /* is busy    */
408 #if 0
409 /*
410  * This code has been temporarily removed because the interrupt is enabled
411  * but never disabled.  Ultimately, this will be fixed by Xilinx, but removing
412  * this for now at least prevents continuous bus idle interrupts.  SAA
413  */
414                 /* The bus is busy, clear pending BNB interrupt incase previously set
415                  * and then enable BusNotBusy interrupt
416                  */
417                 XIic_mClearEnableIntr(InstancePtr->BaseAddress,
418                                       XIIC_INTR_BNB_MASK);
419                 InstancePtr->Stats.BusBusy++;
420 #endif
421
422                 return TRUE;
423         }
424         return FALSE;
425 }
426
427 /******************************************************************************
428 *
429 * This function sends the proper byte of the address as well as generate the
430 * proper address bit fields depending on the address byte required and the
431 * direction of the data (write or read).
432 *
433 * A master receiving has the restriction that the direction must be switched
434 * from write to read when the third address byte is transmitted.
435 * For the last byte of the 10 bit address, repeated start must be set prior
436 * to writing the address. If repeated start options is enabled, the
437 * control register is written before the address is written to the tx reg.
438 *
439 * @param    InstancePtr is a pointer to the XIic instance to be worked on.
440 *
441 * @return
442 *
443 * None.
444 *
445 * @note
446 *
447 * This function does read/modify/write to the device control register. Calling
448 * functions must ensure critical sections are used.
449 *
450 ******************************************************************************/
451 static void
452 SendSlaveAddr(XIic * InstancePtr)
453 {
454         u8 CRreg;
455
456         /* Set the control register for Master Receive, repeated start must be set
457          * before writing the address, MSMS should be already set, don't set here
458          * so if arbitration is lost or some other reason we don't want MSMS set
459          * incase of error
460          */
461         CRreg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
462
463         CRreg |= XIIC_CR_REPEATED_START_MASK;
464         CRreg &= ~XIIC_CR_DIR_IS_TX_MASK;
465
466         XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET, CRreg);
467
468         /* Send the 1st byte of the 10 bit address as a read operation, enable the
469          * receive interrupt to know when data is received, assuming that the
470          * receive FIFO threshold has been previously set
471          */
472         XIic_mSend10BitAddrByte1(InstancePtr->AddrOfSlave, XIIC_READ_OPERATION);
473
474         XIic_mClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_RX_FULL_MASK);
475 }
476
477 /******************************************************************************
478 *
479 * When the IIC Tx FIFO/register goes empty, this routine is called by the
480 * interrupt service routine to fill the transmit FIFO with data to be sent.
481 *
482 * This function also is called by the Tx ½ empty interrupt as the data handling
483 * is identical when you don't assume the FIFO is empty but use the Tx_FIFO_OCY
484 * register to indicate the available free FIFO bytes.
485 *
486 * @param    InstancePtr is a pointer to the XIic instance to be worked on.
487 *
488 * @return
489 *
490 * None.
491 *
492 * @note
493 *
494 * None.
495 *
496 ******************************************************************************/
497 static void
498 SendMasterData(XIic * InstancePtr)
499 {
500         u8 CntlReg;
501         u32 MessageDone = FALSE;
502
503         CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
504
505         /* The device is a master on the bus.  If there is still more address bytes
506          * to send when in master receive operation and the slave device is 10 bit
507          * addressed. This requires the lower 7 bits of address to be resent when
508          * the mode switches to Read instead of write (while sending addresses).
509          */
510         if (InstancePtr->TxAddrMode & XIIC_TX_ADDR_MSTR_RECV_MASK) {
511                 /* Send the 1st byte of the slave address in the read operation
512                  * and change the state to indicate this has been done
513                  */
514                 SendSlaveAddr(InstancePtr);
515                 InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
516         }
517
518         /* In between 1st and last byte of message, fill the FIFO with more data
519          * to send, disable the 1/2 empty interrupt based upon data left to send
520          */
521         else if (InstancePtr->SendByteCount > 1) {
522                 XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
523
524                 if (InstancePtr->SendByteCount < 2) {
525                         XIic_mDisableIntr(InstancePtr->BaseAddress,
526                                           XIIC_INTR_TX_HALF_MASK);
527                 }
528         }
529         /*
530          * If there is only one byte left to send, processing differs between
531          * repeated start and normal messages
532          */
533         else if (InstancePtr->SendByteCount == 1) {
534                 /* When using repeated start, another interrupt is expected after the
535                  * last byte has been sent, so the message is not done yet
536                  */
537                 if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
538                         XIic_mWriteSendByte(InstancePtr);
539                 }
540
541                 /* When not using repeated start, the stop condition must be generated
542                  * after the last byte is written. The bus is throttled waiting for the last
543                  * byte.
544                  */
545                 else {
546                         /* Set the stop condition before sending the last byte of data so that
547                          * the stop condition will be generated immediately following the data
548                          * another transmit interrupt is not expected so the message is done
549                          */
550                         CntlReg &= ~XIIC_CR_MSMS_MASK;
551                         XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
552                                  CntlReg);
553
554                         XIic_mWriteSendByte(InstancePtr);
555                         MessageDone = TRUE;
556                 }
557         } else {
558                 /* The message being sent has completed. When using repeated start with
559                  * no more bytes to send repeated start needs to be set in the control
560                  * register so that the bus will still be held by this master
561                  */
562                 MessageDone = TRUE;
563
564                 if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
565                         CntlReg |= XIIC_CR_REPEATED_START_MASK;
566                         XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
567                                  CntlReg);
568                 }
569         }
570
571         /* If the message that was being sent has finished, disable all transmit
572          * interrupts and call the callbac that was setup to indicate the message
573          * was sent, with 0 bytes remaining
574          */
575         if (MessageDone) {
576                 XIic_mDisableIntr(InstancePtr->BaseAddress, XIIC_TX_INTERRUPTS);
577                 InstancePtr->SendHandler(InstancePtr->SendCallBackRef, 0);
578         }
579         return;
580 }
581
582 /*****************************************************************************/
583 /**
584 *
585 * This function is called when the receive register is full. The number
586 * of bytes received to cause the interrupt is adjustable using the Receive FIFO
587 * Depth register. The number of bytes in the register is read in the Receive
588 * FIFO occupancy register. Both these registers are zero based values (0-15)
589 * such that a value of zero indicates 1 byte.
590 *
591 * For a Master Receiver to properly signal the end of a message, the data must
592 * be read in up to the message length - 1, where control register bits will be
593 * set for bus controls to occur on reading of the last byte.
594 *
595 * @param    InstancePtr is a pointer to the XIic instance to be worked on.
596 *
597 * @return
598 *
599 * None.
600 *
601 * @note
602 *
603 * None.
604 *
605 ******************************************************************************/
606 static void
607 RecvMasterData(XIic * InstancePtr)
608 {
609         u8 LoopCnt;
610         u8 BytesInFifo;
611         int BytesToRead; /* Changed from u8 to int to prevent overflow. SAA */
612         u8 CntlReg;
613
614         /* Device is a master receiving, get the contents of the control register
615          * and determine the number of bytes in fifo to be read out
616          */
617         CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
618         BytesInFifo = XIo_In8(InstancePtr->BaseAddress + XIIC_RFO_REG_OFFSET)
619             + 1;
620
621         /* If data in FIFO holds all data to be retrieved - 1, set NOACK and
622          * disable the tx error
623          */
624         if ((InstancePtr->RecvByteCount - BytesInFifo) == 1) {
625                 /* Disable tx error interrupt to prevent interrupt
626                  * as this device will cause it when it set NO ACK next
627                  */
628                 XIic_mDisableIntr(InstancePtr->BaseAddress,
629                                   XIIC_INTR_TX_ERROR_MASK);
630                 XIic_mClearIntr(InstancePtr->BaseAddress,
631                                 XIIC_INTR_TX_ERROR_MASK);
632
633                 /* Write control reg with NO ACK allowing last byte to
634                  * have the No ack set to indicate to slave last byte read.
635                  */
636                 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
637                          (CntlReg | XIIC_CR_NO_ACK_MASK));
638
639                 /* Read one byte to clear a place for the last byte to be read
640                  * which will set the NO ACK
641                  */
642                 XIic_mReadRecvByte(InstancePtr);
643         }
644
645         /* If data in FIFO is all the data to be received then get the data
646          * and also leave the device in a good state for the next transaction
647          */
648         else if ((InstancePtr->RecvByteCount - BytesInFifo) == 0) {
649                 /* If repeated start option is off then the master should stop
650                  * using the bus, otherwise hold the bus, setting repeated start
651                  * stops the slave from transmitting data when the FIFO is read
652                  */
653                 if ((InstancePtr->Options & XII_REPEATED_START_OPTION) == 0) {
654                         CntlReg &= ~XIIC_CR_MSMS_MASK;
655                 } else {
656                         CntlReg |= XIIC_CR_REPEATED_START_MASK;
657                 }
658                 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
659                          CntlReg);
660
661                 /* Read data from the FIFO then set zero based FIFO read depth for a byte
662                  */
663                 for (LoopCnt = 0; LoopCnt < BytesInFifo; LoopCnt++) {
664                         XIic_mReadRecvByte(InstancePtr);
665                 }
666                 XIo_Out8(InstancePtr->BaseAddress + XIIC_RFD_REG_OFFSET, 0);
667
668                 /* Disable Rx full interrupt and write the control reg with ACK allowing
669                  * next byte sent to be acknowledged automatically
670                  */
671                 XIic_mDisableIntr(InstancePtr->BaseAddress,
672                                   XIIC_INTR_RX_FULL_MASK);
673
674                 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
675                          (CntlReg & ~XIIC_CR_NO_ACK_MASK));
676
677                 /* Send notification of msg Rx complete in RecvHandler callback
678                  */
679                 InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef, 0);
680         } else {
681                 /* Fifo data not at n-1, read all but the last byte of data from the
682                  * slave, if more than a FIFO full yet to receive read a FIFO full
683                  */
684                 BytesToRead = InstancePtr->RecvByteCount - BytesInFifo - 1;
685                 if (BytesToRead > IIC_RX_FIFO_DEPTH) {
686                         BytesToRead = IIC_RX_FIFO_DEPTH;
687                 }
688
689                 /* Read in data from the FIFO */
690
691                 for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
692                         XIic_mReadRecvByte(InstancePtr);
693                 }
694         }
695 }