]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseSmbusLib/SmbusLib.c
1. BaseSmbusLib: Make SmbusReadDataByte() & SmbusWriteBlock() function well by re...
[mirror_edk2.git] / MdePkg / Library / BaseSmbusLib / SmbusLib.c
index 39fa7e6f375907e5c6e913b48fe41568b968c46a..16ae2fa279c13d19c81a3fe628a7ae1e97308068 100644 (file)
 //\r
 // Replaced by PCD\r
 //\r
-#define ICH_SMBUS_BASE_ADDRESS               0xEFA0\r
+#define ICH_SMBUS_IO_BASE_ADDRESS               0xEFA0\r
 \r
 /**\r
-  Reads an 8-bit SMBUS register on ICH.\r
+  Reads an 8-bit register on ICH SMBUS controller.\r
 \r
   This internal function reads an SMBUS register specified by Offset.\r
 \r
@@ -42,11 +42,11 @@ InternalSmBusIoRead8 (
   IN UINTN      Offset\r
   )\r
 {\r
-  return IoRead8 (ICH_SMBUS_BASE_ADDRESS + Offset);\r
+  return IoRead8 (ICH_SMBUS_IO_BASE_ADDRESS + Offset);\r
 }\r
 \r
 /**\r
-  Writes an 8-bit SMBUS register on ICH.\r
+  Writes an 8-bit register on ICH SMBUS controller.\r
 \r
   This internal function writes an SMBUS register specified by Offset.\r
 \r
@@ -62,7 +62,7 @@ InternalSmBusIoWrite8 (
   IN UINT8      Value\r
   )\r
 {\r
-  return IoWrite8 (ICH_SMBUS_BASE_ADDRESS + Offset, Value);\r
+  return IoWrite8 (ICH_SMBUS_IO_BASE_ADDRESS + Offset, Value);\r
 }\r
 \r
 /**\r
@@ -89,31 +89,29 @@ InternalSmBusAcquire (
     return RETURN_TIMEOUT;\r
   } else if ((HostStatus & SMBUS_B_HOST_BUSY) != 0) {\r
     //\r
-    // Clear Status Register and exit\r
+    // Clear host status register and exit.\r
     //\r
     InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);\r
     return RETURN_TIMEOUT;\r
   }\r
   //\r
-  // Clear byte pointer of 32-byte buffer.\r
-  //\r
-  InternalSmBusIoRead8 (SMBUS_R_HST_CTL);\r
+  // Clear out any odd status information (Will Not Clear In Use).\r
   //\r
-  // Clear BYTE_DONE status\r
-  //\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_BYTE_DONE_STS);\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, HostStatus);\r
   \r
   return RETURN_SUCCESS;\r
 }\r
 \r
 /**\r
-  Waits until the completion of SMBUS transaction.\r
+  Starts the SMBUS transaction and waits until the end.\r
 \r
-  This internal function waits until the transaction of SMBUS is over\r
-  by polling the INTR bit of Host status register.\r
+  This internal function start the SMBUS transaction and waits until the transaction\r
+  of SMBUS is over by polling the INTR bit of Host status register.\r
   If the SMBUS is not available, RETURN_TIMEOUT is returned;\r
   Otherwise, it performs some basic initializations and returns\r
-  RETURN_SUCCESS. \r
+  RETURN_SUCCESS.\r
+  \r
+  @param  HostControl         The Host control command to start SMBUS transaction.\r
 \r
   @retval RETURN_SUCCESS      The SMBUS command was executed successfully.\r
   @retval RETURN_CRC_ERROR    The checksum is not correct (PEC is incorrect).\r
@@ -124,18 +122,21 @@ InternalSmBusAcquire (
 \r
 **/\r
 RETURN_STATUS\r
