/**HEADER********************************************************************
* 
* Copyright (c) 2008, 2013 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED 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 FREESCALE OR ITS 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.
*
**************************************************************************
*
* $FileName: usb_host_stack_interface.h$
* $Version : 
* $Date    : 
*
* Comments:
*
*   
*
*END************************************************************************/
#ifndef __usb_host_stack_interface_h__
#define __usb_host_stack_interface_h__

/* Prototypes */
#define  USB_SERVICE_HOST_RESUME             (0x01)
#define  USB_SERVICE_SYSTEM_ERROR            (0x02)
#define  USB_SERVICE_SPEED                   (0x03)
#define  USB_SERVICE_ATTACH                  (0x04)
#define  USB_SERVICE_DETACH                  (0x05)
#define  USB_SERVICE_STALL_PACKET            (0x06)
#define  USB_SERVICE_ENUMERATION_DONE        (0x07)
#define  USB_SERVICE_1MS_TIMER               (0x08)

/*------------------------------**
** Class / SubClass / Protocol  **
**------------------------------*/

#define  USB_CLASS_AUDIO            1
#define  USB_SUBCLASS_UNDEFINED     0
#define  USB_SUBCLASS_AUD_CONTROL   1
#define  USB_SUBCLASS_AUD_STREAMING 2
#define  USB_SUBCLASS_AUD_MIDI_STRM 3
#define  USB_PROTOCOL_UNDEFINED     0

#define  USB_CLASS_COMMUNICATION    2
#define  USB_SUBCLASS_COM_DIRECT    1
#define  USB_SUBCLASS_COM_ABSTRACT  2
#define  USB_SUBCLASS_COM_TELEPHONE 3
#define  USB_SUBCLASS_COM_MULTICHAN 4
#define  USB_SUBCLASS_COM_CAPI      5
#define  USB_SUBCLASS_COM_ETHERNET  6
#define  USB_SUBCLASS_COM_ATM_NET   7
#define  USB_PROTOCOL_COM_NOSPEC    0
#define  USB_PROTOCOL_COM_V25       1
#define  USB_PROTOCOL_COM_HAYES     1
#define  USB_PROTOCOL_COM_AT        1
#define  USB_PROTOCOL_COM_VENDOR    0xFF

#define  USB_CLASS_PRINTER          7
#define  USB_SUBCLASS_PRINTER       1
#define  USB_PROTOCOL_PRT_UNIDIR   1
#define  USB_PROTOCOL_PRT_BIDIR     2
#define  USB_PROTOCOL_PRT_1284      3

#define  USB_CLASS_MASS_STORAGE     8
#define  USB_SUBCLASS_MASS_RBC      1
#define  USB_SUBCLASS_MASS_ATAPI    2
#define  USB_SUBCLASS_MASS_QIC157   3
#define  USB_SUBCLASS_MASS_UFI      4
#define  USB_SUBCLASS_MASS_SFF8070I 5
#define  USB_SUBCLASS_MASS_SCSI     6
#define  USB_PROTOCOL_MASS_IRRPT    0
#define  USB_PROTOCOL_MASS_NOIRRPT  1
#define  USB_PROTOCOL_MASS_BULK     0x50

#define  USB_CLASS_HID              3
#define  USB_SUBCLASS_HID_NONE      0
#define  USB_SUBCLASS_HID_BOOT      1
#define  USB_PROTOCOL_HID_NONE      0
#define  USB_PROTOCOL_HID_KEYBOARD  1
#define  USB_PROTOCOL_HID_MOUSE     2
#define  USB_PROTOCOL_HID_BOOT_E    0
#define  USB_PROTOCOL_HID_REPORT_E  1

#define  USB_CLASS_HUB              9
#define  USB_SUBCLASS_HUB_NONE      0
#define  USB_PROTOCOL_HUB_LS        0
#define  USB_PROTOCOL_HUB_FS        0
#define  USB_PROTOCOL_HUB_HS_SINGLE 1
#define  USB_PROTOCOL_HUB_HS_MULTI  2
#define  USB_PROTOCOL_HUB_ALL       0xFF

#define  USB_CLASS_DATA             0x0A
   /* No data subclasses, set to 0 */
