/*******************************************************************************
 * (c) Copyright 2009-2011 Actel Corporation.  All rights reserved.
 *
 * PMBUS bare metal software driver public API. All the APIs are
 * in master mode.
 *
 * SVN $Revision: 3959 $
 * SVN $Date: 2011-11-15 18:47:30 +0530 (Tue, 15 Nov 2011) $
 */
/*=========================================================================*//**
  @mainpage PMBus Bare Metal Driver.
   The PMBus bare metal software driver supports PMBus operations.

  @section intro_sec Introduction
   The Power Management Bus (“PMBus”) is a standard protocol that defines a
   means of communicating with power conversion and other devices. The PMBus
   driver is an implementation of the protocol layer which interacts with PMBus
   slave devices over I2C bus via Actel CoreI2C or SmartFusion MSS I2C hardware
   IP. This driver is intended for the system where a PMBus master needs to send
   commands to slave devices. All the PMBus read/write call transactions
   initiated by the driver is in master mode. A typical application could include
   a PMBus master and any numbers of slave devices. So, user should create device
   topology using this driver and then perform required power management tasks.
   This driver is dependent on various drivers for performing its operation since
   it is placed at protocol layer.
   This driver has been implemented for the system where no operating system is
   available. However, it can be adapted for use as part of an operating system,
   but the implementation of the adaptation layer between this driver and the
   operating system's driver model is outside the scope of this driver.

   The major features provided by PMBus driver are:
   - A function to add a PMBus slave device in system topology.
   - A function to set page in supported slave device before starting any
     transaction.
   - Functions to read/write data from/to PMBus slave devices using SMBus
     protocol.
   - Functions to send group command to slaves using PMBus protocol.
   - A function to get information of the slave which has generated SMBALERT
     signal.
   - Functions to convert PMBus raw data into direct or linear format and vice
     versa.

  @section hw_dependencies Hardware Flow Dependencies
  PMBus driver uses underlying CoreI2C or SmartFusion MSS I2C hardware to
  communicate to PMBus slave devices. Following diagram shows how the user
  application interacts with PMBus driver in a typical system.
                              ___________________
                             | User Application  |
                             |___________________|
                                      |
                              ________V__________
                             |    PMBus Driver   |
                             |___________________|
                                      |
                              ________V__________
                             | Unified I2C driver|
                             | Abstraction layer |
                             |     ( UI2C DAL)   |
                             |___________________|
                                      |
                              ________V__________
                             |   CoreI2C driver/ |
                             |   MSS I2C Driver  |
                             |___________________|
                                      |
                              ________V__________
                             |    I2C Hardware   |
                             |___________________|

                             PMBus Driver Architecture
  Based on I2C hardware used in the PMBus hardware system design, following
  points must be considered while writing software application:
  PMBus system using MSS I2C hardware
    1. You must ensure that the SmartFusion CMSIS-PAL is either included in the
       software tool chain used to build your project or is included in your
       project.CMSIS-PAL contains register address and interrupts number
       assignments required by driver.
    2. Unified I2C driver abstraction layer (UI2C DAL) driver must be included
       in the driver subdirectory of your project directory. This layer routes
       the PMBus driver API call to SmartFusion MSS I2C driver and subsequently
       to I2C hardware.
    3. You must include SmartFusion MSS I2C driver into driver sub directory
       of your project directory
    4. SmartFusion MSS I2C initialization function should be called before using
       any PMBus driver APIs. Check SmartFusion users’ guide for more details on
       MSS I2C initialization.

  PMBus System using CoreI2C hardware
    1. You must ensure that the HAL (Hardware Abstraction Layer) for Cortex-M3
       is either included in the software tool chain used to build your project
       or is included in your project.
    2. Unified I2C driver abstraction layer (UI2C DAL) driver must be included
       in the driver sub directory of your project directory. This layer routes
       the PMBus driver API call to CoreI2C driver and subsequently to I2C
       hardware.
    3. You must include Core I2C driver into driver sub directory of your
       project directory
    4. CoreI2C initialization function should be called before using any PMBus
       driver APIs. Check SmartFusion users’ guide for more details on MSS I2C
       initialization.
    5. Since Interrupt is important part of CoreI2C hardware IP, you should have
       CoreInterrupt IP configured in the system. In that case, you should
       include CoreInterrupt driver in the project directory.

  @section theory_op Theory of Operation
    The Power Management Bus (PMBus) is a variant of the System Management Bus
    which is targeted at digital management of power supplies. So, a typical
    PMBus application will involve sending different commands to power
    converters and other devices in a power system over I2C bus. The PMBus
    driver is protocol layer driver abstracted well over I2C hardware. This
    can be depicted using PMBus Driver architecture diagram above.

    The PMBus driver APIs can be subdivided in following subsections:
    - Initialization
    - PMBus read/write operations
    - Group Command
    - Interrupt Control
    - PMBus data formats

    Initialization
      Since PMBus based system utilizes SmartFusion MSS I2C or CoreI2C IP as
      underlying hardware, it is necessary to initialize them properly before
      starting any PMBus based transaction.
      Initializing PMBus system using SmartFusion MSS I2C hardware
      - Initialize MSS I2C hardware through a call to the MSS_I2C_init()
        function. This function takes the MSS I2C's configuration as parameters.
        The first parameter of the MSS_I2C_init() function is a pointer to one
        of two global data structures used by the MSS I2C driver to store state
        information for each MSS I2C. The names of these two data structures are
        g_mss_i2c0 and g_mss_i2c1. Based on the system design, either one of
        the MSS I2C hardware will be used as a PMBus master. All the PMBus
        devices support bus speed up to 100 KHz and some device may support bus
        frequency in high speed mode up to 400 KHz. So, appropriate serial clock
        divider should be used in MSS_I2C_init() function as configuration
        parameter to generate its I2C bus clock. Since, MSS I2C hardware is used
        as PMBus master, dummy value can be passed as serial address in the
        MSS_I2C_init() function. Check SmartFusion MSS I2C driver users’ guide
        for more details.
      - Open I2C communication channel corresponding to MSS I2C hardware at
        unified I2C driver abstraction layer (UI2C DAL) by calling
        UI2C_mss_i2c_open() function. Check Unified I2C DAL driver users’
        guide for more details.

      Initializing PMBus system using CoreI2C hardware
      - Initialize CoreI2C hardware through a call to the I2C_init() function.
        It takes base address as one of the parameter, which is configured in
        the system design. This function initializes channel 0 of CoreI2C
        hardware. If another channel is used in the system, I2C_channel_init()
        should also be called in the application.                                                                                                                     
        All the PMBus devices support bus speed up to 100 KHz and some device may support 
        bus frequency in high speed mode up to 400 KHz. So, appropriate serial clock 
        divider should be used in I2C_init() function as configuration parameter to g
        enerate its I2C bus clock. Since, CoreI2C hardware is used as PMBus master, 
        dummy value can be passed as serial address in the I2C_init() function. 
        Check CoreI2C driver users’ guide for more details.
      - Open I2C communication channel corresponding to CoreI2C hardware at
        unified I2C driver abstraction layer (UI2C DAL) by calling
        UI2C_core_i2c_open() function.

      Adding slave devices in the PMBus topology
      - In a typical PMBus system design, there will be a PMBus master managing
        power related operations on any number of power devices. PMBUS_add_slave()
        is called to add each PMBus slaves in the system topology. This function
        takes initialized I2C master channel as one of the parameter. All the
        PMBus slave device specific information is configured and stored in
        pmbus_slave_info_t data structure using this function. The PMBus slave
        information like total supported pages and packet error check (PEC) can
        be obtained from corresponding manufacturer datasheet. The slave serial
        address is also provided using PMBUS_add_slave() function.

    PMBus read/write operations
      PMBus devices use System Management Bus (SMBus) protocol at transport layer
      to send and receive data. Refer to SMBus specification 2.0 for more
      information on SMBus command protocol. PMBus driver provides different
      read/write APIs for different types of commands.
      Following table shows the read/write API list and corresponding bus
      protocol associated with the transfer along with SMBus specification section.

      ------------------------------------------------------------------------------
      Read/Write API            SMBus protocol used        SMBus specification section #
      -------------------------------------------------------------------------------
      PMBUS_send_byte            Send byte                    Spec Section 5.5.2
      PMBUS_read_byte            Read byte                    Spec Section 5.5.5
      PMBUS_write_byte            Write byte                    Spec Section 5.5.5
      PMBUS_read_word            Read word                    Spec Section 5.5.2
      PMBUS_write_word            Write word                    Spec Section 5.5.4
      PMBUS_read_block            Read block                    Spec Section 5.5.7
      PMBUS_write_block            Write block                    Spec Section 5.5.7
      PMBUS_write_read_block    Block write- block
                                  read process call            Spec Section 5.5.8
      ------------------------------------------------------------------------------
      Read/write calls should be made only after proper initialization of PMBus
      system. If PMBus slave devices support PAGE operations, then function
      pmbus_set_page() should be called first to  set the appropriate page address
      before starting read/write function calls. Read/write function calls take
      pmbus_slave_info_t data structure as one of the parameter. This parameter
      includes the PMBus slave information, like PMBus master channel it is
      associated with, serial address, number of supported pages and packet
      error check (PEC). The command which needs to be sent to PMBus slave device
      is passed as parameter to read/write functions. If the command is part
      of extension command PMBus protocol, its information need to be provided
      to the function so that the driver can send command code using PMBus
      transport layer protocol specification. Refer to PMBus specification
      document for more details.
      Since read/write functions operate on different size of data buffer, you
      should make sure to pass correct size of read/write buffers.  For example,
      PMBUS_write_word() should pass write_buffer size of one word to the function
      as one of the parameters.
      PMBUS_read_block(), PMBUS_write_block() and PMBUS_write_read_block() also
      requires block data size as one of the parameter.

    Group Command
      The group command protocol is used to send commands to more than one PMBus
      device. The commands are sent in one continuous transmission. When the
      devices detect the STOP condition that ends the sending of commands, they
      all begin executing the command they received. It is not a requirement
      that all devices receive the same command. No more than one command is
      send to any one device in one Group command packet. The Group command must
      not be used with the commands that require the receiving device to respond
      with data, such as STATUS_BYTE command. Since group command is set of
      different commands to different slave devices, it is first require to
      build a table using PMBUS_add_slave_to_group_tbl(). This table will
      contain the PMBus slave addresses and corresponding command codes which
      they are supposed to receive. Once table is built by entering the details
      of each of the PMBus slaves, PMBUS_send_group_command() is called to
      send the group command.

    Interrupt Control
      There are two interrupts associated with PMBus driver. One related to I2C
      hardware status, which is triggered once there is change in state machine
      due to any I2C transactions. Other is associated with SMBAlert signal,
      which is triggered by slave device to notify host that it wants to talk.
      Status Interrupt
      - PMBus system using CoreI2C hardware - This interrupt is generated at
        INTR hardware pin. So, user must have appropriate connection for the interrupt
        through CoreInterrupt Controller or any other design means. The application
        user should then configure the CoreI2C INTR interrupt handler and call
        I2C_isr() function in the  handler to carry out I2C transactions smoothly.
        Refer to CoreI2C driver users’ guide for more details.
      - PMBus system using SmartFusion MSS I2C hardware - Since SmartFusion have
        fixed interrupt lines, the handlers are part of the MSS I2C driver. User
        doesn’t have to configure hardware or driver for this interrupt.

    SMBAlert Interrupt
      PMBus system using either CoreI2C or SmartFusion MSS I2C
      - SMBAlert Interrupt can be enabled or disabled using unified I2C driver
        abstraction layer function calls UI2C_enable_smbus_irq(),
        UI2C_disable_smbus_irq() respectively. User must write their own interrupt
        handlers for both CoreI2C and SmartFusion MSS I2C for controlling SMBAlert
        signal. SmartFusion MSS I2C ISR routines which should be used in the user
        application will be either I2C0_SMBAlert_IRQHandler() or
        I2C1_SMBAlert_IRQHandler() based on which MSS I2C channel is selected as
        PMBus master. While, the method of controlling the CoreI2C SMBAlert interrupt
        is system specific, it is left to user to write its own handlers. If there
        are more than one PMBus slave device in the system, the driver provides
        PMBUS_get_smbalert_source() to figure out the slave source which has
        triggered the interrupt.

    PMBus data formats
      PMBus specification supports Linear and Direct data format of commands.
      If linear or direct format is supported by PMBus slave, then user must
      retrieve the appropriate coefficients from PMBus device before starting
      any write transactions. After coefficient is received from PMBus slave
      device, raw data must be converted to the required format using
      PMBUS_get_linear_format_data() or PMBUS_get_direct_format_data(). This
      converted data will be used to send the data over the PMBus channel
      through required write calls. If data is read from PMBus device and the
      command supports linear or direct formatting, it is required to convert
      data into actual raw format using PMBUS_get_data_from_direct_frmt() or
      PMBUS_get_data_from_linear_frmt().

  *//*=========================================================================*/
