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


#ifndef _MUSB_HID_IF_H_
#define _MUSB_HID_IF_H_

#include "mu_hid.h"

#define MGC_HID_JOYSTICK_NUM   (4)

#ifndef _MU_HID_CMD_TYPE_
#define _MU_HID_CMD_TYPE_
/** 
 * MUSB_HidIoctlCmdType.
 * HFI Ioctl command Type.
 */
typedef enum
{
    MUSB_HID_IOCTL_GET_DEVICE_NUM,     // total number of HID devices on our system.
    MUSB_HID_IOCTL_GET_DEVICE_PORT,   // number of ports on the each HID device.
    MUSB_HID_IOCTL_GET_DEVICE_STATUS,

    /* JoyStick related data */
    MUSB_HID_IOCTL_GET_JOYSTICK_DATA,
    MUSB_HID_IOCTL_GET_JOYSTICK_NUM,
    MUSB_HID_IOCTL_SET_JOYSTICK_INSERT_NOTIFY,
    MUSB_HID_IOCTL_SET_JOYSTICK_DATA_NOTIFY,
    
    MUSB_HID_IOCTL_END
} MUSB_HidIoctlCmdType;
#endif

typedef struct 
{
    uint32_t dwX;
    uint32_t dwY;
    uint32_t dwButton; /* Max 32 buttons in bit field to get 1: press, 0: release */

    /* Value range */
    uint8_t   bXYMin; 
    uint8_t   bXYMax; 
    uint8_t   bButtonBitsNum; 

    /* Count the change index */    
    uint32_t  Index;  
}JOYSTICK_INFO_STRUCT;

typedef void (*MUSB_pfHidJoystickInsertNfy)(uint8_t bJoystickId, 
    uint8_t bInsert);

typedef void (*MUSB_pfHidJoystickDataNfy)(uint8_t bJoystickId, 
    JOYSTICK_INFO_STRUCT *pJoyStick);

struct _MGC_HidDevice;

typedef struct 
{
    /* Joystick related object */
    uint8_t bIndex;
    uint8_t bHidDevId; /* The id index in total id */
    JOYSTICK_INFO_STRUCT rJoyStick;
    MUSB_pfHidJoystickDataNfy pfHidJoystck;
    struct _MGC_HidDevice *pHidDevice;
} MGC_HidJoystick;

typedef struct _MGC_HidDevice
{
    /* USB hid device basic information object */
    uint8_t bDeviceIndex;
    MUSB_BusHandle hBus;   /* MGC_Port* pImplPort */
    MUSB_Device *pUsbDevice;
    MUSB_DeviceDriver *pDriver;
    MUSB_ConfigurationDescriptor *pConfig;
    MUSB_InterfaceDescriptor *pIface;
    MUSB_HidDescriptor *pHidDescr;
    MUSB_EndpointDescriptor *pEnd;
    uint8_t *pReportDescr;

    /* USB transfer related object */
    uint8_t aSetupTx[8+MUSB_HID_CTRL_LENGTH];
    MUSB_ControlIrp ControlIrp;
    MUSB_Irp intrInIrp;
    MUSB_Pipe hIntInPipe;
    uint8_t aIntInBuf[8];

    /* Common HID driver object */
    const CHAR *HidTypes;
    uint8_t bHidType;
    REPORT_STRUCT rReport[3]; /* 0 FOR IN, 1 for OUT, 2 for Feature */
    COLLECTION_STRUCT aCollection[MAX_COLLECTION_ALLOWED];
    uint8_t bCollectionNum;
    uint8_t bState;
    uint8_t bNextState;        

    /* Joystick, Keyboard related object */
    uint8_t bHidDriverNum;  /*Num of driver on the same hid device.*/
    void *pHidDriverTag;
} MGC_HidDevice;

/**
 * Fill an array with the targetted peripheral list entry appropriate
 * for the mass-storage class driver, ending with the MUSB_TARGET_ACCEPT.
 * @param pList array
 * @param wListLength how many bytes are available in the array
 * @return how many bytes were filled in the array.
 * If this equals bListLength, the caller should assume there is insufficient space
 * in the array and the list entry is incomplete.
 */
extern uint16_t MUSB_FillHidClassPeripheralList(uint8_t* pList, uint16_t wListLength);

/**
 * Get a pointer to the mass-storage class driver
 */
extern MUSB_DeviceDriver* MUSB_GetHidClassDriver(void);

extern int32_t MUSB_HidIoctl(uint32_t u4Index, uint32_t u4Cmd, uint32_t u4Aux, void *pBuffer);

/**
 * Joystick internal function.
 */
extern void MUSB_JoystickInit(void); 
extern void MUSB_JoystickRegister(MGC_HidDevice *pHidDevice);
extern void MUSB_JoystickRelease(MGC_HidDevice *pHidDevice);
extern uint32_t MUSB_JoystickEvent(MGC_HidDevice *pHidDevice);
/**
 * Joystick external function.
 */
extern uint32_t MUSB_JoystickCount(void);
extern void *MUSB_JoystickGetData(uint8_t bIndex, void *pBuf);
extern void MUSB_JoystickSetInsertNotify(void *pBuf);
extern void MUSB_JoystickSetDataNotify(void *pBuf);

 
#endif /* _MUSB_HID_IF_H_ */