-InternalSmBusWait (\r
-  VOID \r
+InternalSmBusStart (\r
+  IN  UINT8                   HostControl\r
   )\r
 {\r
   UINT8   HostStatus;\r
   UINT8   AuxiliaryStatus;\r
-  BOOLEAN First;\r
-  First = TRUE;\r
+\r
+  //\r
+  // Set Host Control Register (Initiate Operation, Interrupt disabled).\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, HostControl + SMBUS_B_START);\r
 \r
   do {\r
     //\r
-    // Poll INTR bit of host status register.\r
+    // Poll INTR bit of Host Status Register.\r
     //\r
     HostStatus = InternalSmBusIoRead8 (SMBUS_R_HST_STS);\r
   } while ((HostStatus & (SMBUS_B_INTR | SMBUS_B_ERROR | SMBUS_B_BYTE_DONE_STS)) == 0);\r
@@ -144,11 +145,11 @@ InternalSmBusWait (
     return RETURN_SUCCESS;\r
   }\r
   //\r
-  // Clear error bits of host status register\r
+  // Clear error bits of Host Status Register.\r
   //\r
   InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_ERROR);\r
   //\r
-  // Read auxiliary status register to judge CRC error.\r
+  // Read Auxiliary Status Register to judge CRC error.\r
   //\r
   AuxiliaryStatus = InternalSmBusIoRead8 (SMBUS_R_AUX_STS);\r
   if ((AuxiliaryStatus & SMBUS_B_CRCE) != 0) {\r
@@ -159,64 +160,85 @@ InternalSmBusWait (
 }\r
 \r
 /**\r
-  Executes an SMBUS quick read/write command.\r
+  Executes an SMBUS quick, byte or word command.\r
 \r
-  This internal function executes an SMBUS quick read/write command\r
-  on the SMBUS device specified by SmBusAddress.\r
-  Only the SMBUS slave address field of SmBusAddress is required.\r
+  This internal function executes an SMBUS quick, byte or word commond.\r
   If Status is not NULL, then the status of the executed command is returned in Status.\r
 \r
+  @param  HostControl     The value of Host Control Register to set.  \r
   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
                           SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Value           The byte/word write to the SMBUS.\r
   @param  Status          Return status for the executed command.\r
                           This is an optional parameter and may be NULL.\r
 \r
+  @return The byte/word read from the SMBUS.\r
+\r
 **/\r
-VOID\r
-EFIAPI\r
-InternalSmBusQuick (\r
+UINT16\r
+InternalSmBusNonBlock (\r
+  IN  UINT8                     HostControl,\r
   IN  UINTN                     SmBusAddress,\r
-  OUT RETURN_STATUS             *Status       OPTIONAL\r
+  IN  UINT16                    Value,\r
+  OUT RETURN_STATUS             *Status\r
   )\r
 {\r
-  RETURN_STATUS   ReturnStatus;\r
+  RETURN_STATUS                 ReturnStatus;\r
+  UINT8                         AuxiliaryControl;\r
 \r
+  //\r
+  // Try to acquire the ownership of ICH SMBUS.\r
+  //\r
   ReturnStatus = InternalSmBusAcquire ();\r
   if (RETURN_ERROR (ReturnStatus)) {\r
     goto Done;\r
   }\r
\r
   //\r
-  // Set Command register\r
+  // Set the appropriate Host Control Register and auxiliary Control Register.\r
   //\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, 0);\r
+  AuxiliaryControl = 0;\r
+  if (SMBUS_LIB_PEC (SmBusAddress)) {\r
+    AuxiliaryControl |= SMBUS_B_AAC;\r
+    HostControl      |= SMBUS_B_PEC_EN;\r
+  }\r
+  //\r
+  // Set Host Commond Register.\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));\r
+  //\r
+  // Write value to Host Data 0 and Host Data 1 Registers.\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_D0, (UINT8) Value);\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_D1, (UINT8) (Value >> 8));\r
   //\r
-  // Set Auxiliary Control register\r
+  // Set Auxiliary Control Regiester.\r
   //\r
-  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, 0);\r
+  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, AuxiliaryControl);\r
   //\r
-  // Set SMBus slave address for the device to send/receive from\r
+  // Set SMBUS slave address for the device to send/receive from.\r
   //\r
   InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);\r
   //\r
-  // Set Control Register (Initiate Operation, Interrupt disabled)\r
+  // Start the SMBUS transaction and wait for the end.\r
   //\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, SMBUS_V_SMB_CMD_QUICK + SMBUS_B_START);\r
-\r
+  ReturnStatus = InternalSmBusStart (HostControl);\r
   //\r
-  // Wait for the end\r
+  // Read value from Host Data 0 and Host Data 1 Registers.\r
   //\r
-  ReturnStatus = InternalSmBusWait ();\r
-\r
+  Value  = InternalSmBusIoRead8 (SMBUS_R_HST_D1) << 8;\r
+  Value |= InternalSmBusIoRead8 (SMBUS_R_HST_D0);\r
   //\r
-  // Clear status register and exit\r
+  // Clear Host Status Register and Auxiliary Status Register.\r
   //\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);;\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);\r
+  InternalSmBusIoWrite8 (SMBUS_R_AUX_STS, SMBUS_B_CRCE);\r
 \r
 Done:\r
   if (Status != NULL) {\r
     *Status = ReturnStatus;\r
   }\r
+\r
+  return Value;\r
 }\r
 \r
 /**\r
@@ -248,7 +270,12 @@ SmBusQuickRead (
   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  InternalSmBusQuick (SmBusAddress | SMBUS_B_READ, Status);\r
+  InternalSmBusNonBlock (\r
+    SMBUS_V_SMB_CMD_QUICK,\r
+    SmBusAddress | SMBUS_B_READ,\r
+    0,\r
+    Status\r
+    );\r
 }\r
 \r
 /**\r
@@ -280,88 +307,12 @@ SmBusQuickWrite (
   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  InternalSmBusQuick (SmBusAddress | SMBUS_B_WRITE, Status);\r
-}\r
-\r
-/**\r
-  Executes an SMBUS byte or word command.\r
-\r
-  This internal function executes an .\r
-  Only the SMBUS slave address field of SmBusAddress is required.\r
-  If Status is not NULL, then the status of the executed command is returned in Status.\r
-\r
-  @param  HostControl     The value of Host Control Register to set.  \r
-  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
-                          SMBUS Command, SMBUS Data Length, and PEC.\r
-  @param  Value           The byte/word write to the SMBUS.\r
-  @param  Status          Return status for the executed command.\r
-                          This is an optional parameter and may be NULL.\r
-\r
-  @return The byte/word read from the SMBUS.\r
-\r
-**/\r
-UINT16\r
-InternalSmBusByteWord (\r
-  IN  UINT8                     HostControl,\r
-  IN  UINTN                     SmBusAddress,\r
-  IN  UINT16                    Value,\r
-  OUT RETURN_STATUS             *Status\r
-  )\r
-{\r
-  RETURN_STATUS                 ReturnStatus;\r
-  UINT8                         AuxiliaryControl;\r
-\r
-  ReturnStatus = InternalSmBusAcquire ();\r
-  if (RETURN_ERROR (ReturnStatus)) {\r
-    goto Done;\r
-  }\r
-\r
-  AuxiliaryControl = 0;\r
-  if (SMBUS_LIB_PEC (SmBusAddress)) {\r
-    AuxiliaryControl |= SMBUS_B_AAC;\r
-    HostControl      |= SMBUS_B_PEC_EN;\r
-  }\r
\r
-  //\r
-  // Set commond register\r
-  //\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));\r
-\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_D0, (UINT8) Value);\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_D1, (UINT8) (Value >> 8));\r
-\r
-  //\r
-  // Set Auxiliary Control Regiester.\r
-  //\r
-  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, AuxiliaryControl);\r
-  //\r
-  // Set SMBus slave address for the device to send/receive from.\r
-  //\r
-  InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);\r
-  //\r
-  // Set Control Register (Initiate Operation, Interrupt disabled)\r
-  //\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, HostControl + SMBUS_B_START);\r
-\r
-  //\r
-  // Wait for the end\r
-  //\r
-  ReturnStatus = InternalSmBusWait ();\r
\r
-  Value  = InternalSmBusIoRead8 (SMBUS_R_HST_D1) << 8;\r
-  Value |= InternalSmBusIoRead8 (SMBUS_R_HST_D0);\r
-\r
-  //\r
-  // Clear status register and exit\r
-  //\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);;\r
-\r
-Done:\r
-  if (Status != NULL) {\r
-    *Status = ReturnStatus;\r
-  }\r
-\r
-  return Value;\r
+  InternalSmBusNonBlock (\r
+    SMBUS_V_SMB_CMD_QUICK,\r
+    SmBusAddress | SMBUS_B_WRITE,\r
+    0,\r
+    Status\r
+    );\r
 }\r
 \r
 /**\r
@@ -394,7 +345,7 @@ SmBusReceiveByte (
   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  return (UINT8) InternalSmBusByteWord (\r
+  return (UINT8) InternalSmBusNonBlock (\r
                    SMBUS_V_SMB_CMD_BYTE,\r
                    SmBusAddress | SMBUS_B_READ,\r
                    0,\r
@@ -434,7 +385,7 @@ SmBusSendByte (
   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  return (UINT8) InternalSmBusByteWord (\r
+  return (UINT8) InternalSmBusNonBlock (\r
                    SMBUS_V_SMB_CMD_BYTE,\r
                    SmBusAddress | SMBUS_B_WRITE,\r
                    Value,\r
@@ -470,7 +421,7 @@ SmBusReadDataByte (
   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  return (UINT8) InternalSmBusByteWord (\r
+  return (UINT8) InternalSmBusNonBlock (\r
                    SMBUS_V_SMB_CMD_BYTE_DATA,\r
                    SmBusAddress | SMBUS_B_READ,\r
                    0,\r
@@ -509,7 +460,7 @@ SmBusWriteDataByte (
   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  return (UINT8) InternalSmBusByteWord (\r
+  return (UINT8) InternalSmBusNonBlock (\r
                    SMBUS_V_SMB_CMD_BYTE_DATA,\r
                    SmBusAddress | SMBUS_B_WRITE,\r
                    Value,\r
@@ -545,7 +496,7 @@ SmBusReadDataWord (
   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  return InternalSmBusByteWord (\r
+  return InternalSmBusNonBlock (\r
            SMBUS_V_SMB_CMD_WORD_DATA,\r
            SmBusAddress | SMBUS_B_READ,\r
            0,\r
@@ -584,7 +535,7 @@ SmBusWriteDataWord (
   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  return InternalSmBusByteWord (\r
+  return InternalSmBusNonBlock (\r
            SMBUS_V_SMB_CMD_WORD_DATA,\r
            SmBusAddress | SMBUS_B_WRITE,\r
            Value,\r
@@ -623,7 +574,7 @@ SmBusProcessCall (
   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  return InternalSmBusByteWord (\r
+  return InternalSmBusNonBlock (\r
            SMBUS_V_SMB_CMD_PROCESS_CALL,\r
            SmBusAddress | SMBUS_B_WRITE,\r
            Value,\r
@@ -666,61 +617,77 @@ InternalSmBusBlock (
   UINTN                         Index;\r
   UINTN                         BytesCount;\r
   UINT8                         AuxiliaryControl;\r
-\r
+  \r
   BytesCount = SMBUS_LIB_LENGTH (SmBusAddress);\r
-\r
+  //\r
+  // Try to acquire the ownership of ICH SMBUS.\r
+  //\r
   ReturnStatus = InternalSmBusAcquire ();\r
   if (RETURN_ERROR (ReturnStatus)) {\r
     goto Done;\r
   }\r
-  \r
+  //\r
+  // Set the appropriate Host Control Register and auxiliary Control Register.\r
+  //\r
   AuxiliaryControl = SMBUS_B_E32B;\r
   if (SMBUS_LIB_PEC (SmBusAddress)) {\r
     AuxiliaryControl |= SMBUS_B_AAC;\r
     HostControl      |= SMBUS_B_PEC_EN;\r
   }\r
-\r
+  //\r
+  // Set Host Command Register.\r
+  //\r
   InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));\r
-\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_D0, (UINT8) BytesCount);\r
+  //\r
+  // Set Auxiliary Control Regiester.\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, AuxiliaryControl);\r
+  //\r
+  // Clear byte pointer of 32-byte buffer.\r
+  //\r
+  InternalSmBusIoRead8 (SMBUS_R_HST_CTL);\r
 \r
   if (WriteBuffer != NULL) {\r
+    //\r
+    // Write the number of block to Host Block Data Byte Register.\r
+    //\r
+    InternalSmBusIoWrite8 (SMBUS_R_HST_D0, (UINT8) BytesCount);\r
+    //\r
+    // Write data block to Host Block Data Register.\r
+    //\r
     for (Index = 0; Index < BytesCount; Index++) {\r
       InternalSmBusIoWrite8 (SMBUS_R_HOST_BLOCK_DB, WriteBuffer[Index]);\r
     }\r
   }\r
   //\r
-  // Set Auxiliary Control Regiester.\r
-  //\r
-  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, AuxiliaryControl);\r
-  //\r
-  // Set SMBus slave address for the device to send/receive from\r
+  // Set SMBUS slave address for the device to send/receive from.\r
   //\r
   InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);\r
   //\r
-  // Set Control Register (Initiate Operation, Interrupt disabled)\r
+  // Start the SMBUS transaction and wait for the end.\r
   //\r
-  InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, HostControl + SMBUS_B_START);\r
-\r
-  //\r
-  // Wait for the end\r
-  //\r
-  ReturnStatus = InternalSmBusWait ();\r
+  ReturnStatus = InternalSmBusStart (HostControl);\r
   if (RETURN_ERROR (ReturnStatus)) {\r
     goto Done;\r
   }\r
 \r
-  BytesCount = InternalSmBusIoRead8 (SMBUS_R_HST_D0);\r
   if (ReadBuffer != NULL) {\r
+    //\r
+    // Read the number of block from host block data byte register.\r
+    //\r
+    BytesCount = InternalSmBusIoRead8 (SMBUS_R_HST_D0);\r
+    //\r
+    // Write data block from Host Block Data Register.\r
+    //\r
     for (Index = 0; Index < BytesCount; Index++) {\r
       ReadBuffer[Index] = InternalSmBusIoRead8 (SMBUS_R_HOST_BLOCK_DB);\r
     }\r
   }\r
-\r
   //\r
-  // Clear status register and exit\r
+  // Clear Host Status Register and Auxiliary Status Register.\r
   //\r
   InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);\r
+  InternalSmBusIoWrite8 (SMBUS_R_AUX_STS, SMBUS_B_CRCE);\r
 \r
 Done:\r
   if (Status != NULL) {\r