/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*-----------------------------------------------------------------------------
 * $RCSfile: x_rm.h,v $
 * $Revision: #1 $
 * $Date: 2015/05/29 $
 * $Author: brianpc.huang $
 *
 * Description:
 *         This header file contains Resource Manager specific definitions,
 *         which are exported.
 *---------------------------------------------------------------------------*/

#ifndef _X_RM_H_
#define _X_RM_H_


/*-----------------------------------------------------------------------------
                    include files
-----------------------------------------------------------------------------*/

#include "x_common.h"
#include "x_sys_name.h"
#include "u_rm.h"


/*-----------------------------------------------------------------------------
                    macros, defines, typedefs, enums
 ----------------------------------------------------------------------------*/

/* Max number of characters in a Resource Manager name */
/* (excluding the zero terminating character).         */
#define RM_NAME_LEN  SYS_NAME_LEN

/* Do not increase the number of ports past the value '32'. If that is  */
/* truly required, then one must also check the code to ensure that bit */
/* mask remain valid etc.                                               */
#define MAX_NUM_PORTS  ((UINT8)  32)
#define MAX_COMP_ID    ((UINT16) 0xffff)

/* Selects the union member in DRV_COMP_REG_T */
typedef enum
{
    ID_TYPE_IND = 0,
    ID_TYPE_RANGE,
    ID_TYPE_LIST
}   ID_TYPE_T;

/* Individual id, tag and port value */
typedef struct _ID_IND_T
{
    UINT16  ui2_id;

    VOID*  pv_tag;

    UINT8  ui1_port;
}   ID_IND_T;

/* List of id, tag and port values */
typedef struct _ID_LIST_T
{
    ID_IND_T*  pt_list;

    UINT16  ui2_num_of_ids;
}   ID_LIST_T;

/* Range of id, tag and port values */
typedef struct _ID_RANGE_T
{
    UINT16  ui2_first_id;
    UINT16  ui2_delta_id;

    VOID*  pv_first_tag;
    VOID*  pv_delta_tag;

    UINT16  ui2_num_of_ids;

    UINT8  ui1_port;
}   ID_RANGE_T;


/* Driver component id used by the driver API's */
typedef struct _DRV_COMP_ID_T
{
    VOID*  pv_tag;

    DRV_TYPE_T  e_type;

    UINT16  ui2_id;

    BOOL  b_sel_out_port;

    union
    {
        UINT8  ui1_inp_port;
        UINT8  ui1_out_port;
    }   u;
}   DRV_COMP_ID_T;


/* Driver registration structure */
typedef struct _DRV_COMP_REG_T
{
    DRV_TYPE_T  e_type;

    ID_TYPE_T  e_id_type;

    union
    {
        ID_IND_T    t_ind;
        ID_RANGE_T  t_range;
        ID_LIST_T   t_list;
    }   u;
}   DRV_COMP_REG_T;


/* Connection list direction. */
typedef enum
{
    CONN_DIR_OUT_TO_INP = 0,
    CONN_DIR_INP_TO_OUT,
    CONN_DIR_TO_SUPPORT,
    CONN_DIR_FROM_SUPPORT
}   CONN_DIR_TYPE_T;


/* Callback condition */
typedef enum
{
    DRV_COND_DISCONNECTED = 0,
    DRV_COND_CONNECTED,
    DRV_COND_STATUS,
    DRV_COND_UPDATE
}   DRV_COND_T;

/* Connect reasons */
#define RM_CONN_REASON_AS_REQUESTED  ((UINT32)   0)

/* Disconnect reasons */
#define RM_DISC_REASON_AS_REQUESTED  ((UINT32)   0)

/* Driver callback function. */
typedef VOID (*x_rm_nfy_fct) (DRV_COMP_ID_T*  pt_comp_id,
                              DRV_COND_T      e_nfy_cond,
                              VOID*           pv_tag,
                              UINT32          ui4_data);

/* Connection types */
#define RM_CONN_TYPE_IGNORE   ((DRV_CONN_TYPE_T)   0)
#define RM_CONN_TYPE_RESTORE  ((DRV_CONN_TYPE_T)   1)
#define RM_CONN_TYPE_COMP_ID  ((DRV_CONN_TYPE_T)   2)

/* Driver control functions. */
typedef INT32 (*x_rm_connect_fct) (DRV_COMP_ID_T*   pt_comp_id,
                                   DRV_CONN_TYPE_T  e_conn_type,
                                   const VOID*      pv_conn_info,
                                   SIZE_T           z_conn_info_len,
                                   VOID*            pv_tag,
                                   x_rm_nfy_fct     pf_nfy);


/* Disconnect types */
#define RM_DISC_TYPE_IGNORE   ((DRV_DISC_TYPE_T)   0)
#define RM_DISC_TYPE_COMP_ID  ((DRV_DISC_TYPE_T)   2)

typedef INT32 (*x_rm_disconnect_fct) (DRV_COMP_ID_T*   pt_comp_id,
                                      DRV_DISC_TYPE_T  e_disc_type,
                                      const VOID*      pv_disc_info,
                                      SIZE_T           z_disc_info_len);

/* Get types */
#define RM_GET_TYPE_IGNORE       ((DRV_GET_TYPE_T)   0)
#define RM_GET_TYPE_ISR_CONTEXT  ((DRV_GET_TYPE_T) 0x00100000)

typedef INT32 (*x_rm_get_fct) (DRV_COMP_ID_T*  pt_comp_id,
                               DRV_GET_TYPE_T  e_get_type,
                               VOID*           pv_get_info,
                               SIZE_T*         pz_get_info_len);

