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;
}
Example #2
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);
}
Example #4
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);
	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;
}
Example #6
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;
}
Example #7
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;
	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;
}
Example #8
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);
	gpriv->driver = NULL;

	return 0;
}
Example #9
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);
}
Example #10
0
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;
}
Example #11
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;
}
Example #12
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);
}
Example #13
0
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;
}
Example #14
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;
}
Example #17
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;
	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;
}
Example #18
0
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;
}