/* 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.
 *
 *****************************************************************************/


 /*---------------------------------------------------------------------------
 *
 * $Author: brianpc.huang $
 * $Date: 2015/05/29 $
 * $RCSfile: musb_if.h,v $
 * $Revision: #1 $
 *
 *---------------------------------------------------------------------------*/

/** @file musb_if.h
 *  Brief of file musb_if.h
 *  Details of file musb_if.h (optional).
 */

#ifndef MUSB_IF_H

#define MUSB_IF_H

#ifndef CC_USB_DISABLE

//---------------------------------------------------------------------------
// Include files
//---------------------------------------------------------------------------

#include "mu_hfi_if.h"

#include "x_lint.h"
LINT_EXT_HEADER_BEGIN
#include "x_typedef.h"
LINT_EXT_HEADER_END

//---------------------------------------------------------------------------
// Type definitions
//---------------------------------------------------------------------------
typedef VOID  (*MUSB_CALLBACK)(UINT32 u4Tag, INT32 i4Status);

typedef INT32 (*MBLOCK_GETTOTALLUN)(VOID);
typedef INT32 (*MBLOCK_GETLUN)(VOID);
typedef INT32 (*MBLOCK_SETLUN)(UINT32 u4Lun);
typedef INT64 (*MBLOCK_GETSIZE)(VOID);
typedef INT32 (*MBLOCK_GETBLOCKSIZE)(VOID);
typedef INT32 (*MBLOCK_GETSTATUS)(VOID);
typedef CHAR* (*MBLOCK_GETMODEL)(VOID);
typedef INT32 (*MBLOCK_ERASE)(UINT64 u8Offset, UINT32 u4ByteCount);
typedef INT32 (*MBLOCK_READ)(UINT64 u8Offset, UINT32 u4MemPtr, UINT32 u4MemLen);
typedef INT32 (*MBLOCK_WRITE)(UINT64 u8Offset, UINT32 u4MemPtr, UINT32 u4MemLen);
typedef VOID  (*MBLOCK_SetHotswapCallback)(UINT32 u4Tag, MUSB_CALLBACK pfnCallback);
typedef INT32 (*MBLOCK_GETINFO)(VOID);
typedef struct _MBlockIOFunc 
{
    MBLOCK_GETTOTALLUN           pfnGetTotalLun;
    MBLOCK_GETLUN                pfnGetLun;
    MBLOCK_SETLUN                pfnSetLun;
    MBLOCK_GETSIZE               pfnGetSize;
    MBLOCK_GETBLOCKSIZE          pfnGetBlockSize;
    MBLOCK_GETSTATUS             pfnGetStatus;
    MBLOCK_GETMODEL              pfnGetModel;
    MBLOCK_ERASE                 pfnErase;
    MBLOCK_READ                  pfnRead;
    MBLOCK_WRITE                 pfnWrite;
    MBLOCK_SetHotswapCallback    pfnSetNotify;
    MBLOCK_GETINFO               pfnGetInfo;
} MBlockFunc_T;

#define MUSB_MAX_REG_NOTIFY     3

typedef enum
{
    USB_STATUS_DEV_READY = 0,                         // USB device with supported driver is connected
    USB_STATUS_DEV_ABSENT,      	                 // USB device with supported driver is removed

    USB_STATUS_UNSUPPORT,                               // Unsupported USB device is connected.
    USB_STATUS_UNSUPPORT_ABSENT,                // Unsupported usb device is removed.

    USB_STATUS_HUB_READY, 		                   // USB hub device is connected
    USB_STATUS_HUB_ABSENT, 		                   // USB hub device is connected
    
    USB_STATUS_SERIAL_READY,                       // USB Serial device is connected
    USB_STATUS_SERIAL_ABSENT,                      // USB Serail device is removed
    USB_STATUS_UNSUPPORT_HUB,                       // Unsupported USB hub is connected.
    USB_STATUS_UNSUPPORT_HUB_ABSENT         // Unsupported usb hub is removed.
} MUSB_CONNECT_STATUS;

typedef struct _MUSB_HOTSWAP_DETECT_T
{
    MUSB_CONNECT_STATUS  eStatus;
    UINT16 u2VendorID;
    UINT16 u2ProductID;
    UINT8  *pManufacturer;
    UINT8  *pProduct;
    UINT8  *pSerialNum;
} MUSB_HOWSWAP_DETECT_T;

typedef VOID (*MUSB_HOTSWAP_CALLBACK)(UINT32 u4Tag,  
                                      MUSB_HOWSWAP_DETECT_T *prResult);

typedef struct _MUSB_HOTSWAP_T
{
    UINT32                u4Tag;
    MUSB_HOTSWAP_CALLBACK pfnHotSwapNotify;
} MUSB_HOTSWAP_T;

