400 lines
13 KiB
C
400 lines
13 KiB
C
/* ==========================================================================
|
|
* BLX HS OTG Linux Software Driver and documentation (hereinafter,
|
|
* "Software") is an Unsupported proprietary work of BLX, Inc. unless
|
|
* otherwise expressly agreed to in writing between BLX and you.
|
|
*
|
|
* The Software IS NOT an item of Licensed Software or Licensed Product under
|
|
* any End User Software License Agreement or Agreement for Licensed Product
|
|
* with BLX or any supplement thereto. You are permitted to use and
|
|
* redistribute this Software in source and binary forms, with or without
|
|
* modification, provided that redistributions of source code must retain this
|
|
* notice. You may not view, use, disclose, copy or distribute this file or
|
|
* any information contained herein except pursuant to this license grant from
|
|
* BLX. If you do not agree with this notice, including the disclaimer
|
|
* below, then you are not authorized to use the Software.
|
|
*
|
|
* THIS SOFTWARE IS BEING DISTRIBUTED BY BLX SOLELY ON AN "AS IS" BASIS
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE HEREBY DISCLAIMED. IN NO EVENT SHALL BLX 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 GSC3280_DEVICE_ONLY
|
|
#ifndef __GSC3280_HCD_IF_H__
|
|
#define __GSC3280_HCD_IF_H__
|
|
|
|
#include "gsc3280_otg_core_if.h"
|
|
|
|
/** @file
|
|
* This file defines GSC3280_OTG HCD Core API.
|
|
*/
|
|
|
|
struct gsc3280_otg_hcd;
|
|
typedef struct gsc3280_otg_hcd gsc3280_otg_hcd_t;
|
|
|
|
struct gsc3280_otg_hcd_urb;
|
|
typedef struct gsc3280_otg_hcd_urb gsc3280_otg_hcd_urb_t;
|
|
|
|
/** @name HCD Function Driver Callbacks */
|
|
/** @{ */
|
|
|
|
/** This function is called whenever core switches to host mode. */
|
|
typedef int (*gsc3280_otg_hcd_start_cb_t) (gsc3280_otg_hcd_t * hcd);
|
|
|
|
/** This function is called when device has been disconnected */
|
|
typedef int (*gsc3280_otg_hcd_disconnect_cb_t) (gsc3280_otg_hcd_t * hcd);
|
|
|
|
/** Wrapper provides this function to HCD to core, so it can get hub information to which device is connected */
|
|
typedef int (*gsc3280_otg_hcd_hub_info_from_urb_cb_t) (gsc3280_otg_hcd_t * hcd,
|
|
void *urb_handle,
|
|
uint32_t * hub_addr,
|
|
uint32_t * port_addr);
|
|
/** Via this function HCD core gets device speed */
|
|
typedef int (*gsc3280_otg_hcd_speed_from_urb_cb_t) (gsc3280_otg_hcd_t * hcd,
|
|
void *urb_handle);
|
|
|
|
/** This function is called when urb is completed */
|
|
typedef int (*gsc3280_otg_hcd_complete_urb_cb_t) (gsc3280_otg_hcd_t * hcd,
|
|
void *urb_handle,
|
|
gsc3280_otg_hcd_urb_t * gsc3280_otg_urb,
|
|
int32_t status);
|
|
|
|
/** Via this function HCD core gets b_hnp_enable parameter */
|
|
typedef int (*gsc3280_otg_hcd_get_b_hnp_enable) (gsc3280_otg_hcd_t * hcd);
|
|
|
|
struct gsc3280_otg_hcd_function_ops {
|
|
gsc3280_otg_hcd_start_cb_t start;
|
|
gsc3280_otg_hcd_disconnect_cb_t disconnect;
|
|
gsc3280_otg_hcd_hub_info_from_urb_cb_t hub_info;
|
|
gsc3280_otg_hcd_speed_from_urb_cb_t speed;
|
|
gsc3280_otg_hcd_complete_urb_cb_t complete;
|
|
gsc3280_otg_hcd_get_b_hnp_enable get_b_hnp_enable;
|
|
};
|
|
/** @} */
|
|
|
|
/** @name HCD Core API */
|
|
/** @{ */
|
|
/** This function allocates gsc3280_otg_hcd structure and returns pointer on it. */
|
|
extern gsc3280_otg_hcd_t *gsc3280_otg_hcd_alloc_hcd(void);
|
|
|
|
/** This function should be called to initiate HCD Core.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param core_if The GSC3280_OTG Core
|
|
*
|
|
* Returns -GSC3280_E_NO_MEMORY if no enough memory.
|
|
* Returns 0 on success
|
|
*/
|
|
extern int gsc3280_otg_hcd_init(gsc3280_otg_hcd_t * hcd, gsc3280_otg_core_if_t * core_if);
|
|
|
|
/** Frees HCD
|
|
*
|
|
* @param hcd The HCD
|
|
*/
|
|
extern void gsc3280_otg_hcd_remove(gsc3280_otg_hcd_t * hcd);
|
|
|
|
/** This function should be called on every hardware interrupt.
|
|
*
|
|
* @param gsc3280_otg_hcd The HCD
|
|
*
|
|
* Returns non zero if interrupt is handled
|
|
* Return 0 if interrupt is not handled
|
|
*/
|
|
extern int32_t gsc3280_otg_hcd_handle_intr(gsc3280_otg_hcd_t * gsc3280_otg_hcd);
|
|
|
|
/**
|
|
* Returns private data set by
|
|
* gsc3280_otg_hcd_set_priv_data function.
|
|
*
|
|
* @param hcd The HCD
|
|
*/
|
|
extern void *gsc3280_otg_hcd_get_priv_data(gsc3280_otg_hcd_t * hcd);
|
|
|
|
/**
|
|
* Set private data.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param priv_data pointer to be stored in private data
|
|
*/
|
|
extern void gsc3280_otg_hcd_set_priv_data(gsc3280_otg_hcd_t * hcd, void *priv_data);
|
|
|
|
/**
|
|
* This function initializes the HCD Core.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param fops The Function Driver Operations data structure containing pointers to all callbacks.
|
|
*
|
|
* Returns -GSC3280_E_NO_DEVICE if Core is currently is in device mode.
|
|
* Returns 0 on success
|
|
*/
|
|
extern int gsc3280_otg_hcd_start(gsc3280_otg_hcd_t * hcd,
|
|
struct gsc3280_otg_hcd_function_ops *fops);
|
|
|
|
/**
|
|
* Halts the GSC3280_otg host mode operations in a clean manner. USB transfers are
|
|
* stopped.
|
|
*
|
|
* @param hcd The HCD
|
|
*/
|
|
extern void gsc3280_otg_hcd_stop(gsc3280_otg_hcd_t * hcd);
|
|
|
|
/**
|
|
* Handles hub class-specific requests.
|
|
*
|
|
* @param gsc3280_otg_hcd The HCD
|
|
* @param typeReq Request Type
|
|
* @param wValue wValue from control request
|
|
* @param wIndex wIndex from control request
|
|
* @param buf data buffer
|
|
* @param wLength data buffer length
|
|
*
|
|
* Returns -GSC3280_E_INVALID if invalid argument is passed
|
|
* Returns 0 on success
|
|
*/
|
|
extern int gsc3280_otg_hcd_hub_control(gsc3280_otg_hcd_t * gsc3280_otg_hcd,
|
|
uint16_t typeReq, uint16_t wValue,
|
|
uint16_t wIndex, uint8_t * buf,
|
|
uint16_t wLength);
|
|
|
|
/**
|
|
* Returns otg port number.
|
|
*
|
|
* @param hcd The HCD
|
|
*/
|
|
extern uint32_t gsc3280_otg_hcd_otg_port(gsc3280_otg_hcd_t * hcd);
|
|
|
|
/**
|
|
* Returns 1 if currently core is acting as B host, and 0 otherwise.
|
|
*
|
|
* @param hcd The HCD
|
|
*/
|
|
extern uint32_t gsc3280_otg_hcd_is_b_host(gsc3280_otg_hcd_t * hcd);
|
|
|
|
/**
|
|
* Returns current frame number.
|
|
*
|
|
* @param hcd The HCD
|
|
*/
|
|
extern int gsc3280_otg_hcd_get_frame_number(gsc3280_otg_hcd_t * hcd);
|
|
|
|
/**
|
|
* Dumps hcd state.
|
|
*
|
|
* @param hcd The HCD
|
|
*/
|
|
extern void gsc3280_otg_hcd_dump_state(gsc3280_otg_hcd_t * hcd);
|
|
|
|
/**
|
|
* Dump the average frame remaining at SOF. This can be used to
|
|
* determine average interrupt latency. Frame remaining is also shown for
|
|
* start transfer and two additional sample points.
|
|
* Currently this function is not implemented.
|
|
*
|
|
* @param hcd The HCD
|
|
*/
|
|
extern void gsc3280_otg_hcd_dump_frrem(gsc3280_otg_hcd_t * hcd);
|
|
|
|
/**
|
|
* Sends LPM transaction to the local device.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param devaddr Device Address
|
|
* @param hird Host initiated resume duration
|
|
* @param bRemoteWake Value of bRemoteWake field in LPM transaction
|
|
*
|
|
* Returns negative value if sending LPM transaction was not succeeded.
|
|
* Returns 0 on success.
|
|
*/
|
|
extern int gsc3280_otg_hcd_send_lpm(gsc3280_otg_hcd_t * hcd, uint8_t devaddr,
|
|
uint8_t hird, uint8_t bRemoteWake);
|
|
|
|
/* URB interface */
|
|
|
|
/**
|
|
* Allocates memory for gsc3280_otg_hcd_urb structure.
|
|
* Allocated memory should be freed by call of GSC3280_FREE.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param iso_desc_count Count of ISOC descriptors
|
|
* @param atomic_alloc Specefies whether to perform atomic allocation.
|
|
*/
|
|
extern gsc3280_otg_hcd_urb_t *gsc3280_otg_hcd_urb_alloc(gsc3280_otg_hcd_t * hcd,
|
|
int iso_desc_count,
|
|
int atomic_alloc);
|
|
|
|
/**
|
|
* Set pipe information in URB.
|
|
*
|
|
* @param hcd_urb GSC3280_OTG URB
|
|
* @param devaddr Device Address
|
|
* @param ep_num Endpoint Number
|
|
* @param ep_type Endpoint Type
|
|
* @param ep_dir Endpoint Direction
|
|
* @param mps Max Packet Size
|
|
*/
|
|
extern void gsc3280_otg_hcd_urb_set_pipeinfo(gsc3280_otg_hcd_urb_t * hcd_urb,
|
|
uint8_t devaddr, uint8_t ep_num,
|
|
uint8_t ep_type, uint8_t ep_dir,
|
|
uint16_t mps);
|
|
|
|
/* Transfer flags */
|
|
#define URB_GIVEBACK_ASAP 0x1
|
|
#define URB_SEND_ZERO_PACKET 0x2
|
|
|
|
/**
|
|
* Sets gsc3280_otg_hcd_urb parameters.
|
|
*
|
|
* @param urb GSC3280_OTG URB allocated by gsc3280_otg_hcd_urb_alloc function.
|
|
* @param urb_handle Unique handle for request, this will be passed back
|
|
* to function driver in completion callback.
|
|
* @param buf The buffer for the data
|
|
* @param dma The DMA buffer for the data
|
|
* @param buflen Transfer length
|
|
* @param sp Buffer for setup data
|
|
* @param sp_dma DMA address of setup data buffer
|
|
* @param flags Transfer flags
|
|
* @param interval Polling interval for interrupt or isochronous transfers.
|
|
*/
|
|
extern void gsc3280_otg_hcd_urb_set_params(gsc3280_otg_hcd_urb_t * urb,
|
|
void *urb_handle, void *buf,
|
|
gsc3280_dma_t dma, uint32_t buflen, void *sp,
|
|
gsc3280_dma_t sp_dma, uint32_t flags,
|
|
uint16_t interval);
|
|
|
|
/** Gets status from gsc3280_otg_hcd_urb
|
|
*
|
|
* @param gsc3280_otg_urb GSC3280_OTG URB
|
|
*/
|
|
extern uint32_t gsc3280_otg_hcd_urb_get_status(gsc3280_otg_hcd_urb_t * gsc3280_otg_urb);
|
|
|
|
/** Gets actual length from gsc3280_otg_hcd_urb
|
|
*
|
|
* @param gsc3280_otg_urb GSC3280_OTG URB
|
|
*/
|
|
extern uint32_t gsc3280_otg_hcd_urb_get_actual_length(gsc3280_otg_hcd_urb_t *
|
|
gsc3280_otg_urb);
|
|
|
|
/** Gets error count from gsc3280_otg_hcd_urb. Only for ISOC URBs
|
|
*
|
|
* @param gsc3280_otg_urb GSC3280_OTG URB
|
|
*/
|
|
extern uint32_t gsc3280_otg_hcd_urb_get_error_count(gsc3280_otg_hcd_urb_t *
|
|
gsc3280_otg_urb);
|
|
|
|
/** Set ISOC descriptor offset and length
|
|
*
|
|
* @param gsc3280_otg_urb GSC3280_OTG URB
|
|
* @param desc_num ISOC descriptor number
|
|
* @param offset Offset from beginig of buffer.
|
|
* @param length Transaction length
|
|
*/
|
|
extern void gsc3280_otg_hcd_urb_set_iso_desc_params(gsc3280_otg_hcd_urb_t * gsc3280_otg_urb,
|
|
int desc_num, uint32_t offset,
|
|
uint32_t length);
|
|
|
|
/** Get status of ISOC descriptor, specified by desc_num
|
|
*
|
|
* @param gsc3280_otg_urb GSC3280_OTG URB
|
|
* @param desc_num ISOC descriptor number
|
|
*/
|
|
extern uint32_t gsc3280_otg_hcd_urb_get_iso_desc_status(gsc3280_otg_hcd_urb_t *
|
|
gsc3280_otg_urb, int desc_num);
|
|
|
|
/** Get actual length of ISOC descriptor, specified by desc_num
|
|
*
|
|
* @param gsc3280_otg_urb GSC3280_OTG URB
|
|
* @param desc_num ISOC descriptor number
|
|
*/
|
|
extern uint32_t gsc3280_otg_hcd_urb_get_iso_desc_actual_length(gsc3280_otg_hcd_urb_t *
|
|
gsc3280_otg_urb,
|
|
int desc_num);
|
|
|
|
/** Queue URB. After transfer is completes, the complete callback will be called with the URB status
|
|
*
|
|
* @param gsc3280_otg_hcd The HCD
|
|
* @param gsc3280_otg_urb GSC3280_OTG URB
|
|
* @param ep_handle Out parameter for returning endpoint handle
|
|
*
|
|
* Returns -GSC3280_E_NO_DEVICE if no device is connected.
|
|
* Returns -GSC3280_E_NO_MEMORY if there is no enough memory.
|
|
* Returns 0 on success.
|
|
*/
|
|
extern int gsc3280_otg_hcd_urb_enqueue(gsc3280_otg_hcd_t * gsc3280_otg_hcd,
|
|
gsc3280_otg_hcd_urb_t * gsc3280_otg_urb,
|
|
void **ep_handle, int atomic_alloc);
|
|
|
|
/** De-queue the specified URB
|
|
*
|
|
* @param gsc3280_otg_hcd The HCD
|
|
* @param gsc3280_otg_urb GSC3280_OTG URB
|
|
*/
|
|
extern int gsc3280_otg_hcd_urb_dequeue(gsc3280_otg_hcd_t * gsc3280_otg_hcd,
|
|
gsc3280_otg_hcd_urb_t * gsc3280_otg_urb);
|
|
|
|
/** Frees resources in the GSC3280_otg controller related to a given endpoint.
|
|
* Any URBs for the endpoint must already be dequeued.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param ep_handle Endpoint handle, returned by gsc3280_otg_hcd_urb_enqueue function
|
|
* @param retry Number of retries if there are queued transfers.
|
|
*
|
|
* Returns -GSC3280_E_INVALID if invalid arguments are passed.
|
|
* Returns 0 on success
|
|
*/
|
|
extern int gsc3280_otg_hcd_endpoint_disable(gsc3280_otg_hcd_t * hcd, void *ep_handle,
|
|
int retry);
|
|
|
|
/* Resets the data toggle in qh structure. This function can be called from
|
|
* usb_clear_halt routine.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param ep_handle Endpoint handle, returned by gsc3280_otg_hcd_urb_enqueue function
|
|
*
|
|
* Returns -GSC3280_E_INVALID if invalid arguments are passed.
|
|
* Returns 0 on success
|
|
*/
|
|
extern int gsc3280_otg_hcd_endpoint_reset(gsc3280_otg_hcd_t * hcd, void *ep_handle);
|
|
|
|
/** Returns 1 if status of specified port is changed and 0 otherwise.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param port Port number
|
|
*/
|
|
extern int gsc3280_otg_hcd_is_status_changed(gsc3280_otg_hcd_t * hcd, int port);
|
|
|
|
/** Call this function to check if bandwidth was allocated for specified endpoint.
|
|
* Only for ISOC and INTERRUPT endpoints.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param ep_handle Endpoint handle
|
|
*/
|
|
extern int gsc3280_otg_hcd_is_bandwidth_allocated(gsc3280_otg_hcd_t * hcd,
|
|
void *ep_handle);
|
|
|
|
/** Call this function to check if bandwidth was freed for specified endpoint.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param ep_handle Endpoint handle
|
|
*/
|
|
extern int gsc3280_otg_hcd_is_bandwidth_freed(gsc3280_otg_hcd_t * hcd, void *ep_handle);
|
|
|
|
/** Returns bandwidth allocated for specified endpoint in microseconds.
|
|
* Only for ISOC and INTERRUPT endpoints.
|
|
*
|
|
* @param hcd The HCD
|
|
* @param ep_handle Endpoint handle
|
|
*/
|
|
extern uint8_t gsc3280_otg_hcd_get_ep_bandwidth(gsc3280_otg_hcd_t * hcd,
|
|
void *ep_handle);
|
|
|
|
/** @} */
|
|
|
|
#endif /* __GSC3280_HCD_IF_H__ */
|
|
#endif /* GSC3280_DEVICE_ONLY */
|