#define  USB_PROTOCOL_DATA_I430     0x30
#define  USB_PROTOCOL_DATA_HDLC     0x31
#define  USB_PROTOCOL_DATA_TRANS    0x32
#define  USB_PROTOCOL_DATA_Q921M    0x50
#define  USB_PROTOCOL_DATA_Q921     0x51
#define  USB_PROTOCOL_DATA_Q921TM   0x52
#define  USB_PROTOCOL_DATA_V42BIS   0x90
#define  USB_PROTOCOL_DATA_EUROISDN 0x91
#define  USB_PROTOCOL_DATA_V120     0x92
#define  USB_PROTOCOL_DATA_CAPI20   0x93
#define  USB_PROTOCOL_DATA_HOST     0xFE
#define  USB_PROTOCOL_DATA_CDC      0xFE
#define  USB_PROTOCOL_DATA_VENDOR   0xFF

typedef void * class_handle;

#define  REQ_TYPE_DEVICE    0x00
#define  REQ_TYPE_INTERFACE 0x01
#define  REQ_TYPE_ENDPOINT  0x02

/* Standard USB requests, see Chapter 9 */
#define  REQ_GET_STATUS          0
#define  REQ_CLEAR_FEATURE       1
#define  REQ_SET_FEATURE         3
#define  REQ_SET_ADDRESS         5
#define  REQ_GET_DESCRIPTOR      6
#define  REQ_SET_DESCRIPTOR      7
#define  REQ_GET_CONFIGURATION   8
#define  REQ_SET_CONFIGURATION   9
#define  REQ_GET_INTERFACE       10
#define  REQ_SET_INTERFACE       11
#define  REQ_SYNCH_FRAME         12

/* Combine one of the 3 above with one of the following 2 */
#define  REQ_TYPE_IN        0x80
#define  REQ_TYPE_OUT       0x00

/* Also for class requests set the following bit */
#define  REQ_TYPE_CLASS     0x20

/* Define function type for class device instance initialization */
typedef usb_status (_CODE_PTR_ intf_init_call) (usb_device_instance_handle, usb_interface_descriptor_handle, class_handle*);
/* Define function type for class device instance deinitialization, internal */
typedef usb_status (_CODE_PTR_ intf_deinit_call) (class_handle);
/* Define function type for class device instance deinitialization, internal */
typedef usb_status (_CODE_PTR_ intf_pre_deinit_call) (class_handle);

/* The following define the internal mapping from interface
** class / sub-class / protocol to class drivers 
*/



/*-------------------------------------------------------------**
** Transaction callback parameters:                            **
**    void*     pipe handle                                  **
**    void*     parameter specified by higher level          **
**    uint8_t *   pointer to buffer containing data (TX or RX) **
**    uint32_t     length of data transferred                   **
**    usb_status  status, preferably USB_OK or USB_DONE etc.   **
**-------------------------------------------------------------*/
typedef void  (_CODE_PTR_ tr_callback)(void*, void *, uint8_t *, uint32_t, usb_status);

/*-------------------------------------------------------------------**
** Isochronous Transaction callback parameters:                      **
**    PIPE_DESCRIPTOR_STRUCT_PTR pipe handle                         **
**    tr_struct_t*              transaction handle                  **
**    usb_status  status, preferably USB_OK or USB_DONE etc.         **
**-------------------------------------------------------------------*/
typedef void (_CODE_PTR_ iso_tr_callback)(struct pipe_struct *, struct tr_struct *, usb_status);

/*---------------------------------------------------------**
** Attach/Detach callback parameters:                      **
**    usb_device_instance_handle      new/removed device  **
**    usb_interface_descriptor_handle matching class etc. **
**   uint32_t                           code (attach etc.). **
**---------------------------------------------------------*/
typedef void (_CODE_PTR_ event_callback)(usb_device_instance_handle, usb_interface_descriptor_handle, uint32_t);

/* Setup */
typedef struct
{
   uint8_t                      bmrequesttype;
   uint8_t                      brequest;
   uint8_t                      wvalue[2];
   uint8_t                      windex[2];
   uint8_t                      wlength[2];
} usb_setup_t;


typedef struct tr_struct
{
   struct tr_struct*            next;
   uint32_t                     status;
   uint32_t                     tr_index;           /* Transfer number on this pipe   */
   uint8_t *                    tx_buffer;          /* Address of buffer containing the data to be transmitted (including OUT data phase of control transfers) */
   uint8_t *                    rx_buffer;          /* Address of buffer to receive data */
   uint32_t                     tx_length;          /* Length of data to transmit. For control transfers, the length of data for the data phase */
   uint32_t                     rx_length;          /* Length of data to be received. For control transfers, this indicates the length of data for the data phase */
   bool                         send_phase;         /* Second phase of setup packet: Send/Receive */
   usb_setup_t                  setup_packet;       /* Setup packet raw data */
   uint32_t                     transfered_length;
   tr_callback                  callback;           /* The callback function to be invoked when a transfer is completed or an error is to be reported */
   void*                        callback_param;     /* The second parameter to be passed into the callback function when it is invoked */
   uint8_t                      occupied;
   uint8_t                      setup_status;
} tr_struct_t;