typedef struct _MUSB_HOTSWAP_NFY_T
{
    UINT32         u4Count;
    MUSB_HOTSWAP_T rHotSwap[MUSB_MAX_REG_NOTIFY];
} MUSB_HOTSWAP_NFY_T;

typedef VOID  (*MUSB_SetHotswapNotify)(MUSB_HOTSWAP_T prHotSwap);

/// init usb module to host mode.
#define MUSB_HOST_MODE          (1)         

/// init usb module to device mode.
#define MUSB_DEVICE_MODE       (0)

#if defined(CONFIG_ARCH_MT85XX)
#define MUSB_OTG_MODE       (2)
#endif

/// Generic Capture function.
#define MUSB_DEVICE_MODE_CAP       (0)
/// CDC USB to Uart function.
#define MUSB_DEVICE_MODE_CDC       (1)
/// MSD USB function.
#define MUSB_DEVICE_MODE_MSD      (2)

/// host waring error code.
#define MUSB_WARNING                          (MGC_M_STATUS_WARNING)
#define MUSB_CONNECT                           (MUSB_STATUS_CHILD_CONNECT)
#define MUSB_DISCONNECT                     (MUSB_STATUS_CHILD_DISCONNECT)
#define MUSB_UNSUPPORTED_DEVICE   (MUSB_STATUS_UNSUPPORTED_DEVICE)
#define MUSB_UNSUPPORTED_HUB        (MUSB_STATUS_UNSUPPORTED_HUB)
#define MUSB_UNSUPPORTED_REMOVE (MUSB_STATUS_UNSUPPORTED_REMOVE)


/** Function-only port */
#define USB_PORT_TYPE_FUNCTION   (1)
/** Host-only port */
#define USB_PORT_TYPE_HOST     (2)

#if defined(CONFIG_ARCH_MT85XX)
/** Otg port */
#define USB_PORT_TYPE_OTG		(3)
/* For IC Verification only */
#define USB_DIAG_MAX_LUN_NUM    (12)
#endif

#if !defined(CONFIG_ARCH_MT85XX)
#define FIND_MUSB_NONE                                (0)
#define FIND_CLASS_MASS_STORAGE              (1)
#define FIND_CLASS_HUB                                 (2)

extern void MUSB_SetDeviceOnHubFlag(UINT32 u4flag);
extern UINT32 MUSB_GetDeviceOnHubFlag(VOID);

extern void MUSB_SetMassOnHubFlag(UINT32 u4Massflag);
extern UINT32 MUSB_GetMassOnHubFlag(VOID);
#endif

//---------------------------------------------------------------------------
// Inter-file functions
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Public functions
//---------------------------------------------------------------------------
//-------------------------------------------------------------------------
/** MUSB_Read
*  MUSB read function.
*  @param  u8Offset     read offset from card, u8Offset should be multiple of block size.
*  @param  u4MemPtr      user's read buffer address.
*  @param  u4MemLen      read length, u4MemLen should be multiple of block size.
*  @retval 0   Success.
*  @retval others  Fail.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_Read(UINT64 u8Offset, UINT32 u4MemPtr, UINT32 u4MemLen);
#if defined(CONFIG_ARCH_MT85XX)
EXTERN INT32 MUSB_ReadEx(UINT32 u4Lun, UINT64 u8Offset, UINT32 u4MemPtr, UINT32 u4MemLen);
#endif

//-------------------------------------------------------------------------
/** MUSB_Write
*  MUSB write function.
*  @param  u8Offset     write offset from card, u8Offset should be multiple of block size.
*  @param  u4MemPtr      user's write buffer address.
*  @param  u4MemLen      write length, u4MemLen should be multiple of block size.
*  @retval S_OK   Success.
*  @retval others  Fail.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_Write(UINT64 u4Offset, UINT32 u4MemPtr, UINT32 u4MemLen);
#if defined(CONFIG_ARCH_MT85XX)
EXTERN INT32 MUSB_WriteEx(UINT32 u4Lun, UINT64 u4Offset, UINT32 u4MemPtr, UINT32 u4MemLen);
EXTERN CHAR *MUSB_GetModelEx(UINT32 u4Lun);
#endif

//-------------------------------------------------------------------------
/** MUSB_GetModel
*  MUSB get model name function.
*  @param  VOID.
*  @return   USB model name.
*/
//-------------------------------------------------------------------------
EXTERN CHAR *MUSB_GetModel(VOID);

