import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / arch / ppc / boot / simple / xiic_l.c
1 /* $Id: xiic_l.c,v 1.1.1.1 2005/04/11 02:50:07 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_l.c
43 *
44 * This file contains low-level driver functions that can be used to access the
45 * device.  The user should refer to the hardware device specification for more
46 * details of the device operation.
47 *
48 * <pre>
49 * MODIFICATION HISTORY:
50 *
51 * Ver   Who  Date     Changes
52 * ----- --- -------  -----------------------------------------------
53 * 1.01b jhl 5/13/02  First release
54 * 1.01b jhl 10/14/02 Corrected bug in the receive function, the setup of the
55 *                    interrupt status mask was not being done in the loop such
56 *                    that a read would sometimes fail on the last byte because
57 *                    the transmit error which should have been ignored was
58 *                    being used.  This would leave an extra byte in the FIFO
59 *                    and the bus throttled such that the next operation would
60 *                    also fail.  Also updated the receive function to not
61 *                    disable the device after the last byte until after the
62 *                    bus transitions to not busy which is more consistent
63 *                    with the expected behavior.
64 * </pre>
65 *
66 ****************************************************************************/
67
68 /***************************** Include Files *******************************/
69
70 #include "xbasic_types.h"
71 #include "xio.h"
72 #include "xipif_v1_23_b.h"
73 #include "xiic_l.h"
74
75 /************************** Constant Definitions ***************************/
76
77 /**************************** Type Definitions *****************************/
78
79 /***************** Macros (Inline Functions) Definitions *******************/
80
81 /******************************************************************************
82 *
83 * This macro clears the specified interrupt in the IPIF interrupt status
84 * register.  It is non-destructive in that the register is read and only the
85 * interrupt specified is cleared.  Clearing an interrupt acknowledges it.
86 *
87 * @param    BaseAddress contains the IPIF registers base address.
88 *
89 * @param    InterruptMask contains the interrupts to be disabled
90 *
91 * @return
92 *
93 * None.
94 *
95 * @note
96 *
97 * Signature: void XIic_mClearIisr(u32 BaseAddress,
98 *                                 u32 InterruptMask);
99 *
100 ******************************************************************************/
101 #define XIic_mClearIisr(BaseAddress, InterruptMask)                 \
102     XIIF_V123B_WRITE_IISR((BaseAddress),                            \
103         XIIF_V123B_READ_IISR(BaseAddress) & (InterruptMask))
104
105 /******************************************************************************
106 *
107 * This macro sends the address for a 7 bit address during both read and write
108 * operations. It takes care of the details to format the address correctly.
109 * This macro is designed to be called internally to the drivers.
110 *
111 * @param    SlaveAddress contains the address of the slave to send to.
112 *
113 * @param    Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
114 *
115 * @return
116 *
117 * None.
118 *
119 * @note
120 *
121 * Signature: void XIic_mSend7BitAddr(u16 SlaveAddress, u8 Operation);
122 *
123 ******************************************************************************/
124 #define XIic_mSend7BitAddress(BaseAddress, SlaveAddress, Operation)         \
125 {                                                                           \
126     u8 LocalAddr = (u8)(SlaveAddress << 1);                         \
127     LocalAddr = (LocalAddr & 0xFE) | (Operation);                           \
128     XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET, LocalAddr);                 \
129 }
130
131 /************************** Function Prototypes ****************************/
132
133 static unsigned RecvData(u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount);
134 static unsigned SendData(u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount);
135
136 /************************** Variable Definitions **************************/
137
138 /****************************************************************************/
139 /**
140 * Receive data as a master on the IIC bus.  This function receives the data
141 * using polled I/O and blocks until the data has been received.  It only
142 * supports 7 bit addressing and non-repeated start modes of operation.  The
143 * user is responsible for ensuring the bus is not busy if multiple masters
144 * are present on the bus.
145 *
146 * @param    BaseAddress contains the base address of the IIC device.
147 * @param    Address contains the 7 bit IIC address of the device to send the
148 *           specified data to.
149 * @param    BufferPtr points to the data to be sent.
150 * @param    ByteCount is the number of bytes to be sent.
151 *
152 * @return
153 *
154 * The number of bytes received.
155 *
156 * @note
157 *
158 * None
159 *
160 ******************************************************************************/
161 unsigned
162 XIic_Recv(u32 BaseAddress, u8 Address, u8 * BufferPtr, unsigned ByteCount)
163 {
164         u8 CntlReg;
165         unsigned RemainingByteCount;
166
167         /* Tx error is enabled incase the address (7 or 10) has no device to answer
168          * with Ack. When only one byte of data, must set NO ACK before address goes
169          * out therefore Tx error must not be enabled as it will go off immediately
170          * and the Rx full interrupt will be checked.  If full, then the one byte
171          * was received and the Tx error will be disabled without sending an error
172          * callback msg.
173          */
174         XIic_mClearIisr(BaseAddress,
175                         XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK |
176                         XIIC_INTR_ARB_LOST_MASK);
177
178         /* Set receive FIFO occupancy depth for 1 byte (zero based)
179          */
180         XIo_Out8(BaseAddress + XIIC_RFD_REG_OFFSET, 0);
181
182         /* 7 bit slave address, send the address for a read operation
183          * and set the state to indicate the address has been sent
184          */
185         XIic_mSend7BitAddress(BaseAddress, Address, XIIC_READ_OPERATION);
186
187         /* MSMS gets set after putting data in FIFO. Start the master receive
188          * operation by setting CR Bits MSMS to Master, if the buffer is only one
189          * byte, then it should not be acknowledged to indicate the end of data
190          */
191         CntlReg = XIIC_CR_MSMS_MASK | XIIC_CR_ENABLE_DEVICE_MASK;
192         if (ByteCount == 1) {
193                 CntlReg |= XIIC_CR_NO_ACK_MASK;
194         }
195
196         /* Write out the control register to start receiving data and call the
197          * function to receive each byte into the buffer
198          */
199         XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, CntlReg);
200
201         /* Clear the latched interrupt status for the bus not busy bit which must
202          * be done while the bus is busy
203          */
204         XIic_mClearIisr(BaseAddress, XIIC_INTR_BNB_MASK);
205
206         /* Try to receive the data from the IIC bus */
207
208         RemainingByteCount = RecvData(BaseAddress, BufferPtr, ByteCount);
209         /*
210          * The receive is complete, disable the IIC device and return the number of
211          * bytes that was received
212          */
213         XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, 0);
214
215         /* Return the number of bytes that was received */
216
217         return ByteCount - RemainingByteCount;
218 }
219
220 /******************************************************************************
221 *
222 * Receive the specified data from the device that has been previously addressed
223 * on the IIC bus.  This function assumes that the 7 bit address has been sent
224 * and it should wait for the transmit of the address to complete.
225 *
226 * @param    BaseAddress contains the base address of the IIC device.
227 * @param    BufferPtr points to the buffer to hold the data that is received.
228 * @param    ByteCount is the number of bytes to be received.
229 *
230 * @return
231 *
232 * The number of bytes remaining to be received.
233 *
234 * @note
235 *
236 * This function does not take advantage of the receive FIFO because it is
237 * designed for minimal code space and complexity.  It contains loops that
238 * that could cause the function not to return if the hardware is not working.
239 *
240 * This function assumes that the calling function will disable the IIC device
241 * after this function returns.
242 *
243 ******************************************************************************/
244 static unsigned
245 RecvData(u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount)
246 {
247         u8 CntlReg;
248         u32 IntrStatusMask;
249         u32 IntrStatus;
250
251         /* Attempt to receive the specified number of bytes on the IIC bus */
252
253         while (ByteCount > 0) {
254                 /* Setup the mask to use for checking errors because when receiving one
255                  * byte OR the last byte of a multibyte message an error naturally
256                  * occurs when the no ack is done to tell the slave the last byte
257                  */
258                 if (ByteCount == 1) {
259                         IntrStatusMask =
260                             XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_BNB_MASK;
261                 } else {
262                         IntrStatusMask =
263                             XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_TX_ERROR_MASK |
264                             XIIC_INTR_BNB_MASK;
265                 }
266
267                 /* Wait for the previous transmit and the 1st receive to complete
268                  * by checking the interrupt status register of the IPIF
269                  */
270                 while (1) {
271                         IntrStatus = XIIF_V123B_READ_IISR(BaseAddress);
272                         if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
273                                 break;
274                         }
275                         /* Check the transmit error after the receive full because when
276                          * sending only one byte transmit error will occur because of the
277                          * no ack to indicate the end of the data
278                          */
279                         if (IntrStatus & IntrStatusMask) {
280                                 return ByteCount;
281                         }
282                 }
283
284                 CntlReg = XIo_In8(BaseAddress + XIIC_CR_REG_OFFSET);
285
286                 /* Special conditions exist for the last two bytes so check for them
287                  * Note that the control register must be setup for these conditions
288                  * before the data byte which was already received is read from the
289                  * receive FIFO (while the bus is throttled
290                  */
291                 if (ByteCount == 1) {
292                         /* For the last data byte, it has already been read and no ack
293                          * has been done, so clear MSMS while leaving the device enabled
294                          * so it can get off the IIC bus appropriately with a stop.
295                          */
296                         XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET,
297                                  XIIC_CR_ENABLE_DEVICE_MASK);
298                 }
299
300                 /* Before the last byte is received, set NOACK to tell the slave IIC
301                  * device that it is the end, this must be done before reading the byte
302                  * from the FIFO
303                  */
304                 if (ByteCount == 2) {
305                         /* Write control reg with NO ACK allowing last byte to
306                          * have the No ack set to indicate to slave last byte read.
307                          */
308                         XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET,
309                                  CntlReg | XIIC_CR_NO_ACK_MASK);
310                 }
311
312                 /* Read in data from the FIFO and unthrottle the bus such that the
313                  * next byte is read from the IIC bus
314                  */
315                 *BufferPtr++ = XIo_In8(BaseAddress + XIIC_DRR_REG_OFFSET);
316
317                 /* Clear the latched interrupt status so that it will be updated with
318                  * the new state when it changes, this must be done after the receive
319                  * register is read
320                  */
321                 XIic_mClearIisr(BaseAddress, XIIC_INTR_RX_FULL_MASK |
322                                 XIIC_INTR_TX_ERROR_MASK |
323                                 XIIC_INTR_ARB_LOST_MASK);
324                 ByteCount--;
325         }
326
327         /* Wait for the bus to transition to not busy before returning, the IIC
328          * device cannot be disabled until this occurs.  It should transition as
329          * the MSMS bit of the control register was cleared before the last byte
330          * was read from the FIFO.
331          */
332         while (1) {
333                 if (XIIF_V123B_READ_IISR(BaseAddress) & XIIC_INTR_BNB_MASK) {
334                         break;
335                 }
336         }
337
338         return ByteCount;
339 }
340
341 /****************************************************************************/
342 /**
343 * Send data as a master on the IIC bus.  This function sends the data
344 * using polled I/O and blocks until the data has been sent.  It only supports
345 * 7 bit addressing and non-repeated start modes of operation.  The user is
346 * responsible for ensuring the bus is not busy if multiple masters are present
347 * on the bus.
348 *
349 * @param    BaseAddress contains the base address of the IIC device.
350 * @param    Address contains the 7 bit IIC address of the device to send the
351 *           specified data to.
352 * @param    BufferPtr points to the data to be sent.
353 * @param    ByteCount is the number of bytes to be sent.
354 *
355 * @return
356 *
357 * The number of bytes sent.
358 *
359 * @note
360 *
361 * None
362 *
363 ******************************************************************************/
364 unsigned
365 XIic_Send(u32 BaseAddress, u8 Address, u8 * BufferPtr, unsigned ByteCount)
366 {
367         unsigned RemainingByteCount;
368
369         /* Put the address into the FIFO to be sent and indicate that the operation
370          * to be performed on the bus is a write operation
371          */
372         XIic_mSend7BitAddress(BaseAddress, Address, XIIC_WRITE_OPERATION);
373
374         /* Clear the latched interrupt status so that it will be updated with the
375          * new state when it changes, this must be done after the address is put
376          * in the FIFO
377          */
378         XIic_mClearIisr(BaseAddress, XIIC_INTR_TX_EMPTY_MASK |
379                         XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_ARB_LOST_MASK);
380
381         /* MSMS must be set after putting data into transmit FIFO, indicate the
382          * direction is transmit, this device is master and enable the IIC device
383          */
384         XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET,
385                  XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK |
386                  XIIC_CR_ENABLE_DEVICE_MASK);
387
388         /* Clear the latched interrupt
389          * status for the bus not busy bit which must be done while the bus is busy
390          */
391         XIic_mClearIisr(BaseAddress, XIIC_INTR_BNB_MASK);
392
393         /* Send the specified data to the device on the IIC bus specified by the
394          * the address
395          */
396         RemainingByteCount = SendData(BaseAddress, BufferPtr, ByteCount);
397
398         /*
399          * The send is complete, disable the IIC device and return the number of
400          * bytes that was sent
401          */
402         XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, 0);
403
404         return ByteCount - RemainingByteCount;
405 }
406
407 /******************************************************************************
408 *
409 * Send the specified buffer to the device that has been previously addressed
410 * on the IIC bus.  This function assumes that the 7 bit address has been sent
411 * and it should wait for the transmit of the address to complete.
412 *
413 * @param    BaseAddress contains the base address of the IIC device.
414 * @param    BufferPtr points to the data to be sent.
415 * @param    ByteCount is the number of bytes to be sent.
416 *
417 * @return
418 *
419 * The number of bytes remaining to be sent.
420 *
421 * @note
422 *
423 * This function does not take advantage of the transmit FIFO because it is
424 * designed for minimal code space and complexity.  It contains loops that
425 * that could cause the function not to return if the hardware is not working.
426 *
427 ******************************************************************************/
428 static unsigned
429 SendData(u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount)
430 {
431         u32 IntrStatus;
432
433         /* Send the specified number of bytes in the specified buffer by polling
434          * the device registers and blocking until complete
435          */
436         while (ByteCount > 0) {
437                 /* Wait for the transmit to be empty before sending any more data
438                  * by polling the interrupt status register
439                  */
440                 while (1) {
441                         IntrStatus = XIIF_V123B_READ_IISR(BaseAddress);
442
443                         if (IntrStatus & (XIIC_INTR_TX_ERROR_MASK |
444                                           XIIC_INTR_ARB_LOST_MASK |
445                                           XIIC_INTR_BNB_MASK)) {
446                                 return ByteCount;
447                         }
448
449                         if (IntrStatus & XIIC_INTR_TX_EMPTY_MASK) {
450                                 break;
451                         }
452                 }
453                 /* If there is more than one byte to send then put the next byte to send
454                  * into the transmit FIFO
455                  */
456                 if (ByteCount > 1) {
457                         XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET,
458                                  *BufferPtr++);
459                 } else {
460                         /* Set the stop condition before sending the last byte of data so that
461                          * the stop condition will be generated immediately following the data
462                          * This is done by clearing the MSMS bit in the control register.
463                          */
464                         XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET,
465                                  XIIC_CR_ENABLE_DEVICE_MASK |
466                                  XIIC_CR_DIR_IS_TX_MASK);
467
468                         /* Put the last byte to send in the transmit FIFO */
469
470                         XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET,
471                                  *BufferPtr++);
472                 }
473
474                 /* Clear the latched interrupt status register and this must be done after
475                  * the transmit FIFO has been written to or it won't clear
476                  */
477                 XIic_mClearIisr(BaseAddress, XIIC_INTR_TX_EMPTY_MASK);
478
479                 /* Update the byte count to reflect the byte sent and clear the latched
480                  * interrupt status so it will be updated for the new state
481                  */
482                 ByteCount--;
483         }
484
485         /* Wait for the bus to transition to not busy before returning, the IIC
486          * device cannot be disabled until this occurs.
487          * Note that this is different from a receive operation because the stop
488          * condition causes the bus to go not busy.
489          */
490         while (1) {
491                 if (XIIF_V123B_READ_IISR(BaseAddress) & XIIC_INTR_BNB_MASK) {
492                         break;
493                 }
494         }
495
496         return ByteCount;
497 }