typedef struct pipe_init_struct
{
   void*                        dev_instance;
   uint32_t                     flags;
   uint16_t                     max_packet_size;
   uint16_t                     nak_count;
   uint8_t                      interval;
   uint8_t                      endpoint_number;
   uint8_t                      direction;
   uint8_t                      pipetype;
} pipe_init_struct_t;

typedef struct class_map
{
   intf_init_call               class_init;       /* class driver initialization- entry  of the class driver */
   intf_deinit_call             class_deinit;
   intf_pre_deinit_call         class_pre_deinit;
   uint8_t                      class_code;       /* interface descriptor class, */
   uint8_t                      sub_class_code;   /*   sub-class, and            */
   uint8_t                      protocol_code;    /*   protocol.                 */
   uint8_t                      class_code_mask;  /* masks ANDed with class etc. */
   uint8_t                      sub_code_mask;    /*   mask = 0x00 matches any   */
   uint8_t                      prot_code_mask;   /*   mask = 0xFF must be exact */
} class_map_t;

/* Information for one class or device driver */
typedef struct driver_info
{
   uint8_t                      idVendor[2];      /* Vendor ID per USB-IF */
   uint8_t                      idProduct[2];     /* Product ID per manufacturer */
   uint8_t                      bDeviceClass;     /* Class code, 0xFF if any */
   uint8_t                      bDeviceSubClass;  /* Sub-Class code, 0xFF if any */
   uint8_t                      bDeviceProtocol;  /* Protocol, 0xFF if any */
   uint8_t                      reserved;         /* Alignment padding */
   event_callback               attach_call;
} usb_host_driver_info_t;

/* Strucutre Representing Endpoints and number of endpoints user want*/
typedef struct _usb_device_ep_struct
{
    endpoint_descriptor_t*     lpEndpointDesc;
    uint16_t                   endpointExlength;
    uint8_t*                   endpointEx;
} usb_device_ep_struct_t;

typedef struct _usb_device_interface_struct
{
    interface_descriptor_t*    lpinterfaceDesc;
    uint16_t                   interfaceExlength;
    uint8_t *                  interfaceEx;
    uint8_t                    ep_count;
    usb_device_ep_struct_t     ep[USBCFG_HOST_MAX_EP_PER_INTERFACE];
} usb_device_interface_struct_t;


#ifdef __cplusplus
extern "C" {
#endif

usb_status usb_host_init (uint8_t, usb_host_handle *);
usb_status usb_host_deinit(usb_host_handle);
usb_status usb_host_open_pipe(usb_host_handle, usb_pipe_handle *, pipe_init_struct_t*);
usb_status usb_host_close_pipe(usb_host_handle, usb_pipe_handle);
usb_status usb_host_send_data(usb_host_handle, usb_pipe_handle, tr_struct_t*);
usb_status usb_host_send_setup(usb_host_handle, usb_pipe_handle, tr_struct_t*);
usb_status usb_host_recv_data(usb_host_handle, usb_pipe_handle, tr_struct_t*);
usb_status usb_host_bus_control(usb_host_handle, uint8_t);
usb_status usb_host_open_dev_interface(usb_host_handle, usb_device_instance_handle, usb_interface_descriptor_handle, class_handle*);
usb_status usb_host_close_dev_interface(usb_host_handle, usb_device_instance_handle, usb_interface_descriptor_handle, class_handle);
usb_status usb_host_register_service (usb_host_handle, uint8_t, void(_CODE_PTR_ service)(void*, uint32_t));
usb_status usb_host_unregister_service (usb_host_handle, uint8_t);
usb_status usb_host_register_ch9_callback(usb_host_handle, usb_device_instance_handle, tr_callback, void*);
usb_status usb_host_unregister_ch9_callback(usb_host_handle, usb_device_instance_handle);
usb_status usb_host_register_driver_info(usb_host_handle, void*);
usb_status usb_host_register_unsupported_device_notify(usb_host_handle, event_callback);
usb_status usb_host_get_tr(usb_host_handle, tr_callback, void*, tr_struct_t* *);
usb_status usb_host_release_tr(usb_host_handle, tr_struct_t*);
usb_status usb_host_cancel(usb_host_handle, usb_pipe_handle, tr_struct_t*);


#ifdef __cplusplus
}
#endif

#endif
