// SPDX-License-Identifier: GPL-2.0 /* * Cadence USBSS DRD Driver - gadget side. * * Copyright (C) 2018 Cadence Design Systems. * Copyright (C) 2017-2018 NXP * * Authors: Pawel Jez <[email protected]>, * Pawel Laszczak <[email protected]> * Peter Chen <[email protected]> */ #include <linux/usb/composite.h> #include <linux/iopoll.h> #include "cdns3-gadget.h" #include "cdns3-trace.h" static struct usb_endpoint_descriptor cdns3_gadget_ep0_desc = …; /** * cdns3_ep0_run_transfer - Do transfer on default endpoint hardware * @priv_dev: extended gadget object * @dma_addr: physical address where data is/will be stored * @length: data length * @erdy: set it to 1 when ERDY packet should be sent - * exit from flow control state * @zlp: add zero length packet */ static void cdns3_ep0_run_transfer(struct cdns3_device *priv_dev, dma_addr_t dma_addr, unsigned int length, int erdy, int zlp) { … } /** * cdns3_ep0_delegate_req - Returns status of handling setup packet * Setup is handled by gadget driver * @priv_dev: extended gadget object * @ctrl_req: pointer to received setup packet * * Returns zero on success or negative value on failure */ static int cdns3_ep0_delegate_req(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl_req) { … } static void cdns3_prepare_setup_packet(struct cdns3_device *priv_dev) { … } static void cdns3_ep0_complete_setup(struct cdns3_device *priv_dev, u8 send_stall, u8 send_erdy) { … } /** * cdns3_req_ep0_set_configuration - Handling of SET_CONFIG standard USB request * @priv_dev: extended gadget object * @ctrl_req: pointer to received setup packet * * Returns 0 if success, USB_GADGET_DELAYED_STATUS on deferred status stage, * error code on error */ static int cdns3_req_ep0_set_configuration(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl_req) { … } /** * cdns3_req_ep0_set_address - Handling of SET_ADDRESS standard USB request * @priv_dev: extended gadget object * @ctrl_req: pointer to received setup packet * * Returns 0 if success, error code on error */ static int cdns3_req_ep0_set_address(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl_req) { … } /** * cdns3_req_ep0_get_status - Handling of GET_STATUS standard USB request * @priv_dev: extended gadget object * @ctrl: pointer to received setup packet * * Returns 0 if success, error code on error */ static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl) { … } static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl, int set) { … } static int cdns3_ep0_feature_handle_intf(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl, int set) { … } static int cdns3_ep0_feature_handle_endpoint(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl, int set) { … } /** * cdns3_req_ep0_handle_feature - * Handling of GET/SET_FEATURE standard USB request * * @priv_dev: extended gadget object * @ctrl: pointer to received setup packet * @set: must be set to 1 for SET_FEATURE request * * Returns 0 if success, error code on error */ static int cdns3_req_ep0_handle_feature(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl, int set) { … } /** * cdns3_req_ep0_set_sel - Handling of SET_SEL standard USB request * @priv_dev: extended gadget object * @ctrl_req: pointer to received setup packet * * Returns 0 if success, error code on error */ static int cdns3_req_ep0_set_sel(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl_req) { … } /** * cdns3_req_ep0_set_isoch_delay - * Handling of GET_ISOCH_DELAY standard USB request * @priv_dev: extended gadget object * @ctrl_req: pointer to received setup packet * * Returns 0 if success, error code on error */ static int cdns3_req_ep0_set_isoch_delay(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl_req) { … } /** * cdns3_ep0_standard_request - Handling standard USB requests * @priv_dev: extended gadget object * @ctrl_req: pointer to received setup packet * * Returns 0 if success, error code on error */ static int cdns3_ep0_standard_request(struct cdns3_device *priv_dev, struct usb_ctrlrequest *ctrl_req) { … } static void __pending_setup_status_handler(struct cdns3_device *priv_dev) { … } void cdns3_pending_setup_status_handler(struct work_struct *work) { … } /** * cdns3_ep0_setup_phase - Handling setup USB requests * @priv_dev: extended gadget object */ static void cdns3_ep0_setup_phase(struct cdns3_device *priv_dev) { … } static void cdns3_transfer_completed(struct cdns3_device *priv_dev) { … } /** * cdns3_check_new_setup - Check if controller receive new SETUP packet. * @priv_dev: extended gadget object * * The SETUP packet can be kept in on-chip memory or in system memory. */ static bool cdns3_check_new_setup(struct cdns3_device *priv_dev) { … } /** * cdns3_check_ep0_interrupt_proceed - Processes interrupt related to endpoint 0 * @priv_dev: extended gadget object * @dir: USB_DIR_IN for IN direction, USB_DIR_OUT for OUT direction */ void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir) { … } /** * cdns3_gadget_ep0_enable * @ep: pointer to endpoint zero object * @desc: pointer to usb endpoint descriptor * * Function shouldn't be called by gadget driver, * endpoint 0 is allways active */ static int cdns3_gadget_ep0_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { … } /** * cdns3_gadget_ep0_disable * @ep: pointer to endpoint zero object * * Function shouldn't be called by gadget driver, * endpoint 0 is allways active */ static int cdns3_gadget_ep0_disable(struct usb_ep *ep) { … } /** * cdns3_gadget_ep0_set_halt * @ep: pointer to endpoint zero object * @value: 1 for set stall, 0 for clear stall * * Returns 0 */ static int cdns3_gadget_ep0_set_halt(struct usb_ep *ep, int value) { … } /** * cdns3_gadget_ep0_queue - Transfer data on endpoint zero * @ep: pointer to endpoint zero object * @request: pointer to request object * @gfp_flags: gfp flags * * Returns 0 on success, error code elsewhere */ static int cdns3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, gfp_t gfp_flags) { … } /** * cdns3_gadget_ep_set_wedge - Set wedge on selected endpoint * @ep: endpoint object * * Returns 0 */ int cdns3_gadget_ep_set_wedge(struct usb_ep *ep) { … } static const struct usb_ep_ops cdns3_gadget_ep0_ops = …; /** * cdns3_ep0_config - Configures default endpoint * @priv_dev: extended gadget object * * Functions sets parameters: maximal packet size and enables interrupts */ void cdns3_ep0_config(struct cdns3_device *priv_dev) { … } /** * cdns3_init_ep0 - Initializes software endpoint 0 of gadget * @priv_dev: extended gadget object * @priv_ep: extended endpoint object * * Returns 0 on success else error code. */ int cdns3_init_ep0(struct cdns3_device *priv_dev, struct cdns3_endpoint *priv_ep) { … }