static int usbhsg_gadget_stop(struct usb_gadget_driver *driver) { struct usbhsg_gpriv *gpriv = the_controller; struct usbhs_priv *priv; struct device *dev = usbhsg_gpriv_to_dev(gpriv); if (!gpriv) return -ENODEV; if (!driver || !driver->unbind || driver != gpriv->driver) return -EINVAL; dev = usbhsg_gpriv_to_dev(gpriv); priv = usbhsg_gpriv_to_priv(gpriv); usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); device_del(&gpriv->gadget.dev); gpriv->driver = NULL; if (driver->disconnect) driver->disconnect(&gpriv->gadget); driver->unbind(&gpriv->gadget); dev_dbg(dev, "unbind %s\n", driver->driver.name); return 0; }
static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct device *dev = usbhsg_gpriv_to_dev(gpriv); unsigned long flags; usbhsg_pipe_disable(uep); dev_dbg(dev, "set halt %d (pipe %d)\n", halt, usbhs_pipe_number(pipe)); /******************** spin lock ********************/ usbhs_lock(priv, flags); if (halt) usbhs_pipe_stall(pipe); else usbhs_pipe_disable(pipe); if (halt && wedge) usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE); else usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); usbhs_unlock(priv, flags); /******************** spin unlock ******************/ return 0; }
/* * usb gadget ops */ static int usbhsg_get_frame(struct usb_gadget *gadget) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); return usbhs_frame_get_num(priv); }
/* * * linux usb function * */ static int usbhsg_gadget_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct device *dev = usbhs_priv_to_dev(priv); int ret; if (!driver || !driver->setup || driver->max_speed < USB_SPEED_FULL) return -EINVAL; /* connect to bus through transceiver */ if (!IS_ERR_OR_NULL(gpriv->transceiver)) { ret = otg_set_peripheral(gpriv->transceiver->otg, &gpriv->gadget); if (ret) { dev_err(dev, "%s: can't bind to transceiver\n", gpriv->gadget.name); return ret; } /* get vbus using phy versions */ usbhs_mod_phy_mode(priv); } /* first hook up the driver ... */ gpriv->driver = driver; return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); }
static int usbhsg_pullup(struct usb_gadget *gadget, int is_on) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); usbhs_sys_function_pullup(priv, is_on); return 0; }
/* * * linux usb function * */ static int usbhsg_gadget_start(struct usb_gadget_driver *driver, int (*bind)(struct usb_gadget *)) { struct usbhsg_gpriv *gpriv; struct usbhs_priv *priv; struct device *dev; int ret; if (!bind || !driver || !driver->setup || driver->speed != USB_SPEED_HIGH) return -EINVAL; /* * find unused controller */ usbhsg_for_each_controller(gpriv) { if (!gpriv->driver) goto find_unused_controller; } return -ENODEV; find_unused_controller: dev = usbhsg_gpriv_to_dev(gpriv); priv = usbhsg_gpriv_to_priv(gpriv); /* first hook up the driver ... */ gpriv->driver = driver; gpriv->gadget.dev.driver = &driver->driver; ret = device_add(&gpriv->gadget.dev); if (ret) { dev_err(dev, "device_add error %d\n", ret); goto add_fail; } ret = bind(&gpriv->gadget); if (ret) { dev_err(dev, "bind to driver %s error %d\n", driver->driver.name, ret); goto bind_fail; } dev_dbg(dev, "bind %s\n", driver->driver.name); return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); bind_fail: device_del(&gpriv->gadget.dev); add_fail: gpriv->driver = NULL; gpriv->gadget.dev.driver = NULL; return ret; }
/* * * usb_ep_ops * */ static int usbhsg_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct usbhs_pipe *pipe; int ret = -EIO; unsigned long flags; usbhs_lock(priv, flags); /* * if it already have pipe, * nothing to do */ if (uep->pipe) { usbhs_pipe_clear(uep->pipe); usbhs_pipe_sequence_data0(uep->pipe); ret = 0; goto usbhsg_ep_enable_end; } pipe = usbhs_pipe_malloc(priv, usb_endpoint_type(desc), usb_endpoint_dir_in(desc)); if (pipe) { uep->pipe = pipe; pipe->mod_private = uep; /* set epnum / maxp */ usbhs_pipe_config_update(pipe, 0, usb_endpoint_num(desc), usb_endpoint_maxp(desc)); /* * usbhs_fifo_dma_push/pop_handler try to * use dmaengine if possible. * It will use pio handler if impossible. */ if (usb_endpoint_dir_in(desc)) { pipe->handler = &usbhs_fifo_dma_push_handler; } else { pipe->handler = &usbhs_fifo_dma_pop_handler; usbhs_xxxsts_clear(priv, BRDYSTS, usbhs_pipe_number(pipe)); } ret = 0; } usbhsg_ep_enable_end: usbhs_unlock(priv, flags); return ret; }
static int usbhsg_gadget_stop(struct usb_gadget *gadget) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); gpriv->driver = NULL; return 0; }
static void usbhsg_queue_pop(struct usbhsg_uep *uep, struct usbhsg_request *ureq, int status) { struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); unsigned long flags; usbhs_lock(priv, flags); __usbhsg_queue_pop(uep, ureq, status); usbhs_unlock(priv, flags); }
static int usbhsg_vbus_session(struct usb_gadget *gadget, int is_active) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct platform_device *pdev = usbhs_priv_to_pdev(priv); gpriv->vbus_active = !!is_active; renesas_usbhs_call_notify_hotplug(pdev); return 0; }
static int usbhsg_gadget_stop(struct usb_gadget *gadget) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); if (!IS_ERR_OR_NULL(gpriv->transceiver)) otg_set_peripheral(gpriv->transceiver->otg, NULL); gpriv->driver = NULL; return 0; }
/* * * linux usb function * */ static int usbhsg_gadget_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); if (!driver || !driver->setup || driver->max_speed < USB_SPEED_FULL) return -EINVAL; /* first hook up the driver ... */ gpriv->driver = driver; return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); }
static int usbhsg_pullup(struct usb_gadget *gadget, int is_on) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); unsigned long flags; usbhs_lock(priv, flags); if (is_on) usbhsg_status_set(gpriv, USBHSG_STATUS_SOFT_CONNECT); else usbhsg_status_clr(gpriv, USBHSG_STATUS_SOFT_CONNECT); usbhsg_update_pullup(priv); usbhs_unlock(priv, flags); return 0; }
/* * queue push/pop */ static void __usbhsg_queue_pop(struct usbhsg_uep *uep, struct usbhsg_request *ureq, int status) { struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); struct device *dev = usbhsg_gpriv_to_dev(gpriv); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe)); ureq->req.status = status; spin_unlock(usbhs_priv_to_lock(priv)); usb_gadget_giveback_request(&uep->ep, &ureq->req); spin_lock(usbhs_priv_to_lock(priv)); }
/* * * usb_dcp_ops * */ static int usbhsg_dcp_enable(struct usbhsg_uep *uep) { struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct usbhs_pipe *pipe; /* ********* assume under spin lock ********* */ pipe = usbhs_dcp_malloc(priv); if (!pipe) return -EIO; uep->pipe = pipe; uep->pipe->mod_private = uep; INIT_LIST_HEAD(&uep->list); return 0; }
/* * * usb_ep_ops * */ static int usbhsg_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct usbhs_pipe *pipe; spinlock_t *lock; unsigned long flags; int ret = -EIO; /* * if it already have pipe, * nothing to do */ if (uep->pipe) return 0; /******************** spin lock ********************/ lock = usbhsg_trylock(gpriv, &flags); pipe = usbhs_pipe_malloc(priv, desc); if (pipe) { uep->pipe = pipe; pipe->mod_private = uep; INIT_LIST_HEAD(&uep->list); if (usb_endpoint_dir_in(desc)) uep->handler = &usbhsg_handler_send_packet; else uep->handler = &usbhsg_handler_recv_packet; ret = 0; } usbhsg_unlock(lock, &flags); /******************** spin unlock ******************/ return ret; }
/* * * usb_ep_ops * */ static int usbhsg_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct usbhs_pipe *pipe; int ret = -EIO; /* * if it already have pipe, * nothing to do */ if (uep->pipe) { usbhs_pipe_clear(uep->pipe); usbhs_pipe_clear_sequence(uep->pipe); return 0; } pipe = usbhs_pipe_malloc(priv, desc); if (pipe) { uep->pipe = pipe; pipe->mod_private = uep; /* * usbhs_fifo_dma_push/pop_handler try to * use dmaengine if possible. * It will use pio handler if impossible. */ if (usb_endpoint_dir_in(desc)) uep->handler = &usbhs_fifo_dma_push_handler; else uep->handler = &usbhs_fifo_dma_pop_handler; ret = 0; } return ret; }
static int usbhsg_gadget_stop(struct usb_gadget_driver *driver) { struct usbhsg_gpriv *gpriv; struct usbhs_priv *priv; struct device *dev; if (!driver || !driver->unbind) return -EINVAL; /* * find controller */ usbhsg_for_each_controller(gpriv) { if (gpriv->driver == driver) goto find_matching_controller; } return -ENODEV; find_matching_controller: dev = usbhsg_gpriv_to_dev(gpriv); priv = usbhsg_gpriv_to_priv(gpriv); usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); device_del(&gpriv->gadget.dev); gpriv->driver = NULL; if (driver->disconnect) driver->disconnect(&gpriv->gadget); driver->unbind(&gpriv->gadget); dev_dbg(dev, "unbind %s\n", driver->driver.name); return 0; }