Example #1
0
static int usbhsh_stop(struct usbhs_priv *priv)
{
	struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv);
	struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv);
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
	struct device *dev = usbhs_priv_to_dev(priv);

	/*
	 * disable irq callback
	 */
	mod->irq_attch	= NULL;
	mod->irq_dtch	= NULL;
	mod->irq_sack	= NULL;
	mod->irq_sign	= NULL;
	usbhs_irq_callback_update(priv, mod);

	usb_remove_hcd(hcd);

	/* disable sys */
	usbhs_sys_host_ctrl(priv, 0);

	dev_dbg(dev, "quit host\n");

	return 0;
}
Example #2
0
/*
 *		usb module start/end
 */
static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
{
	struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
	struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
	struct device *dev = usbhs_priv_to_dev(priv);
	unsigned long flags;
	int ret = 0;

	/********************  spin lock ********************/
	usbhs_lock(priv, flags);

	usbhsg_status_set(gpriv, status);
	if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) &&
	      usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)))
		ret = -1; /* not ready */

	usbhs_unlock(priv, flags);
	/********************  spin unlock ********************/

	if (ret < 0)
		return 0; /* not ready is not error */

	/*
	 * enable interrupt and systems if ready
	 */
	dev_dbg(dev, "start gadget\n");

	/*
	 * pipe initialize and enable DCP
	 */
	usbhs_pipe_init(priv,
			usbhsg_queue_done,
			usbhsg_dma_map_ctrl);
	usbhs_fifo_init(priv);
	usbhsg_uep_init(gpriv);

	/* dcp init */
	dcp->pipe		= usbhs_dcp_malloc(priv);
	dcp->pipe->mod_private	= dcp;

	/*
	 * system config enble
	 * - HI speed
	 * - function
	 * - usb module
	 */
	usbhs_sys_hispeed_ctrl(priv, 1);
	usbhs_sys_function_ctrl(priv, 1);
	usbhs_sys_usb_ctrl(priv, 1);

	/*
	 * enable irq callback
	 */
	mod->irq_dev_state	= usbhsg_irq_dev_state;
	mod->irq_ctrl_stage	= usbhsg_irq_ctrl_stage;
	usbhs_irq_callback_update(priv, mod);

	return 0;
}
/*
 *		usb module start/end
 */
static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
{
	struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
	struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
	struct device *dev = usbhs_priv_to_dev(priv);
	spinlock_t *lock;
	unsigned long flags;

	/********************  spin lock ********************/
	lock = usbhsg_trylock(gpriv, &flags);

	/*
	 * enable interrupt and systems if ready
	 */
	usbhsg_status_set(gpriv, status);
	if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) &&
	      usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)))
		goto usbhsg_try_start_unlock;

	dev_dbg(dev, "start gadget\n");

	/*
	 * pipe initialize and enable DCP
	 */
	usbhs_pipe_init(priv);
	usbhsg_uep_init(gpriv);
	usbhsg_dcp_enable(dcp);

	/*
	 * system config enble
	 * - HI speed
	 * - function
	 * - usb module
	 */
	usbhs_sys_hispeed_ctrl(priv, 1);
	usbhs_sys_function_ctrl(priv, 1);
	usbhs_sys_usb_ctrl(priv, 1);

	/*
	 * enable irq callback
	 */
	mod->irq_dev_state	= usbhsg_irq_dev_state;
	mod->irq_ctrl_stage	= usbhsg_irq_ctrl_stage;
	mod->irq_empty		= usbhsg_irq_empty;
	mod->irq_ready		= usbhsg_irq_ready;
	mod->irq_bempsts	= 0;
	mod->irq_brdysts	= 0;
	usbhs_irq_callback_update(priv, mod);

usbhsg_try_start_unlock:
	usbhsg_unlock(lock, &flags);
	/********************  spin unlock ********************/

	return 0;
}
Example #4
0
int usbhs_mod_is_host(struct usbhs_priv *priv)
{
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
	struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv);

	if (!mod)
		return -EINVAL;

	return info->mod[USBHS_HOST] == mod;
}
Example #5
0
/*
 *		hotplug
 */