//-------------------------------------------------------------------------
/** MUSB_GetBlockSize
*  MUSB get block size function.
*  @param  VOID.
*  @return  the card block size in bytes.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_GetBlockSize(VOID);
#if defined(CONFIG_ARCH_MT85XX)
EXTERN INT32 MUSB_GetBlockSizeEx(UINT32 u4Lun);
#endif

//-------------------------------------------------------------------------
/** MUSB_GetSize
*  MUSB get card size function.
*  @param  VOID.
*  @return  the card size. Unit in sector:
*                512 bytes or 2048 bytes depend on pMediumInfo->dwBlockSize.
*/
//-------------------------------------------------------------------------
EXTERN INT64 MUSB_GetSize(VOID);

//-------------------------------------------------------------------------
/** MUSB_GetInsert
*  MUSB get usb insert status.
*  @param  VOID.
*  @retval 1   Device is inserted in USB socket.
*  @retval 0   Device absent.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_GetInsert(VOID);

//-------------------------------------------------------------------------
/** MUSB_GetStatus
*  MUSB get usb status.
*  @param  VOID.
*  @return  the card status in STORG_DEV_STATUS_T.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_GetStatus(VOID);

//-------------------------------------------------------------------------
/** MUSB_SetHotswapCallback
* MUSB register device call back function when usb is removed, inserted.
*  @param  u4Tag             user's tag in call back function.
*  @param  pfnCallback     user's call back function, it will be called at card inserted or removed.
*  @retval VOID.
*/
//-------------------------------------------------------------------------
EXTERN VOID MUSB_SetHotswapCallback(UINT32 u4Tag, MUSB_CALLBACK pfnCallback);

//-------------------------------------------------------------------------
/** MUSB_GetInfo
* Get target protected information.
*  @retval 0         Success.
*  @retval 2  Device read-only.
*  @retval 3  Device abstent.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_GetInfo(void);

//-------------------------------------------------------------------------
/** MUSB_GetBlkFuncTbl
* Get MUSB block function table pointer.
*  @param  pFuncTable      define the query function that the block manager 
*                                       can get a table of pointers to all IO functions.
*  @retval 0         Success.
*  @retval others  Fail.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_GetBlkFuncTbl(MBlockFunc_T *pFuncTable);

//-------------------------------------------------------------------------
/** MUSB_GetAccessType
*  MUSB get access type.
*  @retval device accesss type.
*/
//-------------------------------------------------------------------------
EXTERN MUSB_HfiAccessType MUSB_GetAccessType(void);

//-------------------------------------------------------------------------
/** MUSB_GetTotalLun
* Get total number of logical unit number in MSD device.
*  @param  void.
*  @retval   total number of logical unit number in MSD device.
*/
//-------------------------------------------------------------------------
EXTERN UINT32 MUSB_GetTotalLun(void);
#if defined(CONFIG_ARCH_MT85XX)
EXTERN UINT32 MUSB_GetTotalLunEx(UINT32 u4Lun);
#endif

//-------------------------------------------------------------------------
/** MUSB_GetLun
* Get active target logical unit number of MSD device.
*  @retval active target logical unit number of MSD device.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_GetLun(void);

//-------------------------------------------------------------------------
/** MUSB_SetLun
* Set target logical unit number of MSD device.
*  @param  u4Lun   target logical unit number of MSD device.
*  @retval 0         Success.
*  @retval others  Fail.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_SetLun(UINT32 u4Lun);

//-------------------------------------------------------------------------
/** MUSB_Suspend
* Set suspend usb bus.
*  @param  void.
*  @retval 0         Success.
*  @retval others  Fail.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_Suspend(void);

//-------------------------------------------------------------------------
/** MUSB_Resume
* Set resume usb bus.
*  @param  void.
*  @retval 0         Success.
*  @retval others  Fail.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_Resume(void);

#ifdef CC_MT8563
//-------------------------------------------------------------------------
/** MUSB_Resume
* Set resume usb bus.
*  @param  void.
*  @retval 0         Success.
*  @retval others  Fail.
*/
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_Pdwnc(uint32_t port, uint32_t powerState);
#endif
//-------------------------------------------------------------------------
/** MUSB_SetHostErrorCallback
* Notify user usb host detect error.
*  @param  u4Tag             user's tag in call back function.
*  @param  pfnCallback     user's call back function, it will be called at host detect error.
*                                       (MUSB_WARNING, MUSB_UNSUPPORTED_DEVICE, MUSB_UNSUPPORTED_HUB, 
*                                       MUSB_UNSUPPORTED_REMOVE)
*  @retval VOID.
*/
//-------------------------------------------------------------------------
EXTERN void MUSB_SetHostErrorCallback(UINT32 u4Tag, MUSB_CALLBACK pfnCallback);

//-------------------------------------------------------------------------
/** MUSB_SetPortMode
 *  Set USB port to host or device mode function.
 *  @param  u4PortIndex   port index 0 ~ (MUSB_CountPorts() - 1).
 *  @param  u4Type	    
            1: USB_PORT_TYPE_FUNCTION
            2: USB_PORT_TYPE_HOST            
 *  @retval  0 	SUCCESS.
 *  @retval  -1	FAIL. 
 */
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_SetPortMode(UINT32 u4PortIndex, UINT32 u4Type);