/* Set types */
#define RM_SET_TYPE_IGNORE       ((DRV_SET_TYPE_T)   0)
#define RM_SET_TYPE_ISR_CONTEXT  ((DRV_SET_TYPE_T) 0x00100000)
#define RM_SET_TYPE_ARG_NO_REF   ((DRV_SET_TYPE_T) 0x00200000)
#define RM_SET_TYPE_ARG_CALLBACK ((DRV_SET_TYPE_T) 0x00400000)

typedef INT32 (*x_rm_set_fct) (DRV_COMP_ID_T*  pt_comp_id,
                               DRV_SET_TYPE_T  e_set_type,
                               const VOID*     pv_set_info,
                               SIZE_T          z_set_info_len);

/* Driver component exclusion notify function. */
typedef VOID (*x_rm_comp_excl_nfy_fct) (DRV_COMP_ID_T*  pt_pas_comp_id,
                                        DRV_COMP_ID_T*  pt_act_comp_id);


/* Driver function table */
typedef struct _DRV_COMP_FCT_TBL_T
{
    x_rm_connect_fct     pf_rm_connect;
    x_rm_disconnect_fct  pf_rm_disconnect;
    x_rm_get_fct         pf_rm_get;
    x_rm_set_fct         pf_rm_set;
}   DRV_COMP_FCT_TBL_T;

/* Component flags. */
#define DRV_FLAG_ASYNC_CONN_OR_DISC     ((UINT32) 0x00000001)
#define DRV_FLAG_SINGLE_CONN_ON_OUTPUT  ((UINT32) 0x00000002)

/* Resource Manager API return values */
#define RMR_DRV_INV_CONN_INFO          ((INT32) -256)
#define RMR_DRV_INV_DISC_INFO          ((INT32) -257)
#define RMR_DRV_INV_GET_INFO           ((INT32) -258)
#define RMR_DRV_INV_SET_INFO           ((INT32) -259)
#define RMR_DRV_CONN_FAILED            ((INT32) -260)
#define RMR_DRV_DISC_FAILED            ((INT32) -261)
#define RMR_DRV_SET_FAILED             ((INT32) -262)
#define RMR_DRV_GET_FAILED             ((INT32) -263)
#define RMR_DRV_NO_GET_INFO            ((INT32) -264)
#define RMR_DRV_NOT_ENOUGH_SPACE       ((INT32) -265)
#define RMR_DRV_WRITE_PROTECT          ((INT32) - 266)


/*-----------------------------------------------------------------------------
                    functions declarations
 ----------------------------------------------------------------------------*/

extern INT32 x_rm_get_comp_info_from_name (const CHAR*  ps_name,
                                           UINT16       ui2_idx,
                                           DRV_TYPE_T*  pe_type,
                                           UINT16*      pui2_id,
                                           UINT8*       pui1_num_inp_ports,
                                           UINT8*       pui1_num_out_ports,
                                           UINT32*      pui4_comp_flags);
extern INT32 x_rm_get_num_comps_of_type_from_name (const CHAR*  ps_name,
                                                   DRV_TYPE_T   e_type,
                                                   UINT16*      pui2_num_comps);
extern INT32 x_rm_reg_comp (DRV_COMP_REG_T*      pt_comp_id,
                            UINT8                ui1_num_inp_ports,
                            UINT8                ui1_num_out_ports,
                            const CHAR*          ps_comp_name,
                            UINT32               ui4_comp_flags,
                            DRV_COMP_FCT_TBL_T*  pt_comp_fct_tbl,
                            const VOID*          pv_comp_data,
                            SIZE_T               z_comp_data_len);
extern INT32 x_rm_reg_conn_list (const DRV_COMP_REG_T*  pt_comp_id,
                                 const DRV_COMP_REG_T*  pt_conn_ids,
                                 UINT16                 ui2_num_entries,
                                 CONN_DIR_TYPE_T        e_conn_dir,
                                 BOOL                   b_hard_wired);
extern INT32 x_rm_reg_comp_excl_list (const DRV_COMP_REG_T*  pt_comp_id,
                                      const DRV_COMP_REG_T*  pt_comp_excl_ids,
                                      UINT16                 ui2_num_entries);
extern INT32 x_rm_reg_comp_excl_nfy (const DRV_COMP_REG_T*   pt_comp_ids,
                                     UINT16                  ui2_num_entries,
                                     x_rm_comp_excl_nfy_fct  pf_rm_comp_excl_nfy);
extern INT32 x_rm_reg_conn_excl_list (const DRV_COMP_REG_T*  pt_comp_id,
                                      const DRV_COMP_REG_T*  pt_conn_excl_ids,
                                      UINT16                 ui2_num_entries);
extern INT32 x_rm_reg_group_name (const CHAR*            ps_group_name,
                                  const DRV_COMP_REG_T*  pt_comp_ids,
                                  UINT16                 ui2_num_entries);

extern INT32 x_rm_set_comp (DRV_TYPE_T      e_type,
                            UINT16          ui2_id,
                            BOOL            b_sel_out_port,
                            UINT8           ui1_port,
                            DRV_SET_TYPE_T  e_set_type,
                            const VOID*     pv_set_info,
                            SIZE_T          z_set_info_len);

extern INT32 x_rm_get_comp (DRV_TYPE_T      e_type,
                            UINT16          ui2_id,
                            BOOL            b_sel_out_port,
                            UINT8           ui1_port,
                            DRV_GET_TYPE_T  e_get_type,
                            VOID*           pv_get_info,
                            SIZE_T*         pz_get_info_len);

#endif /* _X_RM_H */
