/**
 * @file pca9673_gpio_expander.h
 *
 * @brief This file contains function prototypes ,macros,enumeration and
 * structure definition of PCAL6408 GPIO expander
 *
 * @copyright Copyright 2023 Antaris, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef GPIO_EXP_PCA9673_H_
#define GPIO_EXP_PCA9673_H_

#include <stdint.h>
#include <string.h>

/// Error code definitions
#define PCA9673_OK                          INT8_C(0)     ///< Success return value
#define PCA9673_E_NULL_PTR                  INT8_C(-1)    ///< Null pointer return value
#define PCA9673_E_READ_WRITE_LENGTH_INVALID INT8_C(-2)    ///< Invalid read write length return value
#define PCA9673_E_OUT_OF_RANGE              INT8_C(-3)    ///< out of range return value
#define PCA9673_E_COM_FAIL				  INT8_C(-4)	///< INA230 communication fail

/**@}*/
/**\name C standard macros */
#ifndef NULL
#ifdef __cplusplus
#define NULL                                      0
#else
#define NULL                                      ((void *) 0)
#endif
#endif

/*****************************************************************************/
/** 
 * @brief  GPIO Bit SET and Bit RESET enumeration
 */
typedef enum
{
	PCA9673_PIN_RESET = 0,           ///< Pin state is zero
	PCA9673_PIN_SET                 ///< Pin state is one
}pca9673_gpio_pinstate;


/** 
 * @brief  Expander gpio pin enumeration
 */
typedef enum
{
#if 0
	PCA9673_GPIO_0 = 0b00000001,        ///< Expander gpio pin 0
	PCA9673_GPIO_1 = 0b00000010,        ///< Expander gpio pin 1
	PCA9673_GPIO_2 = 0b00000100,        ///< Expander gpio pin 2
	PCA9673_GPIO_3 = 0b00001000,        ///< Expander gpio pin 3
	PCA9673_GPIO_4 = 0b00010000,        ///< Expander gpio pin 4
	PCA9673_GPIO_5 = 0b00100000,        ///< Expander gpio pin 5
	PCA9673_GPIO_6 = 0b01000000,        ///< Expander gpio pin 6
	PCA9673_GPIO_7 = 0b10000000,        ///< Expander gpio pin 7
	PCA9673_GPIO_10 = 0b00000010000000000, ///< Expander gpio pin 0
	PCA9673_GPIO_11 = 0b00000100000000000,        ///< Expander gpio pin 1
	PCA9673_GPIO_12 = 0b00001000000000000,        ///< Expander gpio pin 2
	PCA9673_GPIO_13 = 0b00010000000000000,        ///< Expander gpio pin 3
	PCA9673_GPIO_14 = 0b00100000000000000,        ///< Expander gpio pin 4
	PCA9673_GPIO_15 = 0b01000000000000000,        ///< Expander gpio pin 5
	PCA9673_GPIO_16 = 0b10000000000000000,        ///< Expander gpio pin 6
	PCA9673_GPIO_17 = 0b100000000000000000,        ///< Expander gpio pin 6
	PCA9673_GPIO_MAX = 0b11111111,
#endif
	PCA9673_GPIO_0 = 0,
		PCA9673_GPIO_1 ,
		PCA9673_GPIO_2,
		PCA9673_GPIO_3,
		PCA9673_GPIO_4,
		PCA9673_GPIO_5 ,
		PCA9673_GPIO_6 ,
		PCA9673_GPIO_7 ,
		PCA9673_GPIO_10,
		PCA9673_GPIO_11,
		PCA9673_GPIO_12,
		PCA9673_GPIO_13 ,
		PCA9673_GPIO_14 ,
		PCA9673_GPIO_15 ,
		PCA9673_GPIO_16 ,
		PCA9673_GPIO_17 ,
		PCA9673_GPIO_MAX =255,
}pca9673_gpio_pin;

/** 
 * @brief  Expander gpio pin enumeration
 */
typedef enum{
	PCA9673_OUTPUT,                ///< Pin output state
	PCA9673_INPUT                  ///< Pin input state
}pca9673_pin_dir;


/**
 * @brief Bus communication function pointer which should be mapped to
 * the platform specific read functions of the user
 */
typedef uint8_t (*pca9673_read_fptr_t)(void *hi2c, uint16_t dev_addr,uint8_t *rd_data, uint16_t len);

/**
 * @brief Bus communication function pointer which should be mapped to
 * the platform specific write functions of the user
 */
typedef uint8_t (*pca9673_write_fptr_t)(void *hi2c, uint16_t dev_addr,uint8_t *write_data, uint16_t len);

/*************************** Data structures *********************************/
/**
 * @brief pca9673 expander device structure definition
 *
 */
typedef struct _pca9673_dev
{
	uint8_t  slave_addr;               /*!< Chip address 					*/
	void  *io_intf_hdle;               /*!< 0 - I2C Instance handle pointer */
	pca9673_read_fptr_t  read;       /*!< Read function pointer 			*/
	pca9673_write_fptr_t write;      /*!< Write function pointer 			*/
} pca9673_dev;


/**
 * @brief This API initializes the gpio pin as per the gpio_config. This api
 * needs to be called for all the gpio expander pins.
 * @param[in] hdev        : Structure instance of pca9673_dev.
 * @param[in] gpio_config : configuration of the gpio pin
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error.
 */
int8_t pca9673_gpio_init(pca9673_dev *hdev);

/**
 * @brief This API used to read data from register and write  to validate GPIO expender
 * @param[in] hdev        : Structure instance of pca9673_dev.
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error.
 */
int8_t pca9673_self_test(pca9673_dev *hdev);

/**
 * @brief This API is used to read the pcal6408a registers through i2c interface
 * @param[in] hdev   : Structure instance of pca9673_dev.
 * @param[in] reg    : Address of the register that needs to be read
 * @param[out] data  : Data that is read from the register
 * @param[in] len    : size of data to be read
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error.
 */
int8_t pca9673_read(pca9673_dev *hdev,uint8_t *data, uint16_t len);

/**
 * @brief This API is used to write the pcal6408a registers through i2c interface
 * @param[in] hdev   : Structure instance of pca9673_dev.
 * @param[in] reg    : Address of the register that needs to be written
 * @param[in] data   : Data to be written to the register
 * @param[in] len    : size of data to be written
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error.
 */
int8_t pca9673_write(pca9673_dev *hdev,uint8_t *data, uint16_t len);

/**
 * @brief This API is used to read the state of the gpio pin
 * @param[in] hdev    : Structure instance of pca9673_dev.
 * @param[in] pin     : pin whose state needs to be read
 * @param[out] state  : state of the gpio pin
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error.
 */
int8_t pca9673_readpin(pca9673_dev *hdev,pca9673_gpio_pin pin, pca9673_gpio_pinstate *state);

/**
 * @brief This API is used to write the state of the gpio pin
 * @param[in] hdev    : Structure instance of pca9673_dev.
 * @param[in] pin     : pin whose state needs to be changed
 * @param[in] state   : state of the gpio pin that will be set to the gpio pin
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error.
 */
int8_t pca9673_writepin(pca9673_dev *hdev,pca9673_gpio_pin pin, pca9673_gpio_pinstate state);
int8_t pca9673_togglepin(pca9673_dev *hdev, pca9673_gpio_pin pin);

#endif /*GPIO_EXP_PCA9673_H_ */