static void usbhsc_hotplug(struct usbhs_priv *priv)
{
	struct platform_device *pdev = usbhs_priv_to_pdev(priv);
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
	int id;
	int enable;
	int ret;

	/*
	 * get vbus status from platform
	 */
	enable = usbhs_platform_call(priv, get_vbus, pdev);

	/*
	 * get id from platform
	 */
	id = usbhs_platform_call(priv, get_id, pdev);

	if (enable && !mod) {
		ret = usbhs_mod_change(priv, id);
		if (ret < 0)
			return;

		dev_dbg(&pdev->dev, "%s enable\n", __func__);

		/* power on */
		if (usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
			usbhsc_power_ctrl(priv, enable);

		/* bus init */
		usbhsc_set_buswait(priv);
		usbhsc_bus_init(priv);

		/* module start */
		usbhs_mod_call(priv, start, priv);

	} else if (!enable && mod) {
		dev_dbg(&pdev->dev, "%s disable\n", __func__);

		/* module stop */
		usbhs_mod_call(priv, stop, priv);

		/* bus init */
		usbhsc_bus_init(priv);

		/* power off */
		if (usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
			usbhsc_power_ctrl(priv, enable);

		usbhs_mod_change(priv, -1);

		/* reset phy for next connection */
		usbhs_platform_call(priv, phy_reset, pdev);
	}
}
static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
{
	struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
	struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
	struct device *dev = usbhs_priv_to_dev(priv);
	spinlock_t *lock;
	unsigned long flags;

	/********************  spin lock ********************/
	lock = usbhsg_trylock(gpriv, &flags);

	/*
	 * disable interrupt and systems if 1st try
	 */
	usbhsg_status_clr(gpriv, status);
	if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) &&
	    !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))
		goto usbhsg_try_stop_unlock;

	/* disable all irq */
	mod->irq_dev_state	= NULL;
	mod->irq_ctrl_stage	= NULL;
	mod->irq_empty		= NULL;
	mod->irq_ready		= NULL;
	mod->irq_bempsts	= 0;
	mod->irq_brdysts	= 0;
	usbhs_irq_callback_update(priv, mod);

	usbhsg_dcp_disable(dcp);

	gpriv->gadget.speed = USB_SPEED_UNKNOWN;

	/* disable sys */
	usbhs_sys_hispeed_ctrl(priv, 0);
	usbhs_sys_function_ctrl(priv, 0);
	usbhs_sys_usb_ctrl(priv, 0);

	usbhsg_unlock(lock, &flags);
	/********************  spin unlock ********************/

	if (gpriv->driver &&
	    gpriv->driver->disconnect)
		gpriv->driver->disconnect(&gpriv->gadget);

	dev_dbg(dev, "stop gadget\n");

	return 0;

usbhsg_try_stop_unlock:
	usbhsg_unlock(lock, &flags);

	return 0;
}
Example #7
0
static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
{
	struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
	struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
	struct device *dev = usbhs_priv_to_dev(priv);
	unsigned long flags;
	int ret = 0;

	/********************  spin lock ********************/
	usbhs_lock(priv, flags);

	usbhsg_status_clr(gpriv, status);
	if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) &&
	    !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))
		ret = -1; /* already done */

	usbhs_unlock(priv, flags);
	/********************  spin unlock ********************/

	if (ret < 0)
		return 0; /* already done is not error */

	/*
	 * disable interrupt and systems if 1st try
	 */
	usbhs_fifo_quit(priv);

	/* disable all irq */
	mod->irq_dev_state	= NULL;
	mod->irq_ctrl_stage	= NULL;
	usbhs_irq_callback_update(priv, mod);

	gpriv->gadget.speed = USB_SPEED_UNKNOWN;

	/* disable sys */
	usbhs_sys_hispeed_ctrl(priv, 0);
	usbhs_sys_function_ctrl(priv, 0);
	usbhs_sys_usb_ctrl(priv, 0);

	usbhsg_pipe_disable(dcp);

	if (gpriv->driver &&
	    gpriv->driver->disconnect)
		gpriv->driver->disconnect(&gpriv->gadget);

	dev_dbg(dev, "stop gadget\n");

	return 0;
}
Example #8
0
static int usbhsc_suspend(struct device *dev)
{
	struct usbhs_priv *priv = dev_get_drvdata(dev);
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);

	if (mod) {
		usbhs_mod_call(priv, stop, priv);
		usbhs_mod_change(priv, -1);
	}

	if (mod || !usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
		usbhsc_power_ctrl(priv, 0);

	return 0;
}
Example #9
0
static int usbhs_status_get_each_irq(struct usbhs_priv *priv,
				     struct usbhs_irq_state *state)
{
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
	u16 intenb0, intenb1;
	unsigned long flags;

	/********************  spin lock ********************/
	usbhs_lock(priv, flags);
	state->intsts0 = usbhs_read(priv, INTSTS0);
	intenb0 = usbhs_read(priv, INTENB0);

