/*
 * exo_ahw_vdp_gpio_exp_pcs9673.c
 *
 *  Created on: Oct 27, 2023
 *      Author: Invcuser_63
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "exo_ahw_vdp_gpio_exp_pca9673.h"
#include "pca9673_gpio_expander.h"
#include "exo_io_al_gpio_common.h"
#include "exo_osal_mem_management.h"
#include "exo_ahw_al_linux_wrpr.h"
#include "exo_common.h"

/**
 * @brief  IO Map lookup table.
 */
extern ahw_io_map *ahw_io_lookup_tble[MAX_AH_INST_ID];

/**
 * @brief  Instance handle pointer.
 */
extern void *intf_inst_hdle_ptr[MAX_IO_INST_ID];

/**
 * @brief  This API is used for i2c write.
 */
uint8_t pca9673_i2c_write(void* intf_hdl, uint16_t slv_addr,uint8_t *data, uint16_t len)
{
    int8_t rslt;
    if(io_hal_i2c_transmit(intf_hdl,slv_addr,data,2,500) == HAL_SCS)
    {
        rslt=PCA9673_OK;
    }
    return rslt;
}

/**
 * @brief  This API is used for i2c read.
 */
uint8_t pca9673_i2c_read(void* intf_hdl, uint16_t slv_addr, uint8_t *data, uint16_t len)
{
    ioal_i2c_hdle *hi2c = (ioal_i2c_hdle*)intf_hdl;
    int8_t rslt;
	if(HAL_SCS == io_hal_i2c_receive(hi2c, (uint16)slv_addr, data, len, 500))
	{
		rslt =PCA9673_OK;
	}
	else
	{
		rslt =PCA9673_E_COM_FAIL;
	}
    return rslt;
}

/**
 * @brief This API initializes the GPIO pin as per the gpio_config.
 */
hal_ret_sts ahw_vdp_gpio_exp_pca9673_init(ahw_al_gpio_exp_hdle *hgpio_exp)
{
    hal_ret_sts sts = HAL_MAX_ERR;
    pca9673_dev* hge=(pca9673_dev*)os_malloc(sizeof(pca9673_dev));
#ifdef LINUX_TEMP_PORT
    hge->write = skt_intf_write_pca9673;
    hge->read = skt_intf_read_pca9673;
#else
    hge->write = pca9673_i2c_write;
    hge->read = pca9673_i2c_read;
#endif
    hge->io_intf_hdle = intf_inst_hdle_ptr[ahw_io_lookup_tble[hgpio_exp->ahw_gen_info.ahw_inst_id]->io_instance_id];
    hge->slave_addr=ahw_io_lookup_tble[hgpio_exp->ahw_gen_info.ahw_inst_id]->slv_addr;
    if(HAL_SCS == (hal_ret_sts)pca9673_gpio_init(hge))
    {
        hgpio_exp->ahw_gen_info.vdp_inst_hdle =(void*)hge;
        hgpio_exp->ahw_gen_info.io_intf_hdle=hge->io_intf_hdle;
        sts = HAL_SCS;
    }
    else
    {
        sts = HAL_AH_DRIVER_ERR;
    }
#ifdef LINUX_TEMP_PORT
    sts = HAL_SCS;
#endif
    return sts;
}

/**
 * @brief This API is used to reads and writes data to register
 */
hal_ret_sts ahw_vdp_gpio_exp_pca9673_self_test(ahw_al_gpio_exp_hdle *hgpio_exp)
{
    hal_ret_sts sts;
    pca9673_dev *vdh_gex;
    vdh_gex = (pca9673_dev*) hgpio_exp->ahw_gen_info.vdp_inst_hdle;
    if(HAL_SCS == (hal_ret_sts) pca9673_self_test(vdh_gex))
    {
        sts = HAL_SCS;
    }
    else
    {
        sts = HAL_AH_DRIVER_ERR;
    }
    return sts;
}
/**
 * @brief This API is used to read the state of the GPIO pin
 */
hal_ret_sts ahw_vdp_gpio_exp_pca9673_readpin(ahw_al_gpio_exp_hdle *hgpio_exp, gpio_exp_gpio_pin pin, gpio_exp_gpio_pinstate *pin_state)
{
    hal_ret_sts sts;
    pca9673_dev *vdh_gex;
    vdh_gex = (pca9673_dev*) hgpio_exp->ahw_gen_info.vdp_inst_hdle;
    if(HAL_SCS == (hal_ret_sts) pca9673_readpin(vdh_gex,pin,(pca9673_gpio_pinstate*)pin_state))
    {
        sts = HAL_SCS;
    }
    else
    {
        sts = HAL_AH_DRIVER_ERR;
    }
    return sts;
}

/**
 * @brief This API is used to write the state of the GPIO pin
 */
hal_ret_sts ahw_vdp_gpio_exp_pca9673_writepin(ahw_al_gpio_exp_hdle *hgpio_exp,gpio_exp_gpio_pin pin, gpio_exp_gpio_pinstate pin_state)
{
    hal_ret_sts sts;
    pca9673_dev *vdh_gex;
    vdh_gex = (pca9673_dev*) hgpio_exp->ahw_gen_info.vdp_inst_hdle;
    if(HAL_SCS == pca9673_writepin(vdh_gex,pin,pin_state))
    {
        sts = HAL_SCS;
    }
    else
    {
        sts = HAL_AH_DRIVER_ERR;
    }
    return sts;
}

/**
 * @brief This API is used to toggle the state of the GPIO pin
 */
hal_ret_sts ahw_vdp_gpio_exp_pca9673_togglepin(ahw_al_gpio_exp_hdle *hgpio_exp, gpio_exp_gpio_pin pin)
{
    hal_ret_sts sts;
    pca9673_dev *vdh_gex;
    vdh_gex = (pca9673_dev*) hgpio_exp->ahw_gen_info.vdp_inst_hdle;

    if(HAL_SCS == pca9673_togglepin(vdh_gex,(pca9673_gpio_pinstate)pin))
    {
        sts = HAL_SCS;
    }
    else
    {
        sts = HAL_AH_DRIVER_ERR;
    }
    return sts;
}