//-------------------------------------------------------------------------
/** MUSB_Init
 *  Set USB host or device mode function.
 *  @param  u4Mode		1: host, 0: device.
 *  @retval  0 	SUCCESS.
 *  @retval  -1	FAIL. 
 */
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_Init(UINT32 u4Mode);

//-------------------------------------------------------------------------
/** MUSB_InitDeviceMode
 *  Set USB device mode function.
 *  @param  u4Mode 
 *      MUSB_DEVICE_MODE_CAP         (0)
 *      MUSB_DEVICE_MODE_CDC        (1)
 *      MUSB_DEVICE_MODE_MSD        (2)
 *  @retval  0 	SUCCESS.
 *  @retval  -1	FAIL. 
 */
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_InitDeviceMode(UINT32 u4Mode);

#if defined(CONFIG_ARCH_MT85XX)
/** i4UsbHostInit
 *  Initial USB as host mode function.
 *  @param  void
 *  @retval  0 	SUCCESS.
 *  @retval  -1	FAIL. 
 */
//-------------------------------------------------------------------------
EXTERN INT32 i4UsbHostInit(void);
#endif

//-------------------------------------------------------------------------
/** MUSB_CheckSLT
 *  USB SLT check function.
 *  @param  void.
 *  @retval  0 	SUCCESS.
 *  @retval  -1	FAIL. 
 */
//-------------------------------------------------------------------------
EXTERN INT32 MUSB_CheckSLT(void);

//-------------------------------------------------------------------------
/** MUSB_InitTimeMonitor
* Initial variable of data rate monitor time.
*  @param void.
*  @retval void.
*/
//-------------------------------------------------------------------------
EXTERN void MUSB_InitTimeMonitor(void);
#if defined(CONFIG_ARCH_MT85XX)
EXTERN void MUSB_InitTimeMonitorEx(UINT32 u4Lun);
#endif

//-------------------------------------------------------------------------
/** MUSB_InitRateMonitor
* Get total data rate monitor operation time.
*  @param void.
*  @retval  total operation time in micro second.
*/
//-------------------------------------------------------------------------
EXTERN UINT64 MUSB_GetTimeMonitor(void);
#if defined(CONFIG_ARCH_MT85XX)
EXTERN UINT64 MUSB_GetTimeMonitorEx(UINT32 u4Lun);
#endif

//#ifdef CC_USBIF_TEST
//-------------------------------------------------------------------------
/** MUSB_SetHotSwap
 *  Set hot-swap notify for USB-IF test function.
 *  @param  void.
 *  @retval TRUE 	SUCCESS.
 *  @retval FALSE   FAIL. 
 */
//-------------------------------------------------------------------------
extern BOOL MUSB_SetHotSwap(const MUSB_HOTSWAP_T *prHotSwap);
//#endif

//-------------------------------------------------------------------------
/** MUSB_fgIsInit
 *  Get the initialization status of USB controller.
 *  @param  void.
 *  @retval TRUE 	USB controller has been initialed.
 *  @retval FALSE   USB controller has NOT been initialed. 
 */
//-------------------------------------------------------------------------
#if defined(CONFIG_ARCH_MT85XX)
extern BOOL MUSB_fgIsInit(void);
extern BOOL fgUsbVbusEnable(uint8_t bPortNum, BOOL fgEnable);
#endif

#if !defined(CONFIG_ARCH_MT85XX)
//-------------------------------------------------------------------------
/** MUSB_TurnOffVBus
 *  Turn off USB 5V.
 *  @param  void.
 *  @retval void.
 */
//-------------------------------------------------------------------------
extern void MUSB_TurnOffVBus(void);

//-------------------------------------------------------------------------
/** MUSB_TurnOnVBus
 *  Turn on USB 5V.
 *  @param  void.
 *  @retval void.
 */
//-------------------------------------------------------------------------
extern void MUSB_TurnOnVBus(void);

//-------------------------------------------------------------------------
/** MUSB_GetTotalPort
* Get total number of port number on the platform.
*  @param  void.
*  @retval   total number of port number on the platform.
*/
//-------------------------------------------------------------------------
extern UINT32 MUSB_GetTotalPort(void);
extern BOOL MUSB_Uart_Cli_Support(void);
extern UINT32 MUSB_Uart_Read(UINT8 *pBuffer, UINT32 u4NumToRead);
extern void MUSB_Uart_PutChar(UINT8 u1Char);
#endif

#endif // CC_USB_DISABLE
#endif // MUSB_IF_H

