• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 I2C Library for Quark I2C Controller.
3 Follows I2C Controller setup instructions as detailed in
4 Quark DataSheet (doc id: 329676) Section 19.1/19.1.3.
5 
6 
7 Copyright (c) 2013-2015 Intel Corporation.
8 
9 This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution.  The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
13 
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 
17 **/
18 
19 #include "CommonHeader.h"
20 
21 /**
22   The Called to Common Service Entry.
23 
24   @return None.
25 
26 **/
27 
28 VOID
I2cCommonServiceEntry(OUT UINT16 * SaveCmdPtr,OUT UINT32 * SaveBar0Ptr)29 I2cCommonServiceEntry  (
30   OUT UINT16 *SaveCmdPtr,
31   OUT UINT32 *SaveBar0Ptr
32   )
33 {
34   *SaveBar0Ptr = IohMmPci32 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0);
35   if (((*SaveBar0Ptr) & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK) == 0) {
36 
37     IohMmPci32(0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0) =
38       FixedPcdGet32 (PcdIohI2cMmioBase) & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK;
39 
40     //
41     // also Save Cmd Register, Setup by InitializeInternal later during xfers.
42     //
43     *SaveCmdPtr = IohMmPci16 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_CMD);
44   }
45 }
46 
47 /**
48   The Called on Common Service Exit.
49 
50   @return None.
51 
52 **/
53 VOID
I2cCommonServiceExit(IN CONST UINT16 SaveCmd,IN CONST UINT32 SaveBar0)54 I2cCommonServiceExit  (
55   IN CONST UINT16 SaveCmd,
56   IN CONST UINT32 SaveBar0
57 
58   )
59 {
60   if ((SaveBar0 & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK) == 0) {
61     IohMmPci16 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_CMD) = SaveCmd;
62     IohMmPci32 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0) = SaveBar0;
63   }
64 }
65 
66 
67 /**
68   The GetI2CIoPortBaseAddress() function gets IO port base address of I2C Controller.
69 
70   Always reads PCI configuration space to get MMIO base address of I2C Controller.
71 
72   @return The IO port base address of I2C controller.
73 
74 **/
75 UINTN
GetI2CIoPortBaseAddress(VOID)76 GetI2CIoPortBaseAddress (
77   VOID
78   )
79 {
80   UINTN     I2CIoPortBaseAddress;
81 
82   //
83   // Get I2C Memory Mapped registers base address.
84   //
85   I2CIoPortBaseAddress = IohMmPci32(0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0);
86 
87   //
88   // Make sure that the IO port base address has been properly set.
89   //
90   ASSERT (I2CIoPortBaseAddress != 0);
91   ASSERT (I2CIoPortBaseAddress != 0xFF);
92 
93   return I2CIoPortBaseAddress;
94 }
95 
96 
97 /**
98   The EnableI2CMmioSpace() function enables access to I2C MMIO space.
99 
100 **/
101 VOID
EnableI2CMmioSpace(VOID)102 EnableI2CMmioSpace (
103   VOID
104   )
105 {
106   UINT8 PciCmd;
107 
108   //
109   // Read PCICMD.  Bus=0, Dev=0, Func=0, Reg=0x4
110   //
111   PciCmd = IohMmPci8(0, I2C_Bus, I2C_Device, I2C_Func, PCI_REG_PCICMD);
112 
113   //
114   // Enable Bus Master(Bit2), MMIO Space(Bit1) & I/O Space(Bit0)
115   //
116   PciCmd |= 0x7;
117   IohMmPci8(0, I2C_Bus, I2C_Device, I2C_Func, PCI_REG_PCICMD) = PciCmd;
118 
119 }
120 
121 /**
122   The DisableI2CController() functions disables I2C Controller.
123 
124 **/
125 VOID
DisableI2CController(VOID)126 DisableI2CController (
127   VOID
128   )
129 {
130   UINTN       I2CIoPortBaseAddress;
131   UINT32      Addr;
132   UINT32      Data;
133   UINT8       PollCount;
134 
135   PollCount = 0;
136 
137   //
138   // Get I2C Memory Mapped registers base address.
139   //
140   I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
141 
142   //
143   // Disable the I2C Controller by setting IC_ENABLE.ENABLE to zero
144   //
145   Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE;
146   Data = *((volatile UINT32 *) (UINTN)(Addr));
147   Data &= ~B_I2C_REG_ENABLE;
148   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
149 
150   //
151   // Read the IC_ENABLE_STATUS.IC_EN Bit to check if Controller is disabled
152   //
153   Data = 0xFF;
154   Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE_STATUS;
155   Data = *((volatile UINT32 *) (UINTN)(Addr)) & I2C_REG_ENABLE_STATUS;
156   while (Data != 0) {
157     //
158     // Poll the IC_ENABLE_STATUS.IC_EN Bit to check if Controller is disabled, until timeout (TI2C_POLL*MAX_T_POLL_COUNT).
159     //
160     PollCount++;
161     if (PollCount >= MAX_T_POLL_COUNT) {
162       break;
163     }
164     MicroSecondDelay(TI2C_POLL);
165     Data = *((volatile UINT32 *) (UINTN)(Addr));
166     Data &= I2C_REG_ENABLE_STATUS;
167   }
168 
169   //
170   // Asset if controller does not enter Disabled state.
171   //
172   ASSERT (PollCount < MAX_T_POLL_COUNT);
173 
174   //
175   // Read IC_CLR_INTR register to automatically clear the combined interrupt,
176   // all individual interrupts and the IC_TX_ABRT_SOURCE register.
177   //
178   Addr = I2CIoPortBaseAddress + I2C_REG_CLR_INT;
179   Data = *((volatile UINT32 *) (UINTN)(Addr));
180 
181 }
182 
183 /**
184   The EnableI2CController() function enables the I2C Controller.
185 
186 **/
187 VOID
EnableI2CController(VOID)188 EnableI2CController (
189   VOID
190   )
191 {
192   UINTN   I2CIoPortBaseAddress;
193   UINT32  Addr;
194   UINT32  Data;
195 
196   //
197   // Get I2C Memory Mapped registers base address.
198   //
199   I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
200 
201   //
202   // Enable the I2C Controller by setting IC_ENABLE.ENABLE to 1
203   //
204   Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE;
205   Data = *((volatile UINT32 *) (UINTN)(Addr));
206   Data |= B_I2C_REG_ENABLE;
207   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
208 
209   //
210   // Clear overflow and abort error status bits before transactions.
211   //
212   Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_OVER;
213   Data = *((volatile UINT32 *) (UINTN)(Addr));
214   Addr = I2CIoPortBaseAddress + I2C_REG_CLR_TX_OVER;
215   Data = *((volatile UINT32 *) (UINTN)(Addr));
216   Addr = I2CIoPortBaseAddress + I2C_REG_CLR_TX_ABRT;
217   Data = *((volatile UINT32 *) (UINTN)(Addr));
218 
219 }
220 
221 /**
222   The WaitForStopDet() function waits until I2C STOP Condition occurs,
223   indicating transfer completion.
224 
225   @retval EFI_SUCCESS           Stop detected.
226   @retval EFI_TIMEOUT           Timeout while waiting for stop condition.
227   @retval EFI_ABORTED           Tx abort signaled in HW status register.
228   @retval EFI_DEVICE_ERROR      Tx or Rx overflow detected.
229 
230 **/
231 EFI_STATUS
WaitForStopDet(VOID)232 WaitForStopDet (
233   VOID
234   )
235 {
236   UINTN       I2CIoPortBaseAddress;
237   UINT32      Addr;
238   UINT32      Data;
239   UINT32      PollCount;
240   EFI_STATUS  Status;
241 
242   Status = EFI_SUCCESS;
243 
244   PollCount = 0;
245 
246   //
247   // Get I2C Memory Mapped registers base address.
248   //
249   I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
250 
251   //
252   // Wait for STOP Detect.
253   //
254   Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
255 
256   do {
257     Data = *((volatile UINT32 *) (UINTN)(Addr));
258     if ((Data & I2C_REG_RAW_INTR_STAT_TX_ABRT) != 0) {
259       Status = EFI_ABORTED;
260       break;
261     }
262     if ((Data & I2C_REG_RAW_INTR_STAT_TX_OVER) != 0) {
263       Status = EFI_DEVICE_ERROR;
264       break;
265     }
266     if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0) {
267       Status = EFI_DEVICE_ERROR;
268       break;
269     }
270     if ((Data & I2C_REG_RAW_INTR_STAT_STOP_DET) != 0) {
271       Status = EFI_SUCCESS;
272       break;
273     }
274     MicroSecondDelay(TI2C_POLL);
275     PollCount++;
276     if (PollCount >= MAX_STOP_DET_POLL_COUNT) {
277       Status = EFI_TIMEOUT;
278       break;
279     }
280 
281   } while (TRUE);
282 
283   return Status;
284 }
285 
286 /**
287 
288   The InitializeInternal() function initialises internal I2C Controller
289   register values that are commonly required for I2C Write and Read transfers.
290 
291   @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
292 
293   @retval EFI_SUCCESS           I2C Operation completed successfully.
294 
295 **/
296 EFI_STATUS
InitializeInternal(IN EFI_I2C_ADDR_MODE AddrMode)297 InitializeInternal (
298   IN  EFI_I2C_ADDR_MODE  AddrMode
299   )
300 {
301   UINTN       I2CIoPortBaseAddress;
302   UINTN       Addr;
303   UINT32      Data;
304   EFI_STATUS  Status;
305 
306   Status = EFI_SUCCESS;
307 
308   //
309   // Enable access to I2C Controller MMIO space.
310   //
311   EnableI2CMmioSpace ();
312 
313   //
314   // Disable I2C Controller initially
315   //
316   DisableI2CController ();
317 
318   //
319   // Get I2C Memory Mapped registers base address.
320   //
321   I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
322 
323   //
324   // Clear START_DET
325   //
326   Addr = I2CIoPortBaseAddress + I2C_REG_CLR_START_DET;
327   Data = *((volatile UINT32 *) (UINTN)(Addr));
328   Data &= ~B_I2C_REG_CLR_START_DET;
329   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
330 
331   //
332   // Clear STOP_DET
333   //
334   Addr = I2CIoPortBaseAddress + I2C_REG_CLR_STOP_DET;
335   Data = *((volatile UINT32 *) (UINTN)(Addr));
336   Data &= ~B_I2C_REG_CLR_STOP_DET;
337   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
338 
339   //
340   // Set addressing mode to user defined (7 or 10 bit) and
341   // speed mode to that defined by PCD (standard mode default).
342   //
343   Addr = I2CIoPortBaseAddress + I2C_REG_CON;
344   Data = *((volatile UINT32 *) (UINTN)(Addr));
345   // Set Addressing Mode
346   if (AddrMode == EfiI2CSevenBitAddrMode) {
347     Data &= ~B_I2C_REG_CON_10BITADD_MASTER;
348   } else {
349     Data |= B_I2C_REG_CON_10BITADD_MASTER;
350   }
351   // Set Speed Mode
352   Data &= ~B_I2C_REG_CON_SPEED;
353   if (FeaturePcdGet (PcdI2CFastModeEnabled)) {
354     Data |= BIT2;
355   } else {
356     Data |= BIT1;
357   }
358   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
359 
360   Data = *((volatile UINT32 *) (UINTN)(Addr));
361 
362   return Status;
363 
364 }
365 
366 /**
367 
368   The WriteByte() function provides a standard way to execute a
369   standard single byte write to an IC2 device (without accessing
370   sub-addresses), as defined in the I2C Specification.
371 
372   @param  I2CAddress      I2C Slave device address
373   @param  Value           The 8-bit value to write.
374 
375   @retval EFI_SUCCESS           Transfer success.
376   @retval EFI_UNSUPPORTED       Unsupported input param.
377   @retval EFI_TIMEOUT           Timeout while waiting xfer.
378   @retval EFI_ABORTED           Controller aborted xfer.
379   @retval EFI_DEVICE_ERROR      Device error detected by controller.
380 
381 **/
382 EFI_STATUS
383 EFIAPI
WriteByte(IN UINTN I2CAddress,IN UINT8 Value)384 WriteByte (
385   IN  UINTN          I2CAddress,
386   IN  UINT8          Value
387   )
388 {
389   UINTN       I2CIoPortBaseAddress;
390   UINTN       Addr;
391   UINT32      Data;
392   EFI_STATUS  Status;
393 
394   //
395   // Get I2C Memory Mapped registers base address
396   //
397   I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
398 
399   //
400   // Write to the IC_TAR register the address of the slave device to be addressed
401   //
402   Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
403   Data = *((volatile UINT32 *) (UINTN)(Addr));
404   Data &= ~B_I2C_REG_TAR;
405   Data |= I2CAddress;
406   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
407 
408   //
409   // Enable the I2C Controller
410   //
411   EnableI2CController ();
412 
413   //
414   // Write the data and transfer direction to the IC_DATA_CMD register.
415   // Also specify that transfer should be terminated by STOP condition.
416   //
417   Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
418   Data = *((volatile UINT32 *) (UINTN)(Addr));
419   Data &= 0xFFFFFF00;
420   Data |= (UINT8)Value;
421   Data &= ~B_I2C_REG_DATA_CMD_RW;
422   Data |= B_I2C_REG_DATA_CMD_STOP;
423   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
424 
425   //
426   // Wait for transfer completion.
427   //
428   Status = WaitForStopDet ();
429 
430   //
431   // Ensure I2C Controller disabled.
432   //
433   DisableI2CController();
434 
435   return Status;
436 }
437 
438 /**
439 
440   The ReadByte() function provides a standard way to execute a
441   standard single byte read to an IC2 device (without accessing
442   sub-addresses), as defined in the I2C Specification.
443 
444   @param  I2CAddress      I2C Slave device address
445   @param  ReturnDataPtr   Pointer to location to receive read byte.
446 
447   @retval EFI_SUCCESS           Transfer success.
448   @retval EFI_UNSUPPORTED       Unsupported input param.
449   @retval EFI_TIMEOUT           Timeout while waiting xfer.
450   @retval EFI_ABORTED           Controller aborted xfer.
451   @retval EFI_DEVICE_ERROR      Device error detected by controller.
452 
453 **/
454 EFI_STATUS
455 EFIAPI
ReadByte(IN UINTN I2CAddress,OUT UINT8 * ReturnDataPtr)456 ReadByte (
457   IN  UINTN          I2CAddress,
458   OUT UINT8          *ReturnDataPtr
459   )
460 {
461   UINTN       I2CIoPortBaseAddress;
462   UINTN       Addr;
463   UINT32      Data;
464   EFI_STATUS  Status;
465 
466   //
467   // Get I2C Memory Mapped registers base address.
468   //
469   I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
470 
471   //
472   // Write to the IC_TAR register the address of the slave device to be addressed
473   //
474   Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
475   Data = *((volatile UINT32 *) (UINTN)(Addr));
476   Data &= ~B_I2C_REG_TAR;
477   Data |= I2CAddress;
478   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
479 
480   //
481   // Enable the I2C Controller
482   //
483   EnableI2CController ();
484 
485   //
486   // Write transfer direction to the IC_DATA_CMD register and
487   // specify that transfer should be terminated by STOP condition.
488   //
489   Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
490   Data = *((volatile UINT32 *) (UINTN)(Addr));
491   Data &= 0xFFFFFF00;
492   Data |= B_I2C_REG_DATA_CMD_RW;
493   Data |= B_I2C_REG_DATA_CMD_STOP;
494   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
495 
496   //
497   // Wait for transfer completion
498   //
499   Status = WaitForStopDet ();
500   if (!EFI_ERROR(Status)) {
501 
502     //
503     // Clear RX underflow before reading IC_DATA_CMD.
504     //
505     Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_UNDER;
506     Data = *((volatile UINT32 *) (UINTN)(Addr));
507 
508     //
509     // Obtain and return read data byte from RX buffer (IC_DATA_CMD[7:0]).
510     //
511     Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
512     Data = *((volatile UINT32 *) (UINTN)(Addr));
513     Data &= 0x000000FF;
514     *ReturnDataPtr = (UINT8) Data;
515 
516     Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
517     Data = *((volatile UINT32 *) (UINTN)(Addr));
518     Data &= I2C_REG_RAW_INTR_STAT_RX_UNDER;
519     if (Data != 0) {
520       Status = EFI_DEVICE_ERROR;
521     }
522   }
523 
524   //
525   // Ensure I2C Controller disabled.
526   //
527   DisableI2CController ();
528 
529   return Status;
530 }
531 
532 /**
533 
534   The WriteMultipleByte() function provides a standard way to execute
535   multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or
536   when writing block of data), as defined in the I2C Specification.
537 
538   @param I2CAddress   The I2C slave address of the device
539                       with which to communicate.
540 
541   @param WriteBuffer  Contains the value of byte to be written to the
542                       I2C slave device.
543 
544   @param Length       No. of bytes to be written.
545 
546   @retval EFI_SUCCESS           Transfer success.
547   @retval EFI_UNSUPPORTED       Unsupported input param.
548   @retval EFI_TIMEOUT           Timeout while waiting xfer.
549   @retval EFI_ABORTED           Tx abort signaled in HW status register.
550   @retval EFI_DEVICE_ERROR      Tx overflow detected.
551 
552 **/
553 EFI_STATUS
554 EFIAPI
WriteMultipleByte(IN UINTN I2CAddress,IN UINT8 * WriteBuffer,IN UINTN Length)555 WriteMultipleByte (
556   IN  UINTN          I2CAddress,
557   IN  UINT8          *WriteBuffer,
558   IN  UINTN          Length
559   )
560 {
561   UINTN       I2CIoPortBaseAddress;
562   UINTN       Index;
563   UINTN       Addr;
564   UINT32      Data;
565   EFI_STATUS  Status;
566 
567   if (Length > I2C_FIFO_SIZE) {
568     return EFI_UNSUPPORTED;  // Routine does not handle xfers > fifo size.
569   }
570 
571   I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
572 
573   //
574   // Write to the IC_TAR register the address of the slave device to be addressed
575   //
576   Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
577   Data = *((volatile UINT32 *) (UINTN)(Addr));
578   Data &= ~B_I2C_REG_TAR;
579   Data |= I2CAddress;
580   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
581 
582   //
583   // Enable the I2C Controller
584   //
585   EnableI2CController ();
586 
587   //
588   // Write the data and transfer direction to the IC_DATA_CMD register.
589   // Also specify that transfer should be terminated by STOP condition.
590   //
591   Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
592   for (Index = 0; Index < Length; Index++) {
593     Data = *((volatile UINT32 *) (UINTN)(Addr));
594     Data &= 0xFFFFFF00;
595     Data |= (UINT8)WriteBuffer[Index];
596     Data &= ~B_I2C_REG_DATA_CMD_RW;
597     if (Index == (Length-1)) {
598       Data |= B_I2C_REG_DATA_CMD_STOP;
599     }
600     *((volatile UINT32 *) (UINTN)(Addr)) = Data;
601   }
602 
603   //
604   // Wait for transfer completion
605   //
606   Status = WaitForStopDet ();
607 
608   //
609   // Ensure I2C Controller disabled.
610   //
611   DisableI2CController ();
612   return Status;
613 }
614 
615 /**
616 
617   The ReadMultipleByte() function provides a standard way to execute
618   multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or
619   when reading block of data), as defined in the I2C Specification (I2C combined
620   write/read protocol).
621 
622   @param I2CAddress   The I2C slave address of the device
623                       with which to communicate.
624 
625   @param Buffer       Contains the value of byte data written or read from the
626                       I2C slave device.
627 
628   @param WriteLength  No. of bytes to be written. In this case data
629                       written typically contains sub-address or sub-addresses
630                       in Hi-Lo format, that need to be read (I2C combined
631                       write/read protocol).
632 
633   @param ReadLength   No. of bytes to be read from I2C slave device.
634 
635   @retval EFI_SUCCESS           Transfer success.
636   @retval EFI_UNSUPPORTED       Unsupported input param.
637   @retval EFI_TIMEOUT           Timeout while waiting xfer.
638   @retval EFI_ABORTED           Tx abort signaled in HW status register.
639   @retval EFI_DEVICE_ERROR      Rx underflow or Rx/Tx overflow detected.
640 
641 **/
642 EFI_STATUS
643 EFIAPI
ReadMultipleByte(IN UINTN I2CAddress,IN OUT UINT8 * Buffer,IN UINTN WriteLength,IN UINTN ReadLength)644 ReadMultipleByte (
645   IN  UINTN          I2CAddress,
646   IN  OUT UINT8      *Buffer,
647   IN  UINTN          WriteLength,
648   IN  UINTN          ReadLength
649   )
650 {
651   UINTN       I2CIoPortBaseAddress;
652   UINTN       Index;
653   UINTN       Addr;
654   UINT32      Data;
655   UINT8       PollCount;
656   EFI_STATUS  Status;
657 
658   if (WriteLength > I2C_FIFO_SIZE || ReadLength > I2C_FIFO_SIZE) {
659     return EFI_UNSUPPORTED;  // Routine does not handle xfers > fifo size.
660   }
661 
662   I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
663 
664   //
665   // Write to the IC_TAR register the address of the slave device to be addressed
666   //
667   Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
668   Data = *((volatile UINT32 *) (UINTN)(Addr));
669   Data &= ~B_I2C_REG_TAR;
670   Data |= I2CAddress;
671   *((volatile UINT32 *) (UINTN)(Addr)) = Data;
672 
673   //
674   // Enable the I2C Controller
675   //
676   EnableI2CController ();
677 
678   //
679   // Write the data (sub-addresses) to the IC_DATA_CMD register.
680   //
681   Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
682   for (Index = 0; Index < WriteLength; Index++) {
683     Data = *((volatile UINT32 *) (UINTN)(Addr));
684     Data &= 0xFFFFFF00;
685     Data |= (UINT8)Buffer[Index];
686     Data &= ~B_I2C_REG_DATA_CMD_RW;
687     *((volatile UINT32 *) (UINTN)(Addr)) = Data;
688   }
689 
690   //
691   // Issue Read Transfers for each byte (Restart issued when write/read bit changed).
692   //
693   for (Index = 0; Index < ReadLength; Index++) {
694     Data = *((volatile UINT32 *) (UINTN)(Addr));
695     Data |= B_I2C_REG_DATA_CMD_RW;
696     // Issue a STOP for last read transfer.
697     if (Index == (ReadLength-1)) {
698       Data |= B_I2C_REG_DATA_CMD_STOP;
699     }
700     *((volatile UINT32 *) (UINTN)(Addr)) = Data;
701   }
702 
703   //
704   // Wait for STOP condition.
705   //
706   Status = WaitForStopDet ();
707   if (!EFI_ERROR(Status)) {
708 
709     //
710     // Poll Receive FIFO Buffer Level register until valid (upto MAX_T_POLL_COUNT times).
711     //
712     Data = 0;
713     PollCount = 0;
714     Addr = I2CIoPortBaseAddress + I2C_REG_RXFLR;
715     Data = *((volatile UINT32 *) (UINTN)(Addr));
716     while ((Data != ReadLength) && (PollCount < MAX_T_POLL_COUNT)) {
717       MicroSecondDelay(TI2C_POLL);
718       PollCount++;
719       Data = *((volatile UINT32 *) (UINTN)(Addr));
720     }
721 
722     Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
723     Data = *((volatile UINT32 *) (UINTN)(Addr));
724 
725     //
726     // If no timeout or device error then read rx data.
727     //
728     if (PollCount == MAX_T_POLL_COUNT) {
729       Status = EFI_TIMEOUT;
730     } else if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0) {
731       Status = EFI_DEVICE_ERROR;
732     } else {
733 
734       //
735       // Clear RX underflow before reading IC_DATA_CMD.
736       //
737       Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_UNDER;
738       Data = *((volatile UINT32 *) (UINTN)(Addr));
739 
740       //
741       // Read data.
742       //
743       Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
744       for (Index = 0; Index < ReadLength; Index++) {
745         Data = *((volatile UINT32 *) (UINTN)(Addr));
746         Data &= 0x000000FF;
747         *(Buffer+Index) = (UINT8)Data;
748       }
749       Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
750       Data = *((volatile UINT32 *) (UINTN)(Addr));
751       Data &= I2C_REG_RAW_INTR_STAT_RX_UNDER;
752       if (Data != 0) {
753         Status = EFI_DEVICE_ERROR;
754       } else {
755         Status = EFI_SUCCESS;
756       }
757     }
758   }
759 
760   //
761   // Ensure I2C Controller disabled.
762   //
763   DisableI2CController ();
764 
765   return Status;
766 }
767 
768 /**
769 
770   The I2cWriteByte() function is a wrapper function for the WriteByte function.
771   Provides a standard way to execute a standard single byte write to an IC2 device
772   (without accessing sub-addresses), as defined in the I2C Specification.
773 
774   @param SlaveAddress The I2C slave address of the device
775                       with which to communicate.
776 
777   @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
778 
779   @param Buffer       Contains the value of byte data to execute to the
780                       I2C slave device.
781 
782 
783   @retval EFI_SUCCESS           Transfer success.
784   @retval EFI_INVALID_PARAMETER  This or Buffer pointers are invalid.
785   @retval EFI_UNSUPPORTED       Unsupported input param.
786   @retval EFI_TIMEOUT           Timeout while waiting xfer.
787   @retval EFI_ABORTED           Controller aborted xfer.
788   @retval EFI_DEVICE_ERROR      Device error detected by controller.
789 
790 **/
791 EFI_STATUS
792 EFIAPI
I2cWriteByte(IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,IN EFI_I2C_ADDR_MODE AddrMode,IN OUT VOID * Buffer)793 I2cWriteByte (
794   IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
795   IN        EFI_I2C_ADDR_MODE       AddrMode,
796   IN OUT VOID                       *Buffer
797   )
798 {
799   EFI_STATUS Status;
800   UINTN      I2CAddress;
801   UINT16            SaveCmd;
802   UINT32            SaveBar0;
803 
804   if (Buffer == NULL) {
805     return EFI_INVALID_PARAMETER;
806   }
807   SaveCmd = 0;
808   SaveBar0 = 0;
809 
810   I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
811 
812   Status = EFI_SUCCESS;
813 
814   I2CAddress = SlaveAddress.I2CDeviceAddress;
815   Status = InitializeInternal (AddrMode);
816   if (!EFI_ERROR(Status)) {
817     Status = WriteByte (I2CAddress, *(UINT8 *) Buffer);
818   }
819 
820   I2cCommonServiceExit (SaveCmd, SaveBar0);
821   return Status;
822 }
823 
824 /**
825 
826   The I2cReadByte() function is a wrapper function for the ReadByte function.
827   Provides a standard way to execute a standard single byte read to an I2C device
828   (without accessing sub-addresses), as defined in the I2C Specification.
829 
830   @param SlaveAddress The I2C slave address of the device
831                       with which to communicate.
832 
833   @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
834 
835   @param Buffer       Contains the value of byte data read from the
836                       I2C slave device.
837 
838 
839   @retval EFI_SUCCESS           Transfer success.
840   @retval EFI_INVALID_PARAMETER This or Buffer pointers are invalid.
841   @retval EFI_TIMEOUT           Timeout while waiting xfer.
842   @retval EFI_ABORTED           Controller aborted xfer.
843   @retval EFI_DEVICE_ERROR      Device error detected by controller.
844 
845 
846 **/
847 EFI_STATUS
848 EFIAPI
I2cReadByte(IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,IN EFI_I2C_ADDR_MODE AddrMode,IN OUT VOID * Buffer)849 I2cReadByte (
850   IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
851   IN        EFI_I2C_ADDR_MODE       AddrMode,
852   IN OUT    VOID                    *Buffer
853   )
854 {
855   EFI_STATUS Status;
856   UINTN      I2CAddress;
857   UINT16     SaveCmd;
858   UINT32     SaveBar0;
859 
860   if (Buffer == NULL) {
861     return EFI_INVALID_PARAMETER;
862   }
863   SaveCmd = 0;
864   SaveBar0 =0;
865 
866   I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
867 
868   Status = EFI_SUCCESS;
869 
870   I2CAddress = SlaveAddress.I2CDeviceAddress;
871 
872   Status = InitializeInternal (AddrMode);
873   if (!EFI_ERROR(Status)) {
874     Status = ReadByte (I2CAddress, (UINT8 *) Buffer);
875   }
876   I2cCommonServiceExit (SaveCmd, SaveBar0);
877   return Status;
878 }
879 
880 /**
881 
882   The I2cWriteMultipleByte() function is a wrapper function for the
883   WriteMultipleByte() function. Provides a standard way to execute multiple
884   byte writes to an I2C device (e.g. when accessing sub-addresses or writing
885   block of data), as defined in the I2C Specification.
886 
887   @param SlaveAddress The I2C slave address of the device
888                       with which to communicate.
889 
890   @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
891 
892   @param Length       No. of bytes to be written.
893 
894   @param Buffer       Contains the value of byte to be written to the
895                       I2C slave device.
896 
897   @retval EFI_SUCCESS            Transfer success.
898   @retval EFI_INVALID_PARAMETER  This, Length or Buffer pointers are invalid.
899   @retval EFI_UNSUPPORTED        Unsupported input param.
900   @retval EFI_TIMEOUT            Timeout while waiting xfer.
901   @retval EFI_ABORTED            Controller aborted xfer.
902   @retval EFI_DEVICE_ERROR       Device error detected by controller.
903 
904 **/
905 EFI_STATUS
906 EFIAPI
I2cWriteMultipleByte(IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,IN EFI_I2C_ADDR_MODE AddrMode,IN UINTN * Length,IN OUT VOID * Buffer)907 I2cWriteMultipleByte (
908   IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
909   IN        EFI_I2C_ADDR_MODE       AddrMode,
910   IN UINTN                          *Length,
911   IN OUT    VOID                    *Buffer
912   )
913 {
914   EFI_STATUS Status;
915   UINTN      I2CAddress;
916   UINT16     SaveCmd;
917   UINT32     SaveBar0;
918 
919     if (Buffer == NULL || Length == NULL) {
920     return EFI_INVALID_PARAMETER;
921   }
922   SaveCmd = 0;
923   SaveBar0 =0;
924 
925   I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
926   Status = EFI_SUCCESS;
927 
928   I2CAddress = SlaveAddress.I2CDeviceAddress;
929 
930   Status = InitializeInternal (AddrMode);
931   if (!EFI_ERROR(Status)) {
932     Status = WriteMultipleByte (I2CAddress, Buffer, (*Length));
933   }
934 
935   I2cCommonServiceExit (SaveCmd, SaveBar0);
936   return Status;
937 }
938 
939 /**
940 
941   The I2cReadMultipleByte() function is a wrapper function for the ReadMultipleByte() function.
942   Provides a standard way to execute multiple byte writes to an I2C device
943   (e.g. when accessing sub-addresses or when reading block of data), as defined
944   in the I2C Specification (I2C combined write/read protocol).
945 
946   @param SlaveAddress The I2C slave address of the device
947                       with which to communicate.
948 
949   @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
950 
951   @param WriteLength  No. of bytes to be written. In this case data
952                       written typically contains sub-address or sub-addresses
953                       in Hi-Lo format, that need to be read (I2C combined
954                       write/read protocol).
955 
956   @param ReadLength   No. of bytes to be read from I2C slave device.
957 
958   @param Buffer       Contains the value of byte data read from the
959                       I2C slave device.
960 
961   @retval EFI_SUCCESS            Transfer success.
962   @retval EFI_INVALID_PARAMETER  This, WriteLength, ReadLength or Buffer
963                                  pointers are invalid.
964   @retval EFI_UNSUPPORTED        Unsupported input param.
965   @retval EFI_TIMEOUT            Timeout while waiting xfer.
966   @retval EFI_ABORTED            Controller aborted xfer.
967   @retval EFI_DEVICE_ERROR       Device error detected by controller.
968 
969 **/
970 EFI_STATUS
971 EFIAPI
I2cReadMultipleByte(IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,IN EFI_I2C_ADDR_MODE AddrMode,IN UINTN * WriteLength,IN UINTN * ReadLength,IN OUT VOID * Buffer)972 I2cReadMultipleByte (
973   IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
974   IN        EFI_I2C_ADDR_MODE       AddrMode,
975   IN UINTN                          *WriteLength,
976   IN UINTN                          *ReadLength,
977   IN OUT    VOID                    *Buffer
978   )
979 {
980   EFI_STATUS        Status;
981   UINTN             I2CAddress;
982   UINT16            SaveCmd;
983   UINT32            SaveBar0;
984 
985   if (Buffer == NULL || WriteLength == NULL || ReadLength == NULL) {
986     return EFI_INVALID_PARAMETER;
987   }
988   SaveCmd = 0;
989   SaveBar0 =0;
990 
991   I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
992 
993   Status = EFI_SUCCESS;
994 
995   I2CAddress = SlaveAddress.I2CDeviceAddress;
996   Status = InitializeInternal (AddrMode);
997   if (!EFI_ERROR(Status)) {
998     Status = ReadMultipleByte (I2CAddress, Buffer, (*WriteLength), (*ReadLength));
999   }
1000   I2cCommonServiceExit (SaveCmd, SaveBar0);
1001   return Status;
1002 }
1003 
1004 
1005