	if (usbhs_mod_is_host(priv)) {
		state->intsts1 = usbhs_read(priv, INTSTS1);
		intenb1 = usbhs_read(priv, INTENB1);
	} else {
		state->intsts1 = intenb1 = 0;
	}

	/* mask */
	if (mod) {
		state->brdysts = usbhs_read(priv, BRDYSTS);
		state->nrdysts = usbhs_read(priv, NRDYSTS);
		state->bempsts = usbhs_read(priv, BEMPSTS);

		state->bempsts &= mod->irq_bempsts;
		state->brdysts &= mod->irq_brdysts;
	}
	usbhs_unlock(priv, flags);
	/********************  spin unlock ******************/

	/*
	 * Check whether the irq enable registers and the irq status are set
	 * when IRQF_SHARED is set.
	 */
	if (priv->irqflags & IRQF_SHARED) {
		if (!(intenb0 & state->intsts0) &&
		    !(intenb1 & state->intsts1) &&
		    !(state->bempsts) &&
		    !(state->brdysts))
			return -EIO;
	}

	return 0;
}
Example #10
0
static void usbhs_status_get_each_irq(struct usbhs_priv *priv,
				      struct usbhs_irq_state *state)
{
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);

	state->intsts0 = usbhs_read(priv, INTSTS0);
	state->intsts1 = usbhs_read(priv, INTSTS1);

	/* mask */
	if (mod) {
		state->brdysts = usbhs_read(priv, BRDYSTS);
		state->nrdysts = usbhs_read(priv, NRDYSTS);
		state->bempsts = usbhs_read(priv, BEMPSTS);

		state->bempsts &= mod->irq_bempsts;
		state->brdysts &= mod->irq_brdysts;
	}
}
Example #11
0
static int usbhsh_start(struct usbhs_priv *priv)
{
	struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv);
	struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv);
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
	struct device *dev = usbhs_priv_to_dev(priv);
	int ret;

	/* add hcd */
	ret = usb_add_hcd(hcd, 0, 0);
	if (ret < 0)
		return 0;
	device_wakeup_enable(hcd->self.controller);

	/*
	 * pipe initialize and enable DCP
	 */
	usbhs_fifo_init(priv);
	usbhs_pipe_init(priv,
			usbhsh_dma_map_ctrl);
	usbhsh_pipe_init_for_host(priv);

	/*
	 * system config enble
	 * - HI speed
	 * - host
	 * - usb module
	 */
	usbhs_sys_host_ctrl(priv, 1);

	/*
	 * enable irq callback
	 */
	mod->irq_attch		= usbhsh_irq_attch;
	mod->irq_dtch		= usbhsh_irq_dtch;
	mod->irq_sack		= usbhsh_irq_setup_ack;
	mod->irq_sign		= usbhsh_irq_setup_err;
	usbhs_irq_callback_update(priv, mod);

	dev_dbg(dev, "start host\n");

	return ret;
}
Example #12
0
/*
 *		hotplug
 */
static void usbhsc_hotplug(struct usbhs_priv *priv)
{
	struct platform_device *pdev = usbhs_priv_to_pdev(priv);
	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
	int id;
	int enable;
	int cable;
	int ret;

	/*
	 * get vbus status from platform
	 */
	enable = usbhs_platform_call(priv, get_vbus, pdev);

	/*
	 * get id from platform
	 */
	id = usbhs_platform_call(priv, get_id, pdev);

	if (enable && !mod) {
		if (priv->edev) {
			cable = extcon_get_cable_state(priv->edev, "USB-HOST");
			if ((cable > 0 && id != USBHS_HOST) ||
			    (!cable && id != USBHS_GADGET)) {
				dev_info(&pdev->dev,
					 "USB cable plugged in doesn't match the selected role!\n");
				return;
			}
		}

		ret = usbhs_mod_change(priv, id);
		if (ret < 0)
			return;

		dev_dbg(&pdev->dev, "%s enable\n", __func__);

		/* power on */
		if (usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
			usbhsc_power_ctrl(priv, enable);

		/* bus init */
		usbhsc_set_buswait(priv);
		usbhsc_bus_init(priv);

		/* module start */
		usbhs_mod_call(priv, start, priv);

	} else if (!enable && mod) {
		dev_dbg(&pdev->dev, "%s disable\n", __func__);

		/* module stop */
		usbhs_mod_call(priv, stop, priv);

		/* bus init */
		usbhsc_bus_init(priv);

		/* power off */
		if (usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
			usbhsc_power_ctrl(priv, enable);

		usbhs_mod_change(priv, -1);

		/* reset phy for next connection */
		usbhs_platform_call(priv, phy_reset, pdev);
	}
}