/*
 * Copyright (c) 2022, NVIDIA CORPORATION.  All rights reserved.
 *
 * NVIDIA CORPORATION and its licensors retain all intellectual property
 * and proprietary rights in and to this software, related documentation
 * and any modifications thereto.  Any use, reproduction, disclosure or
 * distribution of this software and related documentation without an express
 * license agreement from NVIDIA CORPORATION is strictly prohibited.
 */

#ifndef I2C__I2C_ASYNC_H
#define I2C__I2C_ASYNC_H
#define FSP__I2C__I2C_ASYNC_H                                 1

/* Compiler headers */

/* Early FSP headers */

/* Hardware headers */

/* Late FSP headers */

/* Module-specific FSP headers */

/** @file i2c-async.h */

/**
 * @brief Start the Asynchronous i2c transfer
 *
 * Start an i2c transfer and return the control to the caller. Once the i2c
 * controller initiates the transfer, tegra_i2c_irq_handler() handles the rest
 * of the transfer and calls the callback function provided as input to this API.
 * The current i2c async transfers support only read or write.
 * Multiple/Mixed reads and writes is not supported.
 * Imp - i2c_start_async_xfer enables the clocks for the i2c xfer. It is FW's
 * responsibility to call i2c_finish_async_xfer to disable the clocks. The unwanted
 * power drawn if i2c_finish_async_xfer is not called is not in the scope of this API.
 *
 * @pre The function i2c_controller_init() must be called before this function.
 * Else, hi2c->hwops structure is not initialized and api returns
 * E_INVALID_OPS.
 *
 * @param[in] hi2c          Pointer to I2C handle which is returned from
 *                          i2c_controller_init().
 * @param[in] msgs          Pointer to I2C messages containing the list of
 *                          message to be transferred.
 * @param[in] num_msgs      Number of messages in the msgs parameter.
 * @param[in] client_data   Pointer to client-specific data
 * @param[in] async_cb      Callback pointer to be called when xfer is completed.
 * @retval E_SUCCESS        I2C transfer initiated successfully.
 * @retval E_INVALID_PARAM  Invalid parameter is passed to the function. <br>
 *                          T194 - allowed size of transfer is 500 Bytes. <br>
 *                          T234 - allowed size of transfer is 65535 Bytes.
 * @retval carry_return     Returns error returned by appfw_mutex_acquire().
 * @retval E_INVALID_OPS    Invalid i2c_hw_ops::start_async_xfer is assigned in
 *                          tegra handle.
 * @retval carry_return     Returns error returned by
 *                          i2c_hw_ops::start_async_xfer function.
 * @retval carry_return     Returns error returned by appfw_mutex_release().
 */
error_t i2c_start_async_xfer(const struct i2c_handle *hi2c,
                                struct i2c_xfer_msg *msgs, uint32_t num_msgs,
                                void *client_data, i2c_async_callback async_cb);

/**
 * @brief Finish the Asynchronous i2c transfer
 *
 * FW calls this API to complete the transaction. In case the transfer returns error,
 * the api handles error handling and disables the clocks. In case of successful
 * transfers, only the clocks are disabled.
 * @pre The function i2c_controller_init() must be called before this function.
 * Else, hi2c->hwops structure is not initialized and api returns
 * E_INVALID_OPS.
 *
 * @pre The function i2c_controller_init() must be called before this function.
 * Else, hi2c->hwops structure is not initialized and api returns
 * E_INVALID_OPS.
 *
 * @param[in] hi2c          Pointer to I2C handle which is returned from
 *                          i2c_controller_init().
 * @param[in] xfer_ret      Return value from the i2c transfer.
 * @retval E_SUCCESS        I2C transfer completed successfully.
 * @retval E_INVALID_OPS    Invalid i2c_hw_ops::finish_async_xfer is assigned in
 *                          tegra handle.
 * @retval carry_return     Returns error returned by
 *                          i2c_hw_ops::finish_async_xfer function..
 * @retval carry_return     Returns error returned by appfw_mutex_release().
 */
error_t i2c_finish_async_xfer(const struct i2c_handle *hi2c, error_t xfer_ret);

/**
 * @brief Get the state of I2C transfer.
 *
 * Return I2C transfer status. Status variables defined at "I2C Xfer status".
 *
 * @pre The function i2c_controller_init() must be called before this function.
 * Else, hi2c->hwops structure is not initialized and api returns
 * E_INVALID_OPS.
 *
 * @param[in] hi2c          Pointer to I2C handle which is returned from
 *                          i2c_controller_init().
 * @param[out] state        refer "I2C HW xfer status" macros for the return values.
 * @param[out] msgs_xfered  Number of msgs transferred.
 * @retval E_INVALID_PARAM  Invalid parameter is passed to the function.
 * @retval carry_return     Returns error returned by tegra_i2c_get_xfer_state().
 * @retval E_SUCCESS        Transfer status is successfully read.
 */
error_t i2c_get_xfer_state(const struct i2c_handle *hi2c, uint32_t *state,
                            uint32_t *msgs_xfered);
#endif