#ifndef __PMBUS_H_
#define __PMBUS_H_

#include "../ui2c_dal/ui2c_dal.h"

#ifdef __cplusplus
extern "C" {
#endif

/*-------------------------------------------------------------------------*//**
  Constant used for Linear formatted commands. It is used by
  PMBUS_get_linear_format_data() and PMBUS_get_data_from_linear_frmt() functions
 */
#define PMBUS_VOUT_LINEAR_FORMAT 0u
#define PMBUS_LINEAR_FORMAT      1u

/*-------------------------------------------------------------------------*//**
  The pmbus_error_code_t type is used to report the error returned by any
  PMBUS driver function. The functions related to command handling will
  return either of the following:
   - PMBUS_WRITE_SUCCESS
   - PMBUS_READ_SUCCESS
   - PMBUS_WRITE_FAILURE
   - PMBUS_READ_FAILURE.
  In other cases, PMBUS_SUCCESS is returned to indicate success of the function
  call or PMBUS_FAILURE is returned if something has gone wrong inside the
  function call.
 */
typedef enum pmbus_error_code
{
    PMBUS_INVALID,
    PMBUS_WRITE_SUCCESS,
    PMBUS_WRITE_FAILURE,
    PMBUS_READ_SUCCESS,
    PMBUS_READ_FAILURE,
    PMBUS_SUCCESS,
    PMBUS_FAILURE
}pmbus_error_code_t;

/*-------------------------------------------------------------------------*//**
  The pmbus_command_type_t type is used to specify PMBUS command data type.
  PMBUS can read /write data using byte, word or block based commands. Send
  command type is used where single message as control command is send over
  PMBus. For example, PMBUS_SEND_TYPE is used for CLEAR_FAULTS PMBUS command.
  Please refer SMBus specification 2.0 for more details.
 */
typedef enum pmbus_command_type
{
    PMBUS_SEND_TYPE ,
    PMBUS_BYTE_TYPE ,
    PMBUS_WORD_TYPE ,
    PMBUS_BLOCK_TYPE
}pmbus_command_type_t;

/*-------------------------------------------------------------------------*//**
  The pmbus_slave_info_t contains the information of the PMBUS slave device.
  The PMBus slave information like total supported pages and packet error
  check (PEC) can be obtained from corresponding manufacturer datasheet. The
  slave address is configurable and set based on the system design. Each
  PMBus slave is associated with the PMBus master, which will send commands
  to the device. PMBus master channel information is also stored in this
  structure. These PMBus slave device specific information are stored during
  PMBUS_add_slave() function call. This structure is used in most of the
  driver functions.
 */
typedef struct pmbus_slave_info
{
    /* I2C channel to which this slave is associated */
    ui2c_channel_t * i2c_channel;

    /* Total pages supported by slave device */
    uint8_t total_supported_pages;

    /* Slave address which will be used to address the slave */
    uint8_t slave_address;

    /* PEC supported by the slave */
    uint8_t is_pec_supported ;

    /* User specific data*/
    void *p_user_data;

}pmbus_slave_info_t;

/*-------------------------------------------------------------------------*//**
  The pmbus_command_info_t stores the information of the specific PMBUS command.
  This includes command code and whether the command is a part of extended
  command. The support for extended command is to provide manufacturer specific
  commands if user runs short of command code in general 256 command lists.
  It also includes command type which can be PMBUS_SEND_TYPE,
  PMBUS_BYTE_TYPE, PMBUS_WORD_TYPE and PMBUS_BLOCK_TYPE. The size of each
  command is specified as one of the data element of this structure.
 */
typedef struct command_info
{
    uint8_t command_code;
    uint8_t is_extended_command;
    pmbus_command_type_t  cmd_type;
    uint8_t command_size ;
}pmbus_command_info_t;

/*-------------------------------------------------------------------------*//**
  The pmbus_group_cmd_info_t specifies the PMBUS group command information.
  The group command protocol is used to send commands to more than one
  PMBus device. The commands are sent in one continuous transmission. When
  the devices detect the STOP condition that ends the sending of commands,
  they all begin executing the command they received. The command code provided
  should not expect slave to respond with data. Essentially, the command
  should be only write transaction type, not process or read call. The
  pmbus_group_cmd_info_t structure holds PMBus slave information, command
  code and data buffer to be written to the slave. This structure is used by
  PMBUS_add_slave_to_group_tbl() and PMBUS_send_group_command() functions.
 */
typedef struct pmbus_group_cmd_info
{
    /* Slave information */
    pmbus_slave_info_t pmbus_slave_instance;

    /* PMBUS command information */
    pmbus_command_info_t cmd_info ;

    /* Data to be written */
    uint8_t *write_buffer;

}pmbus_group_cmd_info_t;

/*-------------------------------------------------------------------------*//**
   This function adds PMBus slave device to the bus topology. The
   pmbus_slave_info_t parameter stores the information of the PMBus slave
   device. The PMBus slave information like total supported pages and packet
   error check (PEC) can be obtained from corresponding manufacturer datasheet.
   These parameters are configured through this function. The slave address
   is set using this function based on the system design. Each PMBus slave
   is associated with a PMBus master, which will send commands to the device.
   PMBus master channel information is stored in pmbus_slave_info_t structure
   by passing initialized unified I2C channel parameter. The driver also
   provides provision to the user to specify its own information using void
   pointer to user_data parameter.

   @param i2c_channel
     The i2c_channel parameter is a pointer to ui2c_channel_t structure
     specifying I2C hardware channel, which can be either MSS I2C or CoreI2C
     hardware.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param user_data
     The user data parameter of type void pointer contains user specific
     information.

   @param total_supported_page
     The total_supported_page parameter is total number of pages supported
     by PMBUS slave. Refer to PMBUS device datasheet to find out total
     number of pages. If paging is supported, PAGE command should
     also be provided by the device.

   @param slave_addr
     The slave_addr parameter is slave address of target PMBUS device.

   @param pec_support
     The pec_support parameter specifies if Packet Error check (PEC)
     is supported by the device.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_SUCCESS else
     PMBUS_FAILURE.

   Example
   @code
     #define PMBUS_SLAVE_ADDRESS          0x10u
     #define COREI2C_BASE_ADDR      0xC0000000u
     #define PMBUS_TOTAL_PAGE_SUPPORTED      0u

     pmbus_slave_info_t pmbus_slave_inst;
     ui2c_channel_t i2c_channel;
     i2c_instance_t core_i2c_inst ;

     void main()
     {
         I2C_init
         (
             &core_i2c_inst,
             COREI2C_BASE_ADDR,
             PMBUS_MASTER_ADDRESS,
             I2C_PCLK_DIV_256
         ) ;
         UI2C_core_i2c_open ( &i2c_channel, &core_i2c_inst);
         // Add PMBUS slave related information
         uint8_t user_data;
         PMBUS_add_slave
         (
              &i2c_channel,
              &pmbus_slave_inst,
              &user_data,
              PMBUS_TOTAL_PAGE_SUPPORTED,
              PMBUS_SLAVE_ADDRESS,
              0 // PEC is not supported
         );
     }
   @endcode
 */
pmbus_error_code_t
PMBUS_add_slave
(
    ui2c_channel_t *i2c_channel,
    pmbus_slave_info_t *pmbus_slave_instance,
    void *user_data,
    uint8_t total_supported_page,
    uint8_t slave_addr,
    uint8_t pec_support
);

/*-------------------------------------------------------------------------*//**
   This function sets page number to current value. This function is only
   required when page is supported by slave device. If page is supported
   by device, user must set the page to appropriate value before
   starting any read / write transaction on PMBUS slave device.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param page_number
     The page_number parameter specifies the page to which any read/write
     operations are intended.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_SUCCESS else
     PMBUS_FAILURE.

   Example
   @code
     #define PMBUS_SLAVE_ADDRESS          0x10u
     #define COREI2C_BASE_ADDR      0xC0000000u
     #define PMBUS_TOTAL_PAGE_SUPPORTED      8u
     #define PMBUS_PAGE_1                    1u
     #define PAGE_PAGE_2                     2u
     #define CLEAR_FAULTS                 0x03u

     pmbus_slave_info_t pmbus_slave_inst;
     ui2c_channel_t i2c_channel;
     i2c_instance_t core_i2c_inst ;

     void main()
     {
         pmbus_error_code_t  error_code ;
         uint8_t page_number ;

         I2C_init
         (
             &core_i2c_inst,
             COREI2C_BASE_ADDR,
             PMBUS_MASTER_ADDRESS,
             I2C_PCLK_DIV_256
         ) ;
         UI2C_core_i2c_open ( &i2c_channel, &core_i2c_inst);
         // Add PMBUS slave related information
         uint8_t user_data;
         PMBUS_add_slave
         (
              &i2c_channel,
              &pmbus_slave_inst,
              &user_data,
              PMBUS_TOTAL_PAGE_SUPPORTED,
              PMBUS_SLAVE_ADDRESS,
              0 // PEC is not supported
         );
          page_number = PMBUS_PAGE_1 ;
         // Set page number to PMBUS_PAGE_1 (1)
         error_code = PMBUS_set_page (&pmbus_slave_inst,page_number);
         // Command CLEAR_FAULTS is send to page 1
         error_code = PMBUS_send_byte (&pmbus_slave_inst, CLEAR_FAULTS );

         page_number = PMBUS_PAGE_2 ;
         // Set page number to PMBUS_PAGE_2 (2)
         error_code = PMBUS_set_page (&pmbus_slave_inst,page_number);
         // Command CLEAR_FAULTS is send to page 2
         error_code = PMBUS_send_byte ( &pmbus_slave_inst, CLEAR_FAULTS );
     }
   @endcode
 */
pmbus_error_code_t
PMBUS_set_page
(
    pmbus_slave_info_t *pmbus_slave_instance,
    uint8_t page_number
);

/*-------------------------------------------------------------------------*//**
   This function sends a byte command to PMBus slave. Refer to SMBUS
   specification section 5.5.2 for more details.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param command_code
     The command_code parameter specifies the command to be sent to
     PMBus slave.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_WRITE_SUCCESS else
     PMBUS_WRITE_FAILURE.

   Example
   @code
     #define PMBUS_SLAVE_ADDRESS          0x10u
     #define COREI2C_BASE_ADDR      0xC0000000u
     #define PMBUS_TOTAL_PAGE_SUPPORTED      0u
     #define CLEAR_FAULTS                 0x03u

     pmbus_slave_info_t pmbus_slave_inst;
     ui2c_channel_t i2c_channel;
     i2c_instance_t core_i2c_inst ;

     void main()
     {
         pmbus_error_code_t  error_code ;

         I2C_init
         (
             &core_i2c_inst,
             COREI2C_BASE_ADDR,
             PMBUS_MASTER_ADDRESS,
             I2C_PCLK_DIV_256
         ) ;
         UI2C_core_i2c_open ( &i2c_channel, &core_i2c_inst);
         // Add PMBUS slave related information
         uint8_t user_data;
         PMBUS_add_slave
         (
              &i2c_channel,
              &pmbus_slave_inst,
              &user_data,
              PMBUS_TOTAL_PAGE_SUPPORTED,
              PMBUS_SLAVE_ADDRESS,
              0 // PEC is not supported
         );
         // Send CLEAR_FAULT command
        error_code=PMBUS_send_byte ( &pmbus_slave_inst, CLEAR_FAULTS );
     }
   @endcode
 */
pmbus_error_code_t
PMBUS_send_byte
(
    pmbus_slave_info_t *pmbus_slave_instance,
    uint8_t command_code
);

/*-------------------------------------------------------------------------*//**
   This function reads a byte command from PMBus slave. A call to this function
   is made only for one byte data commands. Refer to SMBUS specification
   section 5.5.5 for more details.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param command_code
     The command_code parameter specifies the command to be sent to
     PMBus slave.

   @param is_extended_command
     The is_extended_command parameter specifies whether this command
     is manufacture specific and beyond 256 commands. Set 1, if
     this is an extended command else leave as 0.

   @param read_buffer
     The read_buffer parameter is buffer in which data is read back
     from the PMBus device. If PEC is supported, the read buffer should
     be of two byte size, else only one byte.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_READ_SUCCESS else
     PMBUS_READ_FAILURE.

   Example
   @code
     #define PMBUS_SLAVE_ADDRESS          0x10u
     #define COREI2C_BASE_ADDR      0xC0000000u
     #define PMBUS_TOTAL_PAGE_SUPPORTED      0u
     #define PEC_SUPPORTED                   1u
     #define ON_OFF_CONFIG_CMD            0x02u
     #define IS_EXTENDED_CMD                 0u

     pmbus_slave_info_t pmbus_slave_inst;
     ui2c_channel_t i2c_channel;
     i2c_instance_t core_i2c_inst ;

     void main()
     {
         pmbus_error_code_t  error_code ;
         uint8_t  read_buffer[WORD_SIZE]; // As PEC is supported

         I2C_init
         (
             &core_i2c_inst,
             COREI2C_BASE_ADDR,
             PMBUS_MASTER_ADDRESS,
             I2C_PCLK_DIV_256
         ) ;
         UI2C_core_i2c_open ( &i2c_channel, &core_i2c_inst);
         // Add PMBUS slave related information
         uint8_t user_data;
         PMBUS_add_slave
         (
              &i2c_channel,
              &pmbus_slave_inst,
              &user_data,
              PMBUS_TOTAL_PAGE_SUPPORTED,
              PMBUS_SLAVE_ADDRESS,
              0 // PEC is not supported
         );
         // Read ON_OFF_CONFIG_CMD command
         error_code= PMBUS_read_byte
                     (
                         &pmbus_slave_inst,
                         ON_OFF_CONFIG_CMD,
                         IS_EXTENDED_CMD,
                         read_buffer
                      );

         if( error_code == PMBUS_READ_SUCCESS)
         {
             // Read byte command is successfully executed
         }
         else
         {
            // Read byte command failed.
         }
     }
   @endcode
 */
pmbus_error_code_t
PMBUS_read_byte
(
    pmbus_slave_info_t *pmbus_slave_instance,
    uint8_t command_code,
    uint8_t is_extended_command,
    uint8_t *read_buffer
);

/*-------------------------------------------------------------------------*//**
   This function writes a byte command to PMBus slave. A call to this function
   is made only for one byte data commands. Refer to SMBUS specification
   section 5.5.4 for more details.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param command_code
     The command_code parameter specifies the command to be sent to
     PMBus slave.

   @param is_extended_command
     The is_extended_command parameter specifies whether this command
     is manufacture specific and beyond 256 commands. Set 1, if
     this is an extended command else leave as 0.

   @param write_buffer
     The write_buffer parameter is buffer which is send to PMBus
     slave device.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_WRITE_SUCCESS else
     PMBUS_WRITE_FAILURE.

   Example
   @code
     #define PMBUS_SLAVE_ADDRESS          0x10u
     #define COREI2C_BASE_ADDR      0xC0000000u
     #define PMBUS_TOTAL_PAGE_SUPPORTED      0u
     #define PEC_SUPPORTED                   1u
     #define ON_OFF_CONFIG_CMD            0x02u
     #define IS_EXTENDED_CMD                 0u

     pmbus_slave_info_t pmbus_slave_inst;
     ui2c_channel_t i2c_channel;
     i2c_instance_t core_i2c_inst ;

     void main()
     {
         pmbus_error_code_t  error_code ;
         uint8_t  write_buffer[BYTE_SIZE] = {0x10};

         I2C_init
         (
             &core_i2c_inst,
             COREI2C_BASE_ADDR,
             PMBUS_MASTER_ADDRESS,
             I2C_PCLK_DIV_256
         ) ;
         UI2C_core_i2c_open ( &i2c_channel, &core_i2c_inst);
         // Add PMBUS slave related information
         uint8_t user_data;
         PMBUS_add_slave
         (
              &i2c_channel,
              &pmbus_slave_inst,
              &user_data,
              PMBUS_TOTAL_PAGE_SUPPORTED,
              PMBUS_SLAVE_ADDRESS,
              0 // PEC is not supported
         );
         // Write ON_OFF_CONFIG_CMD command
         error_code= PMBUS_write_byte
                     (
                         &pmbus_slave_inst,
                         ON_OFF_CONFIG_CMD,
                         IS_EXTENDED_CMD,
                         write_buffer
                      );

         if( error_code == PMBUS_WRITE_SUCCESS)
         {
             // Write byte command is successfully executed
         }
         else
         {
            // Write byte command failed.
         }
     }
   @endcode
 */
pmbus_error_code_t
PMBUS_write_byte
(
    pmbus_slave_info_t *pmbus_slave_instance,
    uint8_t command_code,
    uint8_t is_extended_command,
    const uint8_t *write_buffer
);

/*-------------------------------------------------------------------------*//**
   This function reads a word command from PMBus slave. A call to this function
   is made only for one word data commands. Refer to SMBUS specification
   section 5.5.5 for more details.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param command_code
     The command_code parameter specifies the command to be sent to
     PMBus slave.

   @param is_extended_command
     The is_extended_command parameter specifies whether this command
     is manufacture specific and beyond 256 commands. Set 1, if
     this is an extended command else leave as 0.

   @param read_buffer
     The read_buffer parameter is buffer in which data is read back
     from the PMBus device. If PEC is supported, the read buffer should
     be of three byte size, else one word ( two byte).

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_READ_SUCCESS else
     PMBUS_READ_FAILURE.

   Example
   @code
     #define PMBUS_SLAVE_ADDRESS          0x10u
     #define COREI2C_BASE_ADDR      0xC0000000u
     #define PMBUS_TOTAL_PAGE_SUPPORTED      0u
     #define PEC_SUPPORTED                   0u
     #define VOUT_CMD                     0x21u
     #define IS_EXTENDED_CMD                 0u

     pmbus_slave_info_t pmbus_slave_inst;
     ui2c_channel_t i2c_channel;
     i2c_instance_t core_i2c_inst ;

     void main()
     {
         pmbus_error_code_t  error_code ;
         uint8_t  read_buffer[WORD_SIZE]; // As PEC not supported

         I2C_init
         (
             &core_i2c_inst,
             COREI2C_BASE_ADDR,
             PMBUS_MASTER_ADDRESS,
             I2C_PCLK_DIV_256
         ) ;
         UI2C_core_i2c_open ( &i2c_channel, &core_i2c_inst);
         // Add PMBUS slave related information
         uint8_t user_data;
         PMBUS_add_slave
         (
              &i2c_channel,
              &pmbus_slave_inst,
              &user_data,
              PMBUS_TOTAL_PAGE_SUPPORTED,
              PMBUS_SLAVE_ADDRESS,
              0 // PEC is not supported
         );
         // Read VOUT_CMD command
         error_code= PMBUS_read_word
                     (
                         &pmbus_slave_inst,
                         VOUT_CMD,
                         IS_EXTENDED_CMD,
                         read_buffer
                      );

         if( error_code == PMBUS_READ_SUCCESS)
         {
             // Read word command is successfully executed
         }
         else
         {
            // Read word command failed.
         }
     }
   @endcode
 */
pmbus_error_code_t
PMBUS_read_word
(
    pmbus_slave_info_t *pmbus_slave_instance,
    uint8_t command_code,
    uint8_t is_extended_command,
    uint8_t *read_buffer
);

/*-------------------------------------------------------------------------*//**
   This function writes a word command to PMBus slave. A call to this function
   is made only for one word data commands. Refer to SMBUS specification
   section 5.5.4 for more details.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param command_code
     The command_code parameter specifies the command to be sent to
     PMBus slave.

   @param is_extended_command
     The is_extended_command parameter specifies whether this command
     is manufacture specific and beyond 256 commands. Set 1, if
     this is an extended command else leave as 0.

   @param write_buffer
     The write_buffer parameter is buffer which is send to PMBus
     slave device.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_WRITE_SUCCESS else
     PMBUS_WRITE_FAILURE.

   Example
   @code
     #define PMBUS_SLAVE_ADDRESS          0x10u
     #define COREI2C_BASE_ADDR      0xC0000000u
     #define PMBUS_TOTAL_PAGE_SUPPORTED      0u
     #define PEC_SUPPORTED                   1u
     #define VOUT_CMD                     0x21u
     #define IS_EXTENDED_CMD                 0u

     pmbus_slave_info_t pmbus_slave_inst;
     ui2c_channel_t i2c_channel;
     i2c_instance_t core_i2c_inst ;

     void main()
     {
         pmbus_error_code_t  error_code ;
         uint8_t  write_buffer[WORD_SIZE] = {0x10,0x11};

         I2C_init
         (
             &core_i2c_inst,
             COREI2C_BASE_ADDR,
             PMBUS_MASTER_ADDRESS,
             I2C_PCLK_DIV_256
         ) ;
         UI2C_core_i2c_open ( &i2c_channel, &core_i2c_inst);
         // Add PMBUS slave related information
         uint8_t user_data;
         PMBUS_add_slave
         (
              &i2c_channel,
              &pmbus_slave_inst,
              &user_data,
              PMBUS_TOTAL_PAGE_SUPPORTED,
              PMBUS_SLAVE_ADDRESS,
              0 // PEC is not supported
         );
         // Write VOUT_CMD command
         error_code= PMBUS_write_word
                     (
                         &pmbus_slave_inst,
                         VOUT_CMD,
                         IS_EXTENDED_CMD,
                         write_buffer
                      );

         if( error_code == PMBUS_WRITE_SUCCESS)
         {
             // Write word command is successfully executed
         }
         else
         {
            // Write word command failed.
         }
     }
   @endcode
 */
pmbus_error_code_t
PMBUS_write_word
(
    pmbus_slave_info_t *pmbus_slave_instance,
    uint8_t command_code,
    uint8_t is_extended_command,
    const uint8_t *write_buffer
);

/*-------------------------------------------------------------------------*//**
   This function reads a block command from PMBus slave. A call to this function
   is made only for block data commands. Refer to SMBUS specification
   section 5.5.7 for more details.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param command_code
     The command_code parameter specifies the command to be sent to
     PMBus slave.

   @param is_extended_command
     The is_extended_command parameter specifies whether this command
     is manufacture specific and beyond 256 commands. Set 1, if
     this is an extended command else leave as 0.

   @param read_buffer
     The read_buffer parameter is buffer in which data is read back
     from the PMBus device. If PEC is supported, the read buffer should
     be of 2 byte more than size specified by the command, else
     one byte more than size. (as block command reads size of
     command in one of the byte.)

   @param size
     The size parameter is the block command size.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_READ_SUCCESS else
     PMBUS_READ_FAILURE.

   Example
   @code
     #define PMBUS_SLAVE_ADDRESS          0x10u
     #define COREI2C_BASE_ADDR      0xC0000000u
     #define PMBUS_TOTAL_PAGE_SUPPORTED      0u
     #define PEC_SUPPORTED                   0u
     #define USER_DATA_00_CMD             0xB0u
     #define IS_EXTENDED_CMD                 0u
     #define BLOCK_SIZE                      8u

     pmbus_slave_info_t pmbus_slave_inst;
     ui2c_channel_t i2c_channel;
     i2c_instance_t core_i2c_inst ;

     void main()
     {
         pmbus_error_code_t  error_code ;
         uint8_t  read_buffer[BLOCK_SIZE+1u]; // As PEC not supported

         I2C_init
         (
             &core_i2c_inst,
             COREI2C_BASE_ADDR,
             PMBUS_MASTER_ADDRESS,
             I2C_PCLK_DIV_256
         ) ;
         UI2C_core_i2c_open ( &i2c_channel, &core_i2c_inst);
         // Add PMBUS slave related information
         uint8_t user_data;
         PMBUS_add_slave
         (
              &i2c_channel,
              &pmbus_slave_inst,
              &user_data,
              PMBUS_TOTAL_PAGE_SUPPORTED,
              PMBUS_SLAVE_ADDRESS,
              0 // PEC is not supported
         );
         // Read USER_DATA_00_CMD command
         error_code= PMBUS_read_block
                     (
                         &pmbus_slave_inst,
                         USER_DATA_00_CMD,
                         IS_EXTENDED_CMD,
                         read_buffer,
                         BLOCK_SIZE
                      );

         if( error_code == PMBUS_READ_SUCCESS)
         {
             // Read block command is successfully executed
         }
         else
         {
            // Read block command failed.
         }
     }
   @endcode
 */
pmbus_error_code_t
PMBUS_read_block
(
    pmbus_slave_info_t *pmbus_slave_instance,
    uint8_t command_code,
    uint8_t is_extended_command,
    uint8_t *read_buffer,
    uint8_t size
);

/*-------------------------------------------------------------------------*//**
   This function writes a block command to PMBus slave. A call to this function
   is made only for block data commands. Refer to SMBUS specification
   section 5.5.7 for more details.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param command_code
     The command_code parameter specifies the command to be sent to
     PMBus slave.

   @param is_extended_command
     The is_extended_command parameter specifies whether this command
     is manufacture specific and beyond 256 commands. Set 1, if
     this is an extended command else leave as 0.

   @param write_buffer
     The write_buffer parameter is buffer which is send to PMBus
     slave device.

   @param size
     The size parameter is the block command size.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_WRITE_SUCCESS else
     PMBUS_WRITE_FAILURE.

   Example
   @code
     #define PMBUS_SLAVE_ADDRESS          0x10u
     #define COREI2C_BASE_ADDR      0xC0000000u
     #define PMBUS_TOTAL_PAGE_SUPPORTED      0u
     #define PEC_SUPPORTED                   1u
     #define USER_DATA_00_CMD             0xB0u
     #define IS_EXTENDED_CMD                 0u
     #define BLOCK_SIZE                      5u

     pmbus_slave_info_t pmbus_slave_inst;
     ui2c_channel_t i2c_channel;
     i2c_instance_t core_i2c_inst ;

     void main()
     {
         pmbus_error_code_t  error_code ;
         uint8_t  write_buffer[BLOCK_SIZE]
                   = {0x10,0x11,0x12,0x13,0x14};

         I2C_init
         (
             &core_i2c_inst,
             COREI2C_BASE_ADDR,
             PMBUS_MASTER_ADDRESS,
             I2C_PCLK_DIV_256
         ) ;
         UI2C_core_i2c_open ( &i2c_channel, &core_i2c_inst);
         // Add PMBUS slave related information
         uint8_t user_data;
         PMBUS_add_slave
         (
              &i2c_channel,
              &pmbus_slave_inst,
              &user_data,
              PMBUS_TOTAL_PAGE_SUPPORTED,
              PMBUS_SLAVE_ADDRESS,
              0 // PEC is not supported
         );
         // Write USER_DATA_00_CMD command
         error_code= PMBUS_write_block
                     (
                         &pmbus_slave_inst,
                         USER_DATA_00_CMD,
                         IS_EXTENDED_CMD,
                         write_buffer,
                         BLOCK_SIZE
                      );

         if( error_code == PMBUS_WRITE_SUCCESS)
         {
             // Write block command is successfully executed
         }
         else
         {
            // Write block command failed.
         }
     }
   @endcode
 */
pmbus_error_code_t
PMBUS_write_block
(
    pmbus_slave_info_t *pmbus_slave_instance,
    uint8_t command_code,
    uint8_t is_extended_command,
    const uint8_t *write_buffer,
    uint8_t size
);

/*-------------------------------------------------------------------------*//**
   This function block write-block read process call command to PMBus slave.
   Refer to SMBUS specification section 5.5.8 for more details.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param command_code
     The command_code parameter specifies the command to be sent to
     PMBus slave.

   @param is_extended_command
     The is_extended_command parameter specifies whether this command
     is manufacture specific and beyond 256 commands. Set 1, if
     this is an extended command else leave as 0.

   @param write_buffer
     The write_buffer parameter is buffer which is send to PMBus slave device.

   @param write_size
     The write_size parameter is the command write size.

   @param read_buffer
     The read_buffer parameter is buffer which is used to receive
     data from PMBus slave device.

   @param read_size
     The read_size parameter is the command read size.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_SUCCESS else
     PMBUS_READ_FAILURE or PMBUS_WRITE_FAILURE.
 */
pmbus_error_code_t
PMBUS_write_read_block
(
    pmbus_slave_info_t *pmbus_slave_instance,
    uint8_t command_code,
    uint8_t is_extended_command,
    uint8_t *write_buffer,
    uint8_t write_size,
    uint8_t *read_buffer,
    uint8_t read_size
);

/*-------------------------------------------------------------------------*//**
   This function updates slave information along with command and data
   buffer in group command table.

   @param i2c_channel
     The i2c_channel parameter is a pointer to ui2c_channel_t structure
     specifying I2C hardware channel, which can be either MSS I2C or CoreI2C
     hardware.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param cmd_info
     The cmd_info parameter of type pmbus_command_info_t  specifies the command
     related information.

   @param write_buffer
     The write_buffer parameter is buffer which is send to PMBus
     slave device.

   @param group_command_table
     The group_command_table parameter is pointer to group command table
     of type pmbus_group_cmd_info_t.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_SUCCESS else
     PMBUS_FAILURE.

   Example
   @code
     #define COREI2C_BASE_ADDR      0xC0000000u
     #define PMBUS_TOTAL_PAGE_SUPPORTED      0u
     #define PEC_SUPPORTED                   0u
     #define VOUT_MARGIN_HIGH_CMD         0x21u
     #define IS_EXTENDED_CMD                 0u
     #define NUMBER_OF_SLAVES                5u

     pmbus_slave_info_t pmbus_slave_inst[NUMBER_OF_SLAVES];
     uint8_t pmbus_slave_address[NUMBER_OF_SLAVES] =
                                 {0x10,0x12,0x14,0x16,0x18};

     ui2c_channel_t i2c_channel;
     i2c_instance_t core_i2c_inst ;

     void main()
     {
        uint8_t inc ;
        pmbus_command_info_t cmd_info ;
        pmbus_group_cmd_info_t group_cmd_tbl[NUMBER_OF_SLAVES];
        pmbus_error_code_t  error_code ;

        uint8_t write_buffer[NUMBER_OF_SLAVES][WORD_SIZE] =
                             { // random values
                               { 0x10, 0x11},
                               { 0x12, 0x13},
                               { 0x14, 0x15},
                               { 0x16, 0x17},
                               { 0x18, 0x19}
                             };
         I2C_init
         (
             &core_i2c_inst,
             COREI2C_BASE_ADDR,
             PMBUS_MASTER_ADDRESS,
             I2C_PCLK_DIV_256
         ) ;

         UI2C_core_i2c_open ( &i2c_channel, &core_i2c_inst);

         // Sends same command to all the device
         cmd_info.command_code =  VOUT_MARGIN_HIGH_CMD ;
         cmd_info.is_extended_command = 0;
         cmd_info.cmd_type = PMBUS_WORD_TYPE;
         cmd_info.command_size = WORD_SIZE;

         for( inc = 0 ; inc <NUMBER_OF_SLAVES; inc++)
         {
             PMBUS_add_slave
             (
                  &i2c_channel,
                  (pmbus_slave_inst+inc),
                  &user_data,
                  PMBUS_TOTAL_PAGE_SUPPORTED,
                  pmbus_slave_address[inc],
                  PEC_SUPPORTED // PEC is not supported for all device
             );

             error_code = PMBUS_add_slave_to_group_tbl
                          (
                             &i2c_channel,
                             (pmbus_slave_inst+inc),
                             &cmd_info,
                             write_buffer[inc],
                             group_cmd_tbl
                          );
         }
     }
   @endcode
 */
pmbus_error_code_t
PMBUS_add_slave_to_group_tbl
(
    ui2c_channel_t *i2c_channel,
    pmbus_slave_info_t *pmbus_slave_instance,
    pmbus_command_info_t *cmd_info,
    uint8_t *write_buffer,
    pmbus_group_cmd_info_t *group_command_table
);

/*-------------------------------------------------------------------------*//**
   This function updates slave information along with command and data
   buffer in group command table.

   @param group_command_table
     The group_command_table parameter is pointer to group command table
     of type pmbus_group_cmd_info_t.

   @return
     This function returns error code of type pmbus_error_code_t.
     If the operation is successful, it returns PMBUS_SUCCESS else
     PMBUS_FAILURE.

   Example
   @code
     // Assume group command table is updated using PMBUS_add_slave_to_group_tbl
     // function to group_command_table. All the slaves updated its
     // information.
      pmbus_error_code_t error_code = PMBUS_send_group_command
                                        {
                                          group_command_table
                                        };
   @endcode
 */
pmbus_error_code_t
PMBUS_send_group_command
(
    const pmbus_group_cmd_info_t *group_command_table
);

/*-------------------------------------------------------------------------*//**
   This function returns the slave device address which has triggered
   SMBAlert Signal. If more than one device pulls SMBALERT low, the highest
   priority (lowest address) device will win communication rights via standard
   arbitration during the slave address transfer. So, this function returns
   lowest address device which has generated SMB Alert signal.

   @param i2c_channel
     The i2c_channel parameter is a pointer to ui2c_channel_t structure
     specifying I2C hardware channel, which can be either MSS I2C or CoreI2C
     hardware.

   @return
     This function returns lowest device addressed PMBus slave pointer.
 */
pmbus_slave_info_t *
PMBUS_get_smbalert_source
(
    ui2c_channel_t * i2c_channel
);

/*-------------------------------------------------------------------------*//**
   This function sets user data.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @param user_data
     The user data parameter of type void pointer contains user specific
     information.

   @return
     This function returns nothing.
 */
void
PMBUS_set_user_data
(
    pmbus_slave_info_t *pmbus_slave_instance,
    void *user_data
);

/*-------------------------------------------------------------------------*//**
   This function returns  pointer to user data.

   @param pmbus_slave_instance
     The pmbus_slave_instance parameter is a pointer to pmbus_slave_info_t
     structure identifying PMBUS slave information.

   @return
     This function returns  pointer to user data.
 */
void *
PMBUS_get_user_data
(
    pmbus_slave_info_t *pmbus_slave_instance
);

/*-------------------------------------------------------------------------*//**
   This function converts user data into linear format. This data
   operation is required when command expects linear formatted data.
   It is called  before PMBUS_write_word function to send formatted
   data over PMBus.

   @param data
     The data parameter is two byte data which needs conversion into
     linear formatted data.

   @param command_format
     The command_format is either PMBUS_VOUT_LINEAR_FORMAT or
     PMBUS_LINEAR_FORMAT. User need to check the format based on the
     command in device data sheet.

   @param exponent_coeff
     The exponent_coeff parameter is exponent coefficient used for
     linear conversion.
     User must retrieve exponent coefficient information from PMBus slave
     before doing any conversion. The VOUT_MODE command should be
     send to get information about linear coefficients which will
     be stored in exponent_coeff. This is required only when
     command format is of PMBUS_VOUT_LINEAR_FORMAT.

   @return
     This function returns linear converted data .
 */
int32_t
PMBUS_get_linear_format_data
(
    uint8_t *data,
    uint8_t command_format,
    int16_t exponent_coeff
);

/*-------------------------------------------------------------------------*//**
   This function converts actual data to direct format data. This data
   operation is required when command expects Direct formatted data.
   It is called before PMBUS_write_word function to send formatted data
   over PMBus.

   @param data
     The data parameter is two byte data which needs conversion into
     direct formatted data.

   @param direct_coeff
     The direct_coeff parameter is a pointer of int16_t type. It stores
     information related to m,b,r parameter of direct coefficient.
     User must retrieve direct coefficient information from PMBus slave
     before doing any conversion. The COEFFICIENT command should be
     send to get information about direct coefficients which will
     be stored in direct_coeff. The direct_coeff array should
     contain three elements related to m,b,r.

   @return
     This function returns direct converted data .
 */
int32_t
PMBUS_get_direct_format_data
(
    uint8_t *data,
    int16_t *direct_coeff
);

/*-------------------------------------------------------------------------*//**
   This function converts linear format data to actual data. This data
   operation is required when command expects linear formatted data.
   It is called only after PMBUS_read_word() function calls.

   @param command_format
     The command_format is either PMBUS_VOUT_LINEAR_FORMAT or
     PMBUS_LINEAR_FORMAT. User need to check the format based on the
     command in device data sheet.

   @param exponent_coeff
     The exponent_coeff parameter is exponent coefficient used for
     linear conversion.
     User must retrieve exponent coefficient information from PMBus slave
     before doing any conversion. The VOUT_MODE command should be
     send to get information about linear coefficients which will
     be stored in exponent_coeff. This is required only when
     command format is of PMBUS_VOUT_LINEAR_FORMAT.

   @param linear_data
     The linear_data parameter is formatted data received from the
     PMBus slave and this data needs conversion into raw data.

   @param converted_data
     The converted_data parameter is two byte converted data
     User must pass two byte data in the function. This is basically
     output parameter.

   @return
     This function does not return anything.
 */
void
PMBUS_get_data_from_linear_frmt
(
    uint8_t command_format,
    int16_t exponent_coeff,
    int32_t linear_data,
    uint8_t *converted_data
);

/*-------------------------------------------------------------------------*//**
   This function converts direct format data to actual data. This data
   operation is required when command expects Direct formatted data.
   It is called only after PMBUS_read_word() function calls.

   @param direct_coeff
     The direct_coeff parameter is a pointer of int16_t type. It stores
     information related to m,b,r parameter of direct coefficient.
     User must retrieve direct coefficient information from PMBus slave
     before doing any conversion. The COEFFICIENT command should be
     send to get information about direct coefficients which will
     be stored in direct_coeff. The direct_coeff array should
     contain three elements related to m,b,r.

   @param direct_data
     The direct_data parameter is formatted data received from the
     PMBus slave and this data needs conversion into raw data.

   @param converted_data
     The converted_data parameter is two byte converted data
     User must pass two byte data in the function. This is basically
     output parameter.

   @return
     This function does not return anything.
 */
void
PMBUS_get_data_from_direct_frmt
(
    int16_t *direct_coeff,
    int32_t direct_data,
    uint8_t *converted_data
);

#ifdef __cplusplus
}
#endif

#endif /* __PMBUS_H_